0
votes

I'm trying to build a Mulesoft custom connector which makes HTTP requests to a third-party system, and I'd like these HTTP requests to be made in a non-blocking manner such that execution can continue without waiting on the HTTP response to be returned.

There is an example of this in the Mulesoft documentation here which shows this example code:

public void request(String url, @Connection HttpClient client, @Content String body, 
    CompletionCallback<InputStream, HttpAttributes> callback ) { 
 client.send(url, body, new HttpResponseCallback() {
   void onResponse(HttpResponse response) {
     callback.success(Result.<InputStream, HttpAttributes>builder() 
                          .output(response.getBody())
                          .attributes(toAttributes(response))
                          .build());
   }

   void onError(Exception e) {
     callback.error(e); 
   }
 });
}

It also states that non-blocking behaviour can be provided

by an HttpClient that supports asynchronous responses

Mulesoft's custom connector documentation states

The HttpClient is capable of using non-blocking I/O to make the requests.

but I don't understand how!

The example code above calls a method send(String, String, HttpResponseCallback) from the HttpClient interface. However, the HttpClient interface, as documented in Mulesoft's API javadoc does not have such a method.

I see that the HttpClient interface does have sendAsync(HttpRequest request) methods, but I'm failing to understand how that could be used with the example code.

I understand that Mulesoft's HttpClient is implemented using Project Grizzly's HTTP client, and that supports non-blocking requests, so I feel this is possible to do, I just don't understand how...

Thanks for any tips!

1

1 Answers

1
votes

Hi was trying to achieve the same thing, with the same non-blocking-operations documentation, but I wasn't able, So I try based on the Slack connector, it has a lot of examples there, and they use other code to achieve async calls ChannelOperations with CompletionCallback

However, this did not work for me, I think maybe I have to make another workaround on the server-side to achieve async calls. Anyway, In the end, I use CompletableFuture to run the request in other thread, the request is in sync way but is performed Async in the CompletableFuture.runAsync

public void request(String url, @Connection HttpClient client, @Content String body) { 

HttpResponse response = null;
HttpEntity entity = new ByteArrayHttpEntity(body.toString().getBytes());
HttpRequest httpRequest = HttpRequest.builder().uri(url).addHeader("Content-Type", "application/json")
                .method("POST").entity(entity).build();
CompletableFuture.runAsync(() -> {
 try {
            client.start();
            response = client.send(httpRequest, 30000, true, null);
        } catch (IOException | TimeoutException e) {
                LOGGER.error(response.toString());
        }
    LOGGER.info(response.toString());
        client.stop();
    
    LOGGER.info("Finish");
});
}

There is a Mule connector similar to DMI where the calls are made async