[Service Task][Issue with Service task with long running REST API

Hi All,

In a process ( Aysnc) , I created a service task with Java Delegate . In delegate , we are making REST API and this call is long running call like we get the response after 15 mins…

Service Task → Java Delegate → Rest API

When this process is started , the Java Delegate triggers the Rest API call and when this is still running and after around 6 minutes we see another thread starting and this in turn calls this service( java delegate) again . After next 6 mins , another new thread triggers this service task again. So, at client side we are multiple requests.

To resolve this issue, we were considering the options below , however not sure if this resolves the issue.

  1. Convert the Rest API call to Asyn in Java delegate
  2. External Task

Please suggest if there are any other solutions to resolve this issue.

Hello @Kavitha ,

the Delegate is not meant to execute long running calls sync. The behaviour you can see is that the job times out and gets picked up again by another thread (job executor).

My suggestion would be to use the External Task for these durations of task execution. Here, you can start with an initial lock of some minutes and extend the lock while waiting for the answer.

The other option would be the implementation of a async pattern with Message send/receive tasks or events. This would also work. Important is here that the engine is not “blocked” by a thread waiting for the answer but the wait state is modelled and saved to the database of the process engine.

I hope this helps

Jonathan

Thanks Jonathan. Will check these External and Message send/receive task approach .
Could you please share some reference code snippets for this .

Also, can we run external task code i.e ExternalTaskClient code inside camunda as another web app?

Thanks.

Like Jonathan said. Best is that you approach every service task assuming it’s going to be long running.
Basically you

  1. Fetch and lock a task for 20 seconds (as that’s the default)
  2. Start your long running task
  3. After 20 seconds you still haven’t completed the task so the engine frees up the lock
  4. Your external task handling service fetches it again and start doing over again on another thread.

You have to either

  1. Fetch and lock it with a very long duration (wrong approach)
  2. Provide an extend lock REST API call to the engine on like 15 seconds basis until your long running task is completed. Since you’re doing Java and as such you’re multithreaded that shouldn’t be a problem.
1 Like

We are using Spring External task client for the External Task service.

Code snippet:

@EnableExternalTaskClient(
baseUrl = “${client.baseUrl}”,
workerId = “${client.workerId}”,maxTasks=1,disableBackoffStrategy =
true
)

here , how to pass camunda username and password ?

pom.xml : external client dependency

org.camunda.bpm camunda-external-task-client-spring 7.15

Hello @Kavitha ,

in gerneral, the REST API does not secured in first place - so no username and password would be required. If you need your Request towards the REST API enhanced in any way, there are 2 options:

  1. Add username and password for Basic Auth with your application.yml like this:
camunda.bpm:
  admin-user: # Configure the login credentials for the Runtime Platform admin user
    id: demo # configure the username
    password: demo # configure the password
  client:
    base-url: http://localhost:8080/engine-rest # The URL pointing to the Camunda Platform Runtime REST API
    async-response-timeout: 1000 # Defines the maximum duration of the long-polling request
    worker-id: spring-boot-client # Identifies the worker towards the Engine
#      basic-auth: # Configure if REST API is secured with basic authentication
#        username: demo
#        password: demo
    subscriptions:
      creditScoreChecker: # This topic name must match the respective `@ExternalTaskSubscription`
        process-definition-key: loan_process # Filters for External Tasks of this key
        auto-open: false # Defines whether the subscription is opened automatically or not
      loanGranter:
        lock-duration: 10000 # Defines for how long the External Tasks are locked until they can be fetched again

This example is taken from here.
2. Configure your request rpogrammtically with an Interceptor like this:

@Configuration
public class InterceptorConfiguration {

  protected static Logger LOG = LoggerFactory.getLogger(InterceptorConfiguration.class);

  @Bean
  public ClientRequestInterceptor interceptor() {
    return context -> {
      LOG.info("Request interceptor called!");
      context.addHeader("X-MY-HEADER", "External Tasks Rock!");
    };
  }

}

This exmple is taken from here

I hope this helps

Jonathan

1 Like

Thanks Jonathan. This worked, added below code in interceptor

@Bean
public ClientRequestInterceptor interceptor() {
return new BasicAuthProvider(env.getRequiredProperty(“client” +
“.username”), env.getRequiredProperty(“client.password”));
}

1 Like