0

I am trying to build a spring integration based architecture where my system needs to talk to different other systems over a variety of protocols. One of these systems is based on exposes REST endpoint for long-running jobs. I want to have a Spring Integration HTTP outbound component that will submit a job (say on POST /api/job/submit with a requestId) and then poll the result of the job from a different endpoint (say GET /api/job/{request-id}/result).

[Note: that the job will be long running and the result may not be immediately available]

I am trying to expose this functionality from submitting a job to getting a result using a single function that will return a Future containing the result of the job.

This is what I am thinking:

public Future<JobResult> executeJob(JobInput input) {
    // call the job submission endpoint using Http Outbound component or RestTemplate
    // get the result of this submission and confirm it is Http 200 
    // using the request id, kick off the task of checking the job result to an executor service. (instance of JobChecker)
    // return the future from the submitted callable.

}

class JobChecker implements Callable<JobResult> { 
      @Override
      public JobResult call() throws Exception {
        while(true) {
           // using rest template or another HTTP outbound channel check if the result of requestId is available 
        }
      }
}

What components/combination of components from Spring Integration should I be using to achieve this? Am I missing something in terms of hardening this to a production grade solution viz. catering to error handling, routing, guaranteed delivery and idempotency of operation?

arnabkaycee
  • 1,634
  • 13
  • 26

1 Answers1

0

It is not clear what you are doing in that executeJob(). There are indeed many features in Spring Integration which can help you. And you might really combine them to achieve the requirements. However to select the best one for you we need to know more details about your logic flow.

You may use a RequestHandlerRetryAdvice on a HTTP Outbound Gateway which sends a status check request. If it fails with some exception like JobResultNotReadyException or some other erroneous HTTP status. You may need to combine it with a ExpressionEvaluatingRequestHandlerAdvice to throw a custom exception for some specific OK HTTP reply, but the one indicating that job is not done yet. However this solution is going to work in the same sending thread.

If you wish to leverage an async solution, you may need to look into an ExecutorChannel as an input for the flow with that check status gateway. Then next endpoint of that gateway would indeed be a router to check response status. If that is not OK, you may use a delayer to have some backoff for the next try. Then you send an original message back to that ExecutorChannel to form a loop. The entry point for this flow could be a @MessagingGateway with a Future return for gateway method. When you got a success response, you just can route to the bridge which would use a replyChannel header to fulfill that Future.

I probably can give you more advises if I know more about your requirements and expectations.

Artem Bilan
  • 113,505
  • 11
  • 91
  • 118