Configuring consumer for custom component in apache camel using Java - apache-camel

Suppose I have a Jetty component comp1 and custom component comp2, where comp1 produces an exchange and comp2 consumes it.
How do I get the exchange of Jetty component in consumer of comp2.
So far I have observed that we can obtain it in consumer's poll() method as -
SomeEndpoint endpoint = camelContext.getEndpoint("someURI", SomeEndpoint.class);
but what to configure at someURI and someEndpoint.class ?
if I mention someURI = "jetty:..", then my consumer will not consume message from anyother endpoint, so how to configure it for generic ?

You must first create skelatal code for your custom component using
mvn archetype:generate -DarchetypeGroupId=org.apache.camel.archetypes -DarchetypeArtifactId=camel-archetype-component
-DarchetypeVersion=2.14.1 -DarchetypeRepository=https://repository.apache.org/content/groups/snapshots-group
-DgroupId=org.apache.camel.component -DartifactId={YourArtifactId}
your component Prefix file is located in this location
src/main/resources/META-INF/services/org/apache/camel/component/
The name of this file is your component prefix. You provide this name when you generate the project from the first step.
Lets say its name is comp2. Now you simply need to configure your routes in this manner:
from("jetty:abc").to("comp2:xyz");
Your component's jar must be provided as dependency to the application that configures the Camel Route.
You need to implement the Component Class, Endpoint class, Consumer and Producer class in case required.

Spring DSL allow you to do something like this:
in between consumer and producer you can add you custom producer
<route>
<from uri="component1 uri"/>
your other process code
<to uri="component2 uri">
</route>

Related

Camel 2.21.1 RouterBuilder OSGI Service getting exception due to Simple language not found in OSGI Service Registry

I am extending Camel RouteBuilder in order to define a Camel route, thus my specialized class is a OSGI component and on #Activate method the camel context is being created, like:
camelContext = new OsgiDefaultCamelContext(bundleContext);
After that the camelContext.addRoute(this) method is invoked, but when the camelContext.start() method is invoked the org.apache.camel.NoSuchLanguageException is threw. Thus, looks like there is a racing condition due to org.apache.camel.language.simple.SimpleLanguage is not register yet in OSGI SR.
Note:
There is no OSGI injection in route builder specialization, thus this one will be ready to activate sooner even before camel-core components.
Then, I'm wondering if it's a issue once makes no sense to my custom bundle add Camel internal dependency (like to SimpleLanguage reference) just to get out this racing condition.
You need to do more setup of CamelContext if you manually create Camel in OSGi.
if you crate osgi camel context yourself, there is a few more setup you need to do
take a look in camel-core-osgi there is a helper class with a method that setup a bunch of stuff
I'm wondering if there is a race condition with Camel-core activator and my custom bundle (no Camel OSGI dependency at all), because bundle language is register with the following invoke stack bundle activation

Apache Camel File component base path

How do I manage to configure the File component of my Camel Context, so that all directory paths provided to its endpoints are prepended with some base path?
For example, if someone writes
file:input/customer12?include=.*\.csv
it will effectively be
file:/usr/local/share/app/exchange/input/customer12?include=.*\.csv
For example, I get the component during the Camel Context initialization like this:
FileComponent file = CAMELCONTEXT.getComponent("file", FileComponent.class);
What do I do next? createComponentConfiguration()?
addition: It's a standalone cli app which I want to be runnable from any directory
The easiest solution is start your app under folder /usr/local/share/app/exchange , but this is not an option as state in addition requirement
If you have a layer between your user input and your code, then you could inject the path. For example, Java DSL with RouteBuilder.
The last solution is override Camel's file component in component class before it create the actual endpoint.

Synchronizing camel route(s)

I have multiple routes deployed in a single camel bundle and what I'm trying to achieve is that once a single route starts execution, the other routes should not be executed until the route that got started is finished with execution.
I understand that it is possible to have the whole camelContext encompassing my routes be made single threaded but I see a drawback here in terms of performance.
Has someone had a similar use case and whats the best way to solve this? Since I'm using OSGi Blueprint DSL, any examples will be welcome.
You can use Camel's Control Bus if you need to control other routes selectively, such as starting and stopping them.
First, you need to prevent the routes you want from executing when your application is started. This is achieved with autoStartup=false in your route definition:
<route id="foo" autoStartup="false">
<from uri="activemq:queue:special"/>
<to uri="file://backup"/>
</route>
Then at the point in your running route where you want to start another route after doing stuff, simply:
<to uri="controlbus:route?routeId=foo&action=start"/>
You can also order the startup (and shutdown) of routes, explained in the Camel documentation here.

Apache Camel - Dynamically changing throttle values

Can anyone please give a sample on how to dynamically change the maxRequestsPerPeriod by using a Throttler processor instance or using a throttle element in Apache Camel ? (Reference - How to change Processor properties during runtime using Camel?)
We cannot use Expression with header because if the header is absent then the Throttler uses the old value. What we need is, in a bean based on some condition we have to update the throttle value so that it will be used until next update. In our case, we cannot use message header for this purpose.
How can we navigate the runtime processors in the route and find the Throttler to change it dynamically? Please help with a sample.
Thanks.
Thanks Claus..We will check jmx mbeans in upcoming Camel 2.16 release.
Now the following solution worked for us with Camel 2.15.2 :
Java DSL:
from("direct:start")
.routeId("throttleroute")
.throttle(ExpressionBuilder.beanExpression("throttleBean","getThrottle"))
.timePeriodMillis(2000)
.to("jms:test.MyQueue")
.beanRef("throttleBean", "receiveData");
Spring DSL:
<route id="throttleroute">
<from uri="direct:start" />
<throttle timePeriodMillis="2000">
<method ref="throttleBean" method="getThrottle" />
<to uri="jms:test.MyQueue" />
</throttle>
<to uri="bean:throttleBean?method=receiveData" />
</route>
Here throttleBean.getThrottle() method will be having the logic to generate and return the required throttle value dynamically.
You can change it using JMX eg the management api.
http://camel.apache.org/maven/current/camel-core/apidocs/org/apache/camel/api/management/mbean/ManagedThrottlerMBean.html
The mbean has JMX attributes to change the values at runtime.
In the upcoming Camel 2.16 release you can easier get hold of the jmx mbeans from java code using
https://github.com/apache/camel/blob/master/camel-core/src/main/java/org/apache/camel/CamelContext.java#L545
Just that you know the id of the mbean. You can assign ids in the routes, so its using a known id, instead of auto generated. Which btw also makes it easier to find the mbean using pure JMX api.

How to add a AggregateDefinition to camel context at runtime

I have a route that uses aggregation strategy, because of that it produces a AggregateDefinition as opposed to RouteDefinition. The CamelContext provides API to add a RouteDefinition but not an AggregateDefinition.
How can I add an AggregateDefinition to the camel context dynamically at runtime ?
Thanks
Srikanth.
You can load/update routes from xml files as shown here:
http://camel.apache.org/loading-routes-from-xml-files.html
Otherwise CamelContext has Java API to add/remove/update routes as well. For example you can use a RouteBuilder class and just add that to the camel context using the api.

Resources