Skip to content

Commit

Permalink
Close #353: Register FetchAndLockHandler when initializing the REST a…
Browse files Browse the repository at this point in the history
…pi so that long polling works, i.e. the if there are currently no tasks then the server will keep the connection open for the given time.
  • Loading branch information
tobiasschaefer authored and arolfes committed Nov 29, 2021
1 parent ee4be71 commit f4866e2
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 8 deletions.
2 changes: 1 addition & 1 deletion micronaut-camunda-bpm-feature/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ dependencies {

// REST API + Webapps
implementation("com.fasterxml.jackson.jaxrs:jackson-jaxrs-json-provider")
implementation("org.camunda.bpm:camunda-engine-rest:$camundaVersion:classes")
implementation("org.camunda.bpm:camunda-engine-rest-jaxrs2:$camundaVersion")
implementation("org.camunda.bpm.webapp:camunda-webapp-webjar:$camundaVersion")
implementation("org.glassfish.jersey.inject:jersey-hk2:$jerseyVersion")
implementation("org.glassfish.jersey.containers:jersey-container-servlet-core:$jerseyVersion")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ dependencies {
kaptTest("io.micronaut:micronaut-inject-java:$micronautVersion")

testCompileOnly("io.micronaut.servlet:micronaut-http-server-jetty")
testImplementation("org.junit.jupiter:junit-jupiter-params")
testImplementation("org.assertj:assertj-core")
testImplementation("io.micronaut:micronaut-http-client")
testImplementation("org.eclipse.jetty:jetty-server:$jettyVersion")
testImplementation("org.eclipse.jetty:jetty-servlet:$jettyVersion")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,15 @@ import io.micronaut.http.client.HttpClient
import io.micronaut.http.client.annotation.Client
import io.micronaut.test.extensions.junit5.annotation.MicronautTest
import jakarta.inject.Inject
import org.assertj.core.api.Assertions.assertThat
import org.assertj.core.api.Assertions.within
import org.eclipse.jetty.server.Server
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Test
import org.junit.jupiter.params.ParameterizedTest
import org.junit.jupiter.params.provider.ValueSource
import java.time.Duration
import java.time.Instant

/**
* Test the REST API on Jetty.
Expand All @@ -49,4 +55,30 @@ class JettyRestTest {

assertEquals("""[{"name":"default"}]""", body)
}

@ParameterizedTest
@ValueSource(longs = [0, 2000, 5000])
fun `long polling`(duration: Long) {
val request: HttpRequest<String> = HttpRequest.POST(
configuration.rest.contextPath + "/external-task/fetchAndLock",
"""
{
"maxTasks": 1,
"workerId": "aWorkerId",
"asyncResponseTimeout": $duration,
"topics": [
{
"topicName": "aTopicName",
"lockDuration": 1000
}
]
}
"""
)
val start = Instant.now()
val body = client.toBlocking().retrieve(request)

assertEquals("[]", body)
assertThat(Duration.between(start, Instant.now()).toMillis()).isCloseTo(duration, within(500L))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,10 @@
import jakarta.inject.Singleton;
import org.camunda.bpm.admin.impl.web.bootstrap.AdminContainerBootstrap;
import org.camunda.bpm.cockpit.impl.web.bootstrap.CockpitContainerBootstrap;
import org.camunda.bpm.engine.rest.security.auth.ProcessEngineAuthenticationFilter;
import org.camunda.bpm.engine.rest.filter.CacheControlFilter;
import org.camunda.bpm.engine.rest.filter.EmptyBodyFilter;
import org.camunda.bpm.engine.rest.impl.FetchAndLockContextListener;
import org.camunda.bpm.engine.rest.security.auth.ProcessEngineAuthenticationFilter;
import org.camunda.bpm.tasklist.impl.web.bootstrap.TasklistContainerBootstrap;
import org.camunda.bpm.webapp.impl.engine.ProcessEnginesFilter;
import org.camunda.bpm.webapp.impl.security.auth.AuthenticationFilter;
Expand All @@ -50,11 +51,11 @@
import java.util.HashMap;
import java.util.Map;

import static java.util.Collections.*;
import static javax.servlet.DispatcherType.*;
import static java.util.Collections.singletonMap;
import static javax.servlet.DispatcherType.REQUEST;

/**
* Using Micronaut Servlet with Jetty to run the REST API as a servlet.
* Using Micronaut Servlet with Jetty to run the REST API/Webapps as a servlet.
*
* see https://micronaut-projects.github.io/micronaut-servlet/latest/guide/#jetty
*
Expand Down Expand Up @@ -84,6 +85,13 @@ public Server onCreated(BeanCreatedEvent<Server> event) {
ServletContextHandler restServletContextHandler = new ServletContextHandler();
restServletContextHandler.setContextPath(configuration.getRest().getContextPath());
restServletContextHandler.addServlet(new ServletHolder(new ServletContainer(new RestApp())), "/*");
restServletContextHandler.addEventListener(new ServletContextListener() {
@Override
public void contextInitialized(ServletContextEvent sce) {
// Required for long polling
new FetchAndLockContextListener().contextInitialized(sce);
}
});

if (configuration.getRest().isBasicAuthEnabled()) {
// see https://docs.camunda.org/manual/latest/reference/rest/overview/authentication/
Expand Down Expand Up @@ -167,9 +175,6 @@ public void contextInitialized(ServletContextEvent sce) {
registerFilter("CacheControlFilter", CacheControlFilter.class, "/api/*", "/app/*");
}

@Override
public void contextDestroyed(ServletContextEvent sce) {}

protected Map<String, String> getCsrfInitParams(){
Map<String, String> initParams = new HashMap<>();

Expand Down

0 comments on commit f4866e2

Please sign in to comment.