Accessing camel Exchange object in OnException block - apache-camel

                                          
.onException(SocketTimeoutException.class,ConnectException.class)
.handled(true)
.maximumRedeliveries(5)
.maximumRedeliveryDelay(5*1000)
I want to use exchange object attributes value to configure the maximumRedeliveries and maximumRedeliveryDelay.

You can use retryWhile on the onException to determine if to keep retrying or not. And you can use Exchange.REDELIVERY_DELAY as key in a message header to set the delay dynamically.

Related

Replicating AMQ Admin UI move functionality in Camel

In ActiveMQ (and Hawtio) there is Admin UI functionality to move a messages from one queue to another. This process keeps the body and all the headers all the same as the original message.
Is there a way to do this in Camel? A simple from(queue1).to(queue2) always seems to change headers.
thanks
edit: tried
from(
"cMQConnectionFactory1:queue:queue1"
+ "?forceSendOriginalMessage=" + true
+ "&mapJmsMessage=" + false)
.routeId("testMove_cJMS_1")
.to("cMQConnectionFactory1:queue:queue2"
+ "?forceSendOriginalMessage=" + true
+ "&mapJmsMessage=" + false).id("testMove_cJMS_2");
}`
The Camel documentation for the JMS component describes the forceSendOriginalMessage option saying:
When using mapJmsMessage=false Camel will create a new JMS message to send to a new JMS destination if you touch the headers (get or set) during the route. Set this option to true to force Camel to send the original JMS message that was received.
forceSendOriginalMessage defaults to false.
The docs say this about mapJmsMessage:
Specifies whether Camel should auto map the received JMS message to a suited payload type, such as javax.jms.TextMessage to a String etc.
mapJmsMessage defaults to true.
Therefore it seems like you need to set mapJmsMessage=false & forceSendOriginalMessage=true.
Keep in mind that Camel will be using the JMS API to consume the message and then resend it. Even though the new message will have the same body and headers as the old message it will be slightly different because the JMS specification dictates that when a message is sent the broker must assign it a message ID and timestamp. Therefore the JMSMessageID and JMSTimestamp on the new message will be different from the old message, and there's really no way around that. If you need to identify the message uniquely you should set the correlation ID on the original message and use that to identify the message rather than the JMSMessageID. Also, if you need to preserve the original time the message was sent then set that in a custom property.
The reason the JMSMessageID and JMSTimestamp are not changed when moving the messages via the management console is because the broker moves the messages internally with a completely different mechanism than JMS.

toD() - Dynamic URI formation in camel 2.23 scheduled via Quartz

I'm newbie to Apache camel and wanted to Implement the toD() which is to dynamically frame the URI and add request params values from Beans..
Code snippet below -
from("quartz2://timer?cron=0+0/1+++*+?")
.noAutoStartup().routeId(ROUTE_ID).log("Route Started")
.toD(http://localhost:3420/contextpath?from=${bean:bean.from} "+ "&size=${bean:bean.size}")
.process(processor)
Seems like, on every hit via Quartz the same URL is being triggered and hence I see duplicate values saved to DB.
Please suggest why Dynamic uri is not working as expected.
Am calling the processor, computing and setting the Bean values which i get from Response of Endpoint. But when the next time Quartz hits the url, the bean values are not updated and takes the default value
. Bean definition is usual getter setter, and registration is I have used Simple registry
SimpleRegistry simpleRegistry = new SimpleRegistry ();
// create CamelContext
context = new DefaultCamelContext (simpleRegistry);
simpleRegistry.put("bean", bean);
Thanks in Advance
In order to use dynamic URI on a camel-route you must include your variable inside a Simple expression.
Since Camel 2.16.0 release endpoint implementation toD() supports the Simple expression language so you can define a dynamic-URI as message-endpoint:
from("quartz2://timer?cron=0+0/1+++*+?")
.noAutoStartup()
.routeId(ROUTE_ID)
.log("Route Started")
.toD( "http://localhost:3420/contextpath?from=${bean:bean.from}&size=${bean:bean.size}" );
So the expressions ${bean:bean.from} and ${bean:bean.size} should get directly interpolated by using Bean language inside your URI-string. This bean-component bean: tells Camel to get the bean registered with your specified name bean and call the specified methods from and size.
Apache Camel: Rest DSL, section Using Dynamic to() has also a note:
Note: we need to use .endRest() to tell Camel where the route ends, so we can go back to the Rest DSL and continue defining REST services.
Otherwise you could implement that dynamic endpoint using simple inside your regular to(). See Apache Camel: How to use a dynamic URI in to().

Dynamic interceptFrom()

The documentation for "intercepts" says:
The interceptSendToEndpoint is dynamic hence it will also trigger if a
dynamic URI is constructed that Camel was not aware of at startup
time.
The interceptFrom is not dynamic as it only intercepts input to
routes registered as routes in CamelContext.
Is there an idiomatic way to create something equivalent to a dynamic "from intercept"?
Stepping back, here is what I want to do: intercept every time a message is written to or read from a jms component, where the URI matches a certain wildcard pattern.
Then use something else than interceptFrom, such as event notifier where you can get a notification when sending/sent/received etc.
http://camel.apache.org/advanced-configuration-of-camelcontext-using-spring.html
http://camel.apache.org/eventnotifier-to-log-details-about-all-sent-exchanges.html

change cxf ws-addressing properties in camel route

i am using cxf as a producer in an apache camel route with WS-Addressing.
I know that it is possible to set the SoapAction Header inside the route via (just as example might be wrong)
...
.setHeader("SoapAction").constant("anysoapactionwanted")
.to("cxf...
is it possible to the same with the WS-Addressing Action field? Because i noticed it is sent with the wrong value. There are 2 WS-Addressing Action values i need to put in and it is decided in the camel route which one to use.
You must be deciding the the required operation based on some value. In that case use Choice-When conditional block to derive correct action.

How to capture original endpoint URI within an expression (Recipient List EIP)

I'm attempting to use the Recipient List EIP to dynamically generate the consumer endpoint URI during runtime based on configuration entries in a database (http://camel.apache.org/how-to-use-a-dynamic-uri-in-to.html). I've got a number of routes that I want to handle this way so I'd like to build something that can handle multiple routes generically.
Therefore, my idea is to keep an in memory map of these URI values keyed on some type of identifying information (original endpoint URI seems like a logical choice) which would be updated if/when the database is updated to keep the routes in sync, and prevent having to go to the database for every exchange. Using the RouteBuilder, I am setting up the route with the recipient list and Bean expression.
from(endpointUri).recipientList(bean(MyBean.class, "getUri"));
I know that I can capture various objects such as the exchange, body, headers (as long as I know the name), etc using the Bean binding for the getUri method. Is it possible to somehow get the original endpoint URI value so that I can use it as a key to fetch the correct consumer endpoint?
The Exchange interface has getFromEndpoint() method which returns an Endpoint. The Endpoint interface has getEndpointUri() method which returns a String. Perhaps that's what you need? If that's not sufficient, you could set header value(s) at some point and then subsequently retrieve them later in your route.

Resources