Apache Camel, how to perform asynchronous messaging inside the route - apache-camel

I want to make Camel route, where client calls synchronous SOAP service. Route will transform the request to asynchronous message, which is sent to message queue MQ2. Route waits until there is correlated reply message in it's own message queue MQ1. Finally route sends reply to client.
How do I
Include the asynchronous request/reply phase inside the route handling synchronous WS invocation
Implement this using different message queue instances, retaining the correlation between incoming messages and original requests
Optimize the performance to free the resources while waiting, if possible
Ensure that I'm able to run multiple instances of each service+MQ bundle
Basically I have chain of three services, each of with it's own one-way message queue bundled in the service. Last service in the chain must return the final result back to first service, and only to the first service, because the result can't be meditated to preceding service instances (or their message queues).
Also, it's an opinion to implement this with one-way SOAP services with callback meshanism, if that is easier with Camel. The point is, the synchronous invocation must be converted to asynchronous chain of operations, and joined back to synchronous. It is vital that first service may be aware of only the final result, and also intermediate services are forbidden to obtain the result produced by the services later in the chain.
Or is there at least an EIP pattern defined for this specific problem to get me on the right tracks?
Here is an example of the route I have so far: it just sends the message into MQ2.
<route id="cxfToJMSRoute">
<from uri="cxf:bean:endpoint" />
<convertBodyTo type="String"/>
<to uri="activemq:queue:api" />
<!-- How to wait for the correlated reply in different MQ? -->
<!-- Releasing resource while waiting, if possible -->
<!-- And finally intercept and return the result -->
<!-- And do all this with horizontal scalability in mind -->
<!-- Considering all exceptions like network failures in any segement -->
</route>

Related

For Apache Camel, is it possible to have half of a route synchronous and the second half async?

I currently have a camel route that exposes a cxf endpoint. When a messages comes through the endpoint I would first enrich that message with some information from another webservice and then do more processing afterwards. However, I want make the first half of this route synchronous so I can send back a response to whomever called my exposed cxf endpoint.
The route looks something like this:
from(cxf:CxfEndpoint)
.process(someProcessing)
.to(cxf:ExternalCxfEndpoint)
.to(activemq:queue:somequeue)
//return a response back to caller here
from(activemq:queue:somequeue)
... //additional processing here
...
The reason for this is because when a message comes via my exposed cxf endpoint I don't know if it's a valid message. I need to first validate it with the message enrichment. Once the message is enriched, I want let whomever sent the message know that their message is accepted but don't want them to wait for the message to make it through the whole route as that could take hours.
Does anyone know how this would work?
Thanks in advance!
I believe all you need to do is set exchangePattern to InOnly a.k.a. make it an Event Message. This should have your route not wait for a reply from ActiveMQ. Camel exchange will default to InOut when it's originating from a web service, as in your case.
A related question with an answer from a Camel dev here.
Also see this one for some details on the behavior when your broker is down.
Yes definitely , 100% possible. A simple example would be this :
From cxf endpoint
Store your request in a camel property or header
To xslt - generate xslt for cxf endpoint - Synchronous flow
Reset your original payload using set body.
Wiretap Endpoint - to any endpoint downstream or even a route , this becomes asynchronous . This won't take part in the above sync response .
Note- step 2 & 4 may not be required, it depends on your use case .
There are whole lots of things you can do, I just gave a very simple example . It doesn't need to be wiretap as well, but wiretap helps us not to write any additional custom exceptional handling.

Camel : Impact on route execution when connection with external client closes unexpectedly

We are exposing a SOAP/HTTP based camel-cxf web service where on receiving a request from 'Client-A', the route execution starts which involves calling one or more external web services lets say 'Server1', 'Server2' and 'Server3' in a sequentialmanner. In this case, we need to understand what happens to the execution of the route, when the original TCP connection with 'Client-A' is closed unexpectedly.
Will the route get executed successfully and an error is logged when it tries to send the final response?
Or will the route execution be stopped immediately as soon as the TCP connection is closed?
You can capture any errors during the route execution by camel's error handling mechanism and then define the policy on how you want to handle the exception, for example you can setup rules that state how many times to try redelivery, and the delay in between attempts, and so forth.
For more information you can refer to this link:
http://camel.apache.org/redeliverypolicy.html

Updating database in different thread in camel based application

I have a Camel based application which receives a request and gives the reply from cache but in between this process it updates the database which i want it to run in a different thread , can anyone tell me how can i achieve this, i tried with WireTap and SEDA but it does not work that way...any help appreciated.
<camel:wireTap uri="seda:tap" processorRef="updateHitCountProcessor"/>
In updateHitCountProcessor I have written code to update table
it is updating the database in same thread (i.e main route thread)
You need to do
<camel:wireTap uri="ref:updateHitCountProcessor"/>
The processorRef attribute is creating and sending a new message, and not for tapping the existing message. So you should not use that.
The uri is used for sending the message which happens in a separate thread. So when you send it to the ref endpoint it will do that in another thread, and call your processor.
You can find details on the wire tap page at: http://camel.apache.org/wire-tap
From the documentation of the camel-seda component (here):
By default, the SEDA endpoint uses a single consumer thread, but you
can configure it to use concurrent consumer threads.
You can add a thread pool to a SEDA endpoint like this:
<from uri="seda:stageName?concurrentConsumers=5" />

Apache Camel: Test if endpoints are up

Does Camel provide anything out of the box which tells if it is able to connect all endpoints?
These endpoints could be MQ, webservice etc.
If not then I have to write a servlet which will send test request to all the endpoints. I will be using multicast or splitter for this implementation.
From my experience Camel will only provide warning logs if a from() endpoint is not available since it is constantly trying to read from them. Every other endpoint won't be accessed until the exchange tries to use that endpoint. If your goal is to test if various resources are alive I believe you would need to create your own testing program. I don't think this will be implemented as a feature because typically applications build in error handling if a resource is down and definte appropriate behaviors.
If we're talking about producers, then no. If your route is sending messages to an amq or http4 endpoint for instance, camel with not automatically send TCP-packets on these connections for monitoring purposes. A common way to handle failure of external endpoints is by using "circuit breakers". Take a look at https://camel.apache.org/load-balancer.html. A more robust alternative, imho, is Netflix's Hystrix.
If you have a polling consumer, say a from:ftp://.. then the polling consumer will poll messages every n-th millisecond, and you'll get an error if the connection is broken.

Send SMS via SMPP with camel

What's the best strategy to send SMS via SMPP with Camel ? Should I use the ProducerTemplate ?
I'm new to camel so I'm not confident if my strategy is the best.
In my application upon reception of an SMS, I have to send back an other SMS with some computed content.
I created a
route smsIn that looks like this
from "uri=smpp ..."
unmarshal ref="bindyDataFormat"
to "uri=bean:myBean
and a route smsOut with
from "uri=direct:smsOut"
to "uri=smpp ..."
The smsIn route, receives the sms, transforms its conent (csv data) in a pojo and send that pojo to myBean.
In myBean I do some processing and then call a ProducerTemplate which send my computed message to the endpoint "direct:smsOut".
The reason I use the producerTemplate is that I have to set some info from my pojo in the header (CamelSmppDestAddr) and the body of the Exchange.
I have tested with the logica SMSC simulator, this seems to work fine, but would like to have your opinion about this solution ?
What about reliability , transaction ?
Should I store my message before trying to send it to the SMSC ?
Should I store it in a database, post it to a queue ?
I'm not sure why you have a producer template, you could just build up the route instead (given that you return something from your bean or takes an Exchange as paramter).
<from uri="smpp: ..."/>
<bean ref="bean:myBean"/>
<to uri="jms:queue:myQueue"/>
then not use direct, but use a JMS queue that is transactional and persistent. Say your smpp call fails, the message would have been gone. Using a queue like this and make sure its transactional, you can make sure not to lose data in this stage of the route.
<from uri="jms:queue:myQueue"/>
<transactional/>
<to uri="smpp.."/>
I suggest using Apache ActiveMQ as JMS middleware. Actually, if you download ActiveMQ, you get camel bundled, so you could actually run your Camel routes from ActiveMQ.
You might want to tweak how retries and error handling occurs dependent on what you want to happen (retry every second forever?, retry five times, then put to error queue? etc).
Read this page: Transaction Error handling in Camel
For deeper info and more tweaks, you might also want to read this:
Transactional Client

Resources