0

We have the following Camel route in our application:

    from(webServiceUri).routeId("webServiceRoute")
        .unmarshal(jaxb)
        .process(new Processor() {
            @Override
            public void process(Exchange exchange) throws Exception {
                final Message in = exchange.getIn();
                final DataRequest body = in.getBody(DataRequest.class);
                final DataRequest.Items items = body.getItems();
                itemValidator.validate(items.getItem());
                getContext().createProducerTemplate().sendBody(importUri, body);
                DataResponse response = new DataResponse();
                response.setReturnCode(ReturnCode.SUCCESS);
                in.setBody(response);
            }
        })
        .marshal(jaxb);

We want the "webServiceRoute" to return the response user as soon as the processor has validated the data and forwarded the message to the "importUri". But right now it seems like the response is not returned to the caller until the "importUri" exchange is completed. So my question is what is the "correct" way to asynchronously forward the received request to another queue? There will not be any reply from the "importUri" exchange (i.e. it should be InOnly).

GaZ
  • 2,346
  • 23
  • 46

1 Answers1

1

You can replace .sendBody(importUri, body) by .asyncSendBody(importUri, body).

Nevertheless I find your route looks strange to me, why do you use a processor to forward your message. I would write something like:

DataResponse successResponse = new DataResponse();
response.setReturnCode(ReturnCode.SUCCESS);

from(webServiceUri).routeId("webServiceRoute")
    .unmarshal(jaxb)
    .bean(WebServiceRouteHelper.class,"validate")
    .to(importUri)
    .setBody(constant(sucessResponse))
    .marshal(jaxb);

class WebServiceRouteHelper {
    public DataRequest validate(DataRequest dataRequest) throws Exception {
        final DataRequest.Items items = body.getItems();
        itemValidator.validate(items.getItem());
        return dataRequest;
    }
}
G Quintana
  • 4,556
  • 1
  • 22
  • 23
  • Agree that the route looks strange. The reason for the processor was because the parameters to the itemValidator was not the request itself but an item within it, so I was 'unwrapping' that data. But in the end I decided just to refactor the itemValidator to accept the request as a parameter. – GaZ Dec 19 '13 at 21:56
  • But I am not sure that what you have suggested solves what I meant in my original question, i.e. that we have two routes (webservice -> import, and import -> finish), but that even after an exchange has been passed to the import route the result is not returned to the webservice caller until the exchange reaches 'finish'. I would like the caller to receive the successResponse as soon as the message has been sent in to importUri. – GaZ Dec 19 '13 at 22:00
  • 1
    Then your importUri should be of type [SEDA](http://camel.apache.org/seda.html) with waitForTaskToComplete=Never or JMS with disableReplyTo=true More on [Camel Async API](http://camel.apache.org/async.html) – G Quintana Jan 03 '14 at 12:52
  • That is the answer I was looking for. I achieved the same result but instead of specifcying disableReplyTo=true I change the ExchangePattern to InOnly: e.g. ".to(ExchangePattern.InOnly, importUri)". Thanks! – GaZ Jan 03 '14 at 15:10