I want to perform custom logic in an IdempotentConsumer. I've extended the class and implemented the logic. How can I add this to my route?
Do I have to make my own Definition class? Do I add it as a Processor? How do I get the parameters passed to the constructor?
Well, custom consumer/producer could be little overkill. I think for some kind of custom logic is enough to do it trough processor or custom bean.
1.Bean
Look at bean binding you can use simple language to pass arguments to your method. It will looks like this:
.bean(OrderService.class, "doSomething(${body}, true)")
.to("bean:orderService?method=doSomething(null, true)")
2.Processor
You have to realize your classes should be stateless because of concurrent matter of camel framework. Your constructor should be empty and your variables final otherwise whole bunch of magic could happen. Everything you want to pass to your logic component/processor should be passed via Exchange object. You can store your variables in getin() or getOut() messages as headers or body or Exchange properties and pass it to next endpoint. The exchange will change dynamically as it flows trough you camel routes. It should be your one and only one mutable object.
Related
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
I'm using ESB and Camel to provide an endpoint to my mobile apps. From there, I need to call multiple web services in such way that the response from the previous call determines whether the next should be called or not and need to pass the same request parameters to the multiple calls.
Additionally, I need to save those response in the database.
I would like to know the best pattern by which we can implement this particular use case using Camel.
there are many ways to do it - just think how you'd like to do such logic as example in pure Java then move it to Camel. From actions flow prospective there is no difference. You have condition - you have to have IF or SWITCH operations that's it.
Straight-forward way.
After calling previous service you have a response in body with attribute that is a decision factor for next call. So, use Camel "choice-when-otherwise" structure (analog of Java "switch" statement) and in "when" use any available ways to check condition from body (i.e. "simple", "xpath", "xquery" etc.)
If logic to identify next call is more complex - create your custom processor which will identify next call, set special exchange property and then go to the same "choice-when-otherwise" block
For that case as example you can have some map with <"previous-result","next-call"> or do it as you'd like to.
and your route may look like (I use Spring):
<cml:to uri="previous_uri"/>
<cml:processor ref="my_selector"/> <!-- it sets Exchange property "next_call" based on result from previous -->
<cml:choice>
<cml:when>
<cml:simple>${exchangeProperty.next_call} =="SERVICE1"/>
<cml:to uri="next_service1_uri"/>
... process Service1 result logic ...
</cml:when>
<cml:when>
<cml:simple>${exchangeProperty.next_call} =="SERVICE2"/>
<cml:to uri="next_service2_uri"/>
... process Service2 result logic ...
</cml:when>
and so on...
Is there a way to set a property at the level of a Route, rather than an Exchange.
As a simplified example, if I wanted to have something like invocation-count or last-invoked-time and check/update it each time the route was triggered, how would I implement it?
You could implement that a number of ways.. using a simple Java class as a processor right after the "from", or as an interceptor (use interceptFrom): http://camel.apache.org/intercept.html.
Curiously though.. you should consider using the out-of-the-box Camel metrics. You should be covered by the defaults.
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.
I have create a camel context; this camel context is having 4 routes. These all routes are related to complete a same feed processing operations. Now I have got a requirement to share a database object within the routes.
This object is supposed to be initialized at the time for context creation and should be available for all routes to validate data from.
So far; I have create a org.apache.camel.StartupListener and registered with the context. This listener will add some properties to the context. But my requirement does not ends with the only string values. I have to put a object in the context.
What should I do to add this object in the Camel Context?
You can always create a normal bean to keep reference to your shared object and get the bean like this in all routes:
MyBean myBean=exchange.getContext().getRegistry().lookup("MyBean",MyBean.class);
Or directly add your shared object as a bean (if possible)