Using Circuit Breaker with camel -ThrottlingExceptionRoutePolicy - apache-camel

There is a route which is consuming messages from a jms queue and after doing some processing sending a request to unreliable web service(Which can be down at times).
So in case of service is down then i need to stop consuming from queue for some time. I tried to use ThrottlingExceptionRoutePolicy . It will stop route as per configuration but issue is for the current message which gets the error as message is getting moved to dead letter queue. I've gone through the code of ThrottlingExceptionRoutePolicy as per code this will be called after all error handling is done for route.
So i need to modify default error handling of camel to avoid putting message to DLQ for some specific cases. I tried to configure various error handlers provided by camel but in all cases camel is putting messages to DLQ.
Is there some configuration or i need to write custom error handler to achieve the same.
<camel:route id="someroute" routePolicyRef="throttlingExceptionRoutePolicy"
errorHandlerRef="myTransactionErrorHandlerErrorHandler">
<camel:from uri="activemq:inputQueue" />
<camel:transacted />
<camel:bean ref="afterQueueProcessor" />
<camel:setHeader headerName="CamelHttpMethod">
<camel:constant>POST</camel:constant>
</camel:setHeader>
<camel:setHeader headerName="Content-Type">
<camel:constant>application/xyz</camel:constant>
</camel:setHeader>
<camel:to
uri="http://localhost:8080/some-ws/newOrder?orderId=dd&productName=bb&quantity=1" />
</camel:route>
This questions is related to async communication

Related

Camel activemq component - TTL

I want old messages to be automatically removed from topic so I'm using the option timeToLive which is described in the Camel ActiveMQ component documentation. However, it only works with queue and not with topic. Any idea why?
For testing purposes I made this simple route:
<route>
<from uri="timer://foo?repeatCount=1"/>
<to uri="activemq:topic:test?timeToLive=10000"/>
</route>
Route sends message to my test topic with TTL=10seconds. I would expect that after 10 seconds message would disappear.
When I use queue instead everything works as expected ( <to uri="activemq:queue:test?timeToLive=10000"/> )

Complete Async web service communication - sender and receiver are not available same time

Two systems are talking to each other through integration(Using apache-camel). Let say system A needs to submit a request to System B which has exposed a web service to receive data and integration is transforming data as per system B web service.
In above scenario A and B has to be available same time and A will have to wait for response from B. I need to remove this dependency by putting queue at integration layer and with Async communication.
Ex:
<camel:route id="AtoIntegration">
<camel:from
uri="spring-ws:someEndPoint" />
<camel:bean ref="testAsyncPreprocessor" />
<camel:inOnly uri="activemq:requestqueue" />
</camel:route>
<camel:route id="integrationToB">
<camel:from uri="activemq:requestqueue" />
<camel:transacted />
<camel:bean ref="afterQueueProcessor" />
<camel:setHeader headerName="CamelHttpMethod">
<camel:constant>POST</camel:constant>
</camel:setHeader>
<camel:setHeader headerName="Content-Type">
<camel:constant>application/x-www-form-urlencoded</camel:constant>
</camel:setHeader>
<camel:to uri="http://localhost:8080/systemB/newOrder?test=testData"
/>
</camel:route>
As per above routing system A can submit request even if system B is not available but route integrationToB still needs system B to be available else it will fail and put request to Dead Letter Queue after retry.
So i'm trying to figure out how i can configure route integrationToB only run if system B is available.
I don't quite understand, you said you put a queuing mechanism in between the systems. Ok, but if you have done this there is no need to know if a system is available or not. That system will consume from the queue when it becomes available.
If you still need to send from a queue to a web-service then what's the point of having a queuing mechanism in between?

Apache Camel, how to perform asynchronous messaging inside the route

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>

move messages between ActiveMQ queues in Camel w/o deserializing

I'm running Camel embedded in ActiveQM 5.11.1. I have some Java serialized messages that I need to move between queues with a simple Camel route...
<route>
<from uri="activemq:A"/>
<to uri="activemq:B"/>
</route>
as expected, I get this error...
WARN | Execution of JMS message listener failed. Caused by:
[org.apache.camel.RuntimeCamelException - Failed to extract body due
to: javax.jms.JMSException: Failed to build body from content.
Serializable class not available to broker. Reason:
java.lang.ClassNotFoundException: com.test.MyMessage. Message:
ActiveMQObjectMessage
I know this is because Camel/AMQ doesn't know about MyMessage and I can add it to AMQ's classpath to get around this...but that isn't an option in my case.
Instead, can I just tell Camel/AMQ to not try to deserialize it and just move it? I tried the jmsMessageType options, but they didn't get around this error...
You can turn of mapping from JMS to Camel Message using the mapJmsMessage=false option.
And then set jmsMessageType=Object so when sending to the queue, Camel will not try to guess the message type, but use object as configured, then the message is sent as-is.

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