Dynamic interceptFrom() - apache-camel

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

Related

in-Message copied in out-Message

I have this simple route in my RouteBuilder.
from("amq:MyQueue").routeId(routeId).log(LoggingLevel.DEBUG, "Log: ${in.headers} - ${in.body}")
As stated in the doc for HTTP-component:
Camel will store the HTTP response from the external server on the OUT body. All headers from the IN message will be copied to the OUT message, ...
I would like to know if this concept also applies to amq-component, routeId, and log? Is it the default behaviour, that IN always gets copied to OUT?
Thank you,
Hadi
First of all: The concept of IN and OUT messages is deprecated in Camel 3.x.
This is mentioned in the Camel 3 migration guide and also annotated on the getOut method of the Camel Exchange.
However, it is not (yet) removed, but what you can take from it: don't care about the OUT message. Use the getMessage method and don't use getIn and getOut anymore.
To answer your question:
Yes, most components behave like this
Every step in the route takes the (IN) message and processes it
The body is typically overwritten with the new processing result
The headers typically stay, new headers can be added
So while the Camel Exchange traverses the route, typically the body is continuously updated and the header list grows.
However, some components like aggregator create new messages based on an AggregationStrategy. In such cases nothing is copied automatically and you have to implement the strategy to your needs.

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.

Custom IdempotentConsumer/Processor in Apache Camel

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.

Camel content based router with a lot of conditions

I have a message with a certain value (e.g. 100, 101) in header and I need to take a specific action depending on that value.
I know I can write a route with when / otherwise branches for content-based routing.
My question is: what if I have about 400 different cases? Is there a best practice in these cases to manage the routing?
Yes use recipient list instead which can compute the endpoint dynamically - eg its a dynamic to. See this FAQ link for further details: http://camel.apache.org/how-do-i-use-dynamic-uri-in-to.html
another option is to use a ProducerTemplate to send messages to any endpoint from a POJO class, just need to inject/pass in a handle to the CamelContext, etc.

What's the difference between "direct:" and to() in Apache Camel?

The DirectComponent documentation gives the following example:
from("activemq:queue:order.in")
.to("bean:orderServer?method=validate")
.to("direct:processOrder");
from("direct:processOrder")
.to("bean:orderService?method=process")
.to("activemq:queue:order.out");
Is there any difference between that and the following?
from("activemq:queue:order.in")
.to("bean:orderServer?method=validate")
.to("bean:orderService?method=process")
.to("activemq:queue:order.out");
I've tried to find documentation on what the behaviour of the to() method is on the Java DSL, but beyond the RouteDefinition javadoc (which gives the very curt "Sends the exchange to the given endpoint") I've come up blank :(
In the very case above, you will not notice much difference. The "direct" component is much like a method call.
Once you start build a bit more complex routes, you will want to segment them in several different parts for multiple reasons.
You can, for instance, create "sub routes" that could be reused among multiple routes in your Camel context. Much like you segment out methods in regular programming to allow reusability and make code more clear. The same goes for sub routes using, for instance the direct component.
The same approach can be extended. Say you want multiple protocols to be used as endpoints to your route. You can use the direct endpoint to create the main route, something like this:
// Three endpoints to one "main" route.
from("activemq:queue:order.in")
.to("direct:processOrder");
from("file:some/file/path")
.to("direct:processOrder");
from("jetty:http://0.0.0.0/order/in")
.to("direct:processOrder");
from("direct:processOrder")
.to("bean:orderService?method=process")
.to("activemq:queue:order.out");
Another thing is that one route is created for each "from()" clause in DSL. A route is an artifact in Camel, and you could do certain administrative tasks towards it with the Camel API, such as start, stop, add, remove routes dynamically. The "to" clause is just an endpoint call.
Once starting to do some real cases with somewhat complexity in Camel, you will note that you cannot get too many "direct" routes.
Direct Component is used to name the logical segment of the route. This is similar process to naming procedures in structural programming.
In your example there is no difference in message flow. In the terms of structural programming, we could say that you make a kind of inline expansion to your route.
Another difference is Direct component doesn't has any thread pool, the direct consumer process method is invoked by the calling thread of direct producer.
Mainly its used for break the complex route configuration like in java we used to have method for reusability. And also by configuring threads at direct route we can reduce the work for calling thread .
from(A).to(B).to(OUT)
is chaining
A --- B --- OUT
But
from(A ).to( X)
from(B ).to( X)
from( X).to( OUT )
where X is a direct:?
is basically like a join
A
\____ OUT
/
B
obviously these are different behaviours, and with the second you could implement anylogic you wanted, not just a serial chain

Resources