camunda-community-hub / micronaut-camunda-platform-7

Integration between Micronaut and Camunda (Workflow Engine). We configure Camunda with sensible defaults, so that you can get started with minimum configuration: simply add a dependency in your Micronaut project to embed the workflow engine!
https://camunda.com/blog/2021/07/automate-any-process-on-micronaut/
Apache License 2.0
75 stars 31 forks source link

How to configure fetchAndLock long poll? (asyncResponseTimeout has no effect) #353

Closed datakurre closed 2 years ago

datakurre commented 2 years ago

I have followed README to configure a Micronaut Camunda application with jetty because of webapps support.

Unfortunately, asyncResponseTimeout for REST API external-task/fetchAndLock seem to have no effect. Response is always instantly returned:

$ curl -X POST http://localhost:8080/engine-rest/external-task/fetchAndLock -H "Content-Type: application/json" -d'{"maxTasks": 1, "workerId": "aWorkerId", "asyncResponseTimeout": 2000, "topics": [{"topicName": "aTopicName", "lockDuration": 3000}]}'

The same command works as expected with the default Camunda Docker images.

datakurre commented 2 years ago

The project seems to depend on org.camunda.bpm:camunda-engine-rest

https://github.com/camunda-community-hub/micronaut-camunda-bpm/blob/910c0badab9c710d22d1504bf3b15fec294a0e47/micronaut-camunda-bpm-feature/build.gradle#L47

when asyncResponseTimeout is feature of

org.camunda.bpm:camunda-engine-rest-jax2rs

datakurre commented 2 years ago

https://github.com/camunda/camunda-bpm-spring-boot-starter/commit/79e862d567f7c31de51da1673b227ae82cb90970#diff-572d41f4162cfe2c52d3ca94a817349a3e55e436504331946c56e1a5e8c31d00

tobiasschaefer commented 2 years ago

Hi @datakurre ,

thanks for reporting this issue and giving us those hints.

There is a small typo in the dependency you mentioned. Correct is implementation("org.camunda.bpm:camunda-engine-rest-jaxrs2:$camundaVersion") (2 at the end)

I tried replacing the dependency but then it fails with

{"type":"NullPointerException","message":"Cannot invoke \"org.camunda.bpm.engine.rest.spi.FetchAndLockHandler.addPendingRequest(org.camunda.bpm.engine.rest.dto.externaltask.FetchExternalTasksExtendedDto, javax.ws.rs.container.AsyncResponse, org.camunda.bpm.engine.ProcessEngine)\" because \"fetchAndLockHandler\" is null"}

Your're welcome to create a PR (see CONTRIBUTING.md) - otherwise @arolfes and I will have a closer look.

Note: this is the issue of the Spring Boot Starter Project which switched the mentioned dependencies: https://jira.camunda.com/browse/CAM-8799

datakurre commented 2 years ago

@tobiasschaefer Thanks for confirming the issue!

Unfortunately, I was unable to solve

{"type":"NullPointerException","message":"Cannot invoke \"org.camunda.bpm.engine.rest.spi.FetchAndLockHandler.addPendingRequest(org.camunda.bpm.engine.rest.dto.externaltask.FetchExternalTasksExtendedDto, javax.ws.rs.container.AsyncResponse, org.camunda.bpm.engine.ProcessEngine)\" because \"fetchAndLockHandler\" is null"}

Some pointers, though...

The exception is raised from

https://github.com/camunda/camunda-bpm-platform/blob/64e60eb7222b58c67104a0912b1d9d4185e2cc1b/engine-rest/engine-rest-jaxrs2/src/main/java/org/camunda/bpm/engine/rest/impl/FetchAndLockRestServiceImpl.java#L38

The missing handler should have been set at

https://github.com/camunda/camunda-bpm-platform/blob/64e60eb7222b58c67104a0912b1d9d4185e2cc1b/engine-rest/engine-rest-jaxrs2/src/main/java/org/camunda/bpm/engine/rest/impl/FetchAndLockContextListener.java#L38

Which was one called at

https://github.com/arolfes/micronaut-camunda-bpm/blob/98eb4d476b0cad48fb208022775e5c5cfb2e7527/example-external-task-process/src/main/java/info/novatec/micronaut/camunda/externaltask/process/FetchAndLockContextFactory.java#L35

but I am not sure, how should it work now.

datakurre commented 2 years ago

šŸŽ‰ā¤ļø

tobiasschaefer commented 2 years ago

Hi @datakurre ,

we've published release v2.3.1 which fixes the bug you reported.

Please confirm that your issue has been resolved (and thanks for reporting it).

datakurre commented 2 years ago

@tobiasschaefer Unfortunately, I was unable to confirm the fix yet :flushed:

I am new to micronaut, but I assume that updating pom.xml should be enough

     <dependency>
       <groupId>info.novatec</groupId>
       <artifactId>micronaut-camunda-bpm-feature</artifactId>
-      <version>2.3.0</version>
+      <version>2.3.1</version>
       <scope>compile</scope>
     </dependency>
     <dependency>

And after shutting down, I now get the following stacktrace:

22:29:54.891 [Thread-10] INFO  org.camunda.bpm.engine.jobexecutor - ENGINE-14015 Shutting down the JobExecutor[info.novatec.micronaut.camunda.bpm.feature.MnJobExecutor]
22:29:54.892 [JobExecutor[info.novatec.micronaut.camunda.bpm.feature.MnJobExecutor]] INFO  org.camunda.bpm.engine.jobexecutor - ENGINE-14020 JobExecutor[info.novatec.micronaut.camunda.bpm.feature.MnJobExecutor] stopped job acquisition
22:29:54.900 [Thread-10] INFO  org.camunda.bpm.engine - ENGINE-00007 Process Engine default closed
22:29:54.982 [Thread-10] INFO  com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Shutdown initiated...
22:29:55.018 [Thread-10] INFO  com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Shutdown completed.
22:29:55.121 [Thread-10] INFO  o.e.j.server.handler.ContextHandler - Stopped i.m.s.j.@411341bd{/,null,STOPPED}
Exception in thread "Thread-10" io.micronaut.http.server.exceptions.HttpServerException: Error stopping HTTP server: Multiple exceptions
        at io.micronaut.servlet.engine.server.AbstractServletServer.stop(AbstractServletServer.java:109)
        at io.micronaut.servlet.engine.server.AbstractServletServer.stop(AbstractServletServer.java:34)
        at io.micronaut.runtime.Micronaut.lambda$null$0(Micronaut.java:115)
        at java.base/java.lang.Thread.run(Thread.java:833)
Caused by: MultiException[java.lang.AbstractMethodError: Receiver class info.novatec.micronaut.camunda.bpm.feature.JettyServerCustomizer$ServletContextInitializedListener does not define or inherit an implementation of the resolved method 'abstract void contextDestroyed(javax.servlet.ServletContextEvent)' of interface javax.servlet.ServletContextListener., java.lang.AbstractMethodError: Receiver class info.novatec.micronaut.camunda.bpm.feature.JettyServerCustomizer$1 does not define or inherit an implementation of the resolved method 'abstract void contextDestroyed(javax.servlet.ServletContextEvent)' of interface javax.servlet.ServletContextListener.]
        at org.eclipse.jetty.util.MultiException.ifExceptionThrow(MultiException.java:122)
        at org.eclipse.jetty.server.Server.doStop(Server.java:484)
        at org.eclipse.jetty.util.component.AbstractLifeCycle.stop(AbstractLifeCycle.java:94)
        at io.micronaut.servlet.jetty.JettyServer.stopServer(JettyServer.java:59)
        at io.micronaut.servlet.engine.server.AbstractServletServer.stop(AbstractServletServer.java:102)
        ... 3 more
        Suppressed: java.lang.AbstractMethodError: Receiver class info.novatec.micronaut.camunda.bpm.feature.JettyServerCustomizer$ServletContextInitializedListener does not define or inherit an implementation of the resolved method 'abstract void contextDestroyed(javax.servlet.ServletContextEvent)' of interface javax.servlet.ServletContextListener.
                at org.eclipse.jetty.server.handler.ContextHandler.callContextDestroyed(ContextHandler.java:1074)
                at org.eclipse.jetty.servlet.ServletContextHandler.callContextDestroyed(ServletContextHandler.java:584)
                at org.eclipse.jetty.server.handler.ContextHandler.contextDestroyed(ContextHandler.java:1037)
                at org.eclipse.jetty.servlet.ServletHandler.doStop(ServletHandler.java:319)
                at org.eclipse.jetty.util.component.AbstractLifeCycle.stop(AbstractLifeCycle.java:94)
                at org.eclipse.jetty.util.component.ContainerLifeCycle.stop(ContainerLifeCycle.java:180)
                at org.eclipse.jetty.util.component.ContainerLifeCycle.doStop(ContainerLifeCycle.java:201)
                at org.eclipse.jetty.server.handler.AbstractHandler.doStop(AbstractHandler.java:108)
                at org.eclipse.jetty.server.session.SessionHandler.doStop(SessionHandler.java:520)
                at org.eclipse.jetty.util.component.AbstractLifeCycle.stop(AbstractLifeCycle.java:94)
                at org.eclipse.jetty.util.component.ContainerLifeCycle.stop(ContainerLifeCycle.java:180)
                at org.eclipse.jetty.util.component.ContainerLifeCycle.doStop(ContainerLifeCycle.java:201)
                at org.eclipse.jetty.server.handler.AbstractHandler.doStop(AbstractHandler.java:108)
                at org.eclipse.jetty.server.handler.ContextHandler.stopContext(ContextHandler.java:1060)
                at org.eclipse.jetty.servlet.ServletContextHandler.stopContext(ServletContextHandler.java:386)
                at org.eclipse.jetty.server.handler.ContextHandler.doStop(ContextHandler.java:1114)
                at org.eclipse.jetty.servlet.ServletContextHandler.doStop(ServletContextHandler.java:297)
                at org.eclipse.jetty.util.component.AbstractLifeCycle.stop(AbstractLifeCycle.java:94)
                at org.eclipse.jetty.util.component.ContainerLifeCycle.stop(ContainerLifeCycle.java:180)
                at org.eclipse.jetty.util.component.ContainerLifeCycle.doStop(ContainerLifeCycle.java:201)
                at org.eclipse.jetty.server.handler.AbstractHandler.doStop(AbstractHandler.java:108)
                at org.eclipse.jetty.util.component.AbstractLifeCycle.stop(AbstractLifeCycle.java:94)
                at org.eclipse.jetty.util.component.ContainerLifeCycle.stop(ContainerLifeCycle.java:180)
                at org.eclipse.jetty.util.component.ContainerLifeCycle.doStop(ContainerLifeCycle.java:201)
                at org.eclipse.jetty.server.handler.AbstractHandler.doStop(AbstractHandler.java:108)
                at org.eclipse.jetty.server.Server.doStop(Server.java:470)
                ... 6 more
        Suppressed: java.lang.AbstractMethodError: Receiver class info.novatec.micronaut.camunda.bpm.feature.JettyServerCustomizer$1 does not define or inherit an implementation of the resolved method 'abstract void contextDestroyed(javax.servlet.ServletContextEvent)' of interface javax.servlet.ServletContextListener.
                at org.eclipse.jetty.server.handler.ContextHandler.callContextDestroyed(ContextHandler.java:1074)
                at org.eclipse.jetty.servlet.ServletContextHandler.callContextDestroyed(ServletContextHandler.java:584)
                at org.eclipse.jetty.server.handler.ContextHandler.contextDestroyed(ContextHandler.java:1037)
                at org.eclipse.jetty.servlet.ServletHandler.doStop(ServletHandler.java:319)
                at org.eclipse.jetty.util.component.AbstractLifeCycle.stop(AbstractLifeCycle.java:94)
                at org.eclipse.jetty.util.component.ContainerLifeCycle.stop(ContainerLifeCycle.java:180)
                at org.eclipse.jetty.util.component.ContainerLifeCycle.doStop(ContainerLifeCycle.java:201)
                at org.eclipse.jetty.server.handler.AbstractHandler.doStop(AbstractHandler.java:108)
                at org.eclipse.jetty.server.handler.ContextHandler.stopContext(ContextHandler.java:1060)
                at org.eclipse.jetty.servlet.ServletContextHandler.stopContext(ServletContextHandler.java:386)
                at org.eclipse.jetty.server.handler.ContextHandler.doStop(ContextHandler.java:1114)
                at org.eclipse.jetty.servlet.ServletContextHandler.doStop(ServletContextHandler.java:297)
                at org.eclipse.jetty.util.component.AbstractLifeCycle.stop(AbstractLifeCycle.java:94)
                at org.eclipse.jetty.util.component.ContainerLifeCycle.stop(ContainerLifeCycle.java:180)
                at org.eclipse.jetty.util.component.ContainerLifeCycle.doStop(ContainerLifeCycle.java:201)
                at org.eclipse.jetty.server.handler.AbstractHandler.doStop(AbstractHandler.java:108)
                at org.eclipse.jetty.util.component.AbstractLifeCycle.stop(AbstractLifeCycle.java:94)
                at org.eclipse.jetty.util.component.ContainerLifeCycle.stop(ContainerLifeCycle.java:180)
                at org.eclipse.jetty.util.component.ContainerLifeCycle.doStop(ContainerLifeCycle.java:201)
                at org.eclipse.jetty.server.handler.AbstractHandler.doStop(AbstractHandler.java:108)
                at org.eclipse.jetty.server.Server.doStop(Server.java:470)
                ... 6 more
Caused by: [CIRCULAR REFERENCE: java.lang.AbstractMethodError: Receiver class info.novatec.micronaut.camunda.bpm.feature.JettyServerCustomizer$ServletContextInitializedListener does not define or inherit an implementation of the resolved method 'abstract void contextDestroyed(javax.servlet.ServletContextEvent)' of interface javax.servlet.ServletContextListener.]
tobiasschaefer commented 2 years ago

@datakurre

Yes, your change in the dependency is correct šŸ‘

The exception is surely an unwanted side effect of the deletion of the contextDestroyed method: https://github.com/camunda-community-hub/micronaut-camunda-bpm/commit/f4866e2762863c260196372e9300e6fd5fd4b453#diff-188ba99efc68f0cf5b032be1d95ae420cb2d8709ffb6787b117c585c2d39cc7cL170

So this would need to added again - and also for the other listener. However, I cannot reproduce the error but need to to safely fix it.

How are you building, starting and stopping your application? I've tried various ways but never get an exception when stopping it.

Which JDK are you using? The interface "ServletContextListener" has a default implementation for both methods so it's unclear to me why these must be implemented.

datakurre commented 2 years ago

@tobiasschaefer I created the app using https://micronaut.io/launch/ with Java 17 and Maven, starting with ./mvnw mn:run with OpenJDK Runtime Environment (build 17.0.1+12), stopping here with Ctrl+C.

Curiously, I also get this error from the default test provided by micronaut launch scaffold with mvn test.

I was able reproduce this by creating a new scaffold with just camunda and h2 features and configuring jetty + webapps + rest.

Update: Got the same results with OpenJDK Runtime Environment (build 11.0.12).

tobiasschaefer commented 2 years ago

@datakurre Sorry about the regression with the exception. It also came in the test because the process engine is started by default and closed again when the application context is closed.

Release 2.3.2 should now work for you. Looking forward to your feedback!

datakurre commented 2 years ago

@tobiasschaefer I can confirm that everything works now. Thanks a lot for the hard work and quick fixes!

FYI. asyncResponseTimeout still does not work when run with ./mvwn mn:run, but when I package a JAR its contents look right and asyncResponseTimeout works as expected when running the JAR. Probably work also for other packaging options.

tobiasschaefer commented 2 years ago

@datakurre Strange, that ./mvnw mn:run fails to activate the long polling but I can confirm that behaviour. The Maven project works when starting the application from IntelliJ. With a Gradle project it works too: ./gradlew run and also from IntelliJ.

Note:

datakurre commented 2 years ago

@tobiasschaefer Thanks. I'm quite happy now with long-polling working in built version. Regarding maven vs. gradle, are there any runtime related differences? (Not sure if I miss anything that I'd really need.)

tobiasschaefer commented 2 years ago

@datakurre no, Iā€™m not aware of any differences.

Iā€™d be happy to discuss any other questions you might have and Iā€™d also like to know more about your use use. I sent you a LinkedIn contact request šŸ˜€