Hi,
I would like to implement a non-blocking HTTP client that I can use in an embedded process engine. We have already an embedded process engine in a Scala Play Framework application. So I would like to use the Play WS HTTP client implementation which is based on Netty and which is able to delegate async execution to a Scala execution context. The client returns a Scala Future
.
So I have thought of a solution that I can call from a ServiceTask
. The client implementation should get its parameters (url, method, body, headers, timeouts) from process variables and it should also writes it output (responseStatus, respnseBody), after the future has completed, into process variables. On the Camunda side, it should not block the thread in which the process is executed.
Currently I have an implementation based on AbstractBpmnActivityBehavior
.
class HttpRequestDelegate @Inject() (wsClient: WSClient)(
implicit
ec: ExecutionContext
) extends AbstractBpmnActivityBehavior {
override def execute(execution: ActivityExecution): Unit = {
(for {
url <- getUrl(execution)
method <- getMethod(execution)
headers <- getHeaders(execution)
body <- getBody(execution)
requestTimeout <- getRequestTimeout(execution)
} yield {
wsClient
.url(url)
.withHttpHeaders(headers: _*)
.withFollowRedirects(true)
.withRequestTimeout(requestTimeout)
.withBody(body)
.withMethod(method)
.execute().map { response =>
execution.setVariable("responseStatus", response.status)
execution.setVariable("responseBody", response.body)
leave(execution)
}.recover {
case e: Throwable =>
throw e
}
}).toTry.recover {
case e: Throwable =>
throw e
}
}
...
}
It will execute the request, but i’m not able to get the response variables in my test. The process instance is also marked as non ended even if I wait a few seconds.
I’m not sure that is the best approach to handle non-blocking requests. Maybe there is a better approach?
Best regards,
Christian