AnsweredAssumed Answered

WebConfigurer and deploying custom endpoints in Unit Test

Question asked by peteth on Jan 15, 2019

Migrating from APS Version 1.5 to 1.9,  we have some Java classes that provide custom REST endpoints that get deployed alongside the standard REST endpoints and allow other systems to call these endpoints via HTTP to inform an process instance that something has happened (e.g message it) 

 

These custom endpoints have Unit Tests, each test

- starts a Jetty server during the startup of the Unit Test,

- I assume the endpoints are then magically deployed to this jetty instance (this is code we inherited) 

- The Unit Test then invokes the custom endpoints using Apache HTTP api, to test the endpoints 

 

The problem we're having is getting the endpoints deployed to the embedded Jetty, with Activiti V1.5 the following Spring @Configuration class worked. However with V1.9 the line

 

contextHandler.addEventListener(configurer);

fails compile, as with v1.5 Activiti's "WebConfigurer" implemented the ServletContextListener interface, but the v1.9 one implements ServletContextInitializer. So the configurer can't be added as an event listener.

 

If we comment out the addEventListener line then the tests will run but I think find that neither activiti's own REST endpoints or our custom endpoints are deployed - as they return HTTP 404. 

 

Any advice how we can deploy to an embedded jetty during a Unit Test ?  

 

The Spring @Configuration is shown below 

package com.alfresco.consulting.activiti.test.config;

import java.util.EventListener;

import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.Profile;
import org.springframework.core.env.Environment;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;

import com.activiti.conf.Bootstrapper;
import com.activiti.servlet.WebConfigurer;

@Configuration
@ComponentScan(basePackages = {
    "com.activiti.runtime.bean",
    "com.activiti.runtime.activiti.bean",
    "com.activiti.reporting",
    "com.activiti.rest" // Extra for testing: the dispatcher servlet is not found by default
}, excludeFilters = {
    // comment out this filter to enable default bootstrap code
    @ComponentScan.Filter(value = Bootstrapper.class, type = FilterType.ASSIGNABLE_TYPE) }
)
@Import(value = { CommonActivitiTestConfiguration.class })
@Profile("rest")
public class RestEndpointTestConfiguration {

    public static final Integer DEFAULT_JETTY_PORT = Integer.valueOf(9999);

    @Bean(initMethod = "start")
    public Server jettyServer(ApplicationContext applicationContext, Environment environment) {
        // build AnnotationConfigWebApplicationContext
        AnnotationConfigWebApplicationContext webApplicationContext = null;

        if (applicationContext instanceof AnnotationConfigWebApplicationContext) {
            webApplicationContext = (AnnotationConfigWebApplicationContext) applicationContext;
        } else {
            webApplicationContext = new AnnotationConfigWebApplicationContext();
            webApplicationContext.setParent(applicationContext);
            webApplicationContext.refresh();
        }

        // build Activiti WebConfigurer using provided application context
        ServletContextHandler contextHandler = new ServletContextHandler();
        WebConfigurer configurer = new WebConfigurer();
        configurer.setContext(webApplicationContext);
        contextHandler.addEventListener(configurer);

        // create server
        int jettyPort = environment.getProperty("jetty.port", Integer.class, DEFAULT_JETTY_PORT).intValue();
        Server server = new Server(jettyPort);
        server.setHandler(contextHandler);

        return server;
    }

}

Outcomes