Dynamic Config Loading in Camel Application Bundle in Karaf 3.0.5 - apache-camel

I have a simple Camel Application bundle which is to be deployed in Karaf 3.0.5 under Apache Service Mix 6.1. The configuration file is placed in etc/ directory (let's say it is named as wf.cfg). I want to have the dynamic config change functionality in my application bundle. So that whenever something is changed in wf.cfg it is immediately available to bundle. For this I have added the following in my
blueprint.xml
<cm:property-placeholder persistent-id="wf"
update-strategy="reload">
<cm:default-properties>
<cm:property name="env" value="local" />
</cm:default-properties>
</cm:property-placeholder>
<!-- a bean that uses a blueprint property placeholder -->
<bean id="configBean" class="com.jabong.orchestratorservice.basecomponent.config.ConfigBean">
<property name="env" value="${env}" />
</bean>
The problem I am facing now is if the update-strategy is set to reload. Then it seems to be reloading the entire bean.
Can someone let me know is there a way I can reload only the configBean not the entire bundle? If I can achieve this then may be I can have some static reference to the config variables inside the configBean which my application bundle can then make use of?
The full blueprint.xml is placed here.

the property-placeholder can have two values for the update-strategy :
reload: The blueprint container is reloaded asynchronously when the properties change. Any property change stops the context (and shutdown camel), and restarts it with the new property. everything is done automatically.
none: Nothing is done. The context is not shutdown (and so camel), but the properties are not injected. The property change are lost
There is another way to inject properties in Aries-Blueprint, through managed-properties : They decorate a bean definition, and dynamically inject the new property into the bean when the configuration change. There are here two modes : bean-managed (invoke a method when the configuration change) and container-managed (invoke a setter when a property change).
With this managed-properties you can dynamically intercept change in the configuration, and respond to it, without restarting the blueprint context (and consequently without stopping the camel context).
However, components in camel are not so dynamics : They read the configuration when an endpoint is created, but that's all. If you want to change the configuration of the route dynamically, it's not easy or impossible. You will have to stop/start the 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

Refresh property every hour in Camel

Using this code
<propertyPlaceholder id="properties" location="file:${basedir}/etc/foo.properties"/>
Camel load foo.properties at application start: is there a way to reload foo.properties every hour?
It can be useful if foo.properties changes.
The camel-properties component has a property that can be used to control if properties have to be cached or not, see: https://github.com/apache/camel/blob/master/camel-core/src/main/docs/properties-component.adoc

How to access header and property from callee in ASynch Route in Apache Camel

I have Apache Camel Route which listens to ActiveMQ queue. During the processing, at one point, route sets the header and property on the exchange.
Now during the integration testing, we want to check the value of the header and property.
The question is, how do we access these two things ie. header and property.
I have tried using the producerTemplate's asyncRequestBody/asyncRequestBodyAndHeader etc. With Future object I can access Exchange, however, I am not able to access the header and property set on the exchange.
I have made sure that the route is InOut type.
If you can get the exchange, can you not just use exchange.getProperty(name) to get the property you're looking for?
I have set properties in my route:
<setProperty propertyName="sampleProperty">
<simple>${body}</simple>
</setProperty>
and retrieve them later using {property.sampleProperty}

How to use spring mvc controllers without component-scanning?

I use Spring 3.x MVC #Controller annotations. My servlet.xml has this entry:
<context:component-scan base-package=”com.my.controllers.package”/>
My webapp, on Google's app engine has to initialize & startup within 60secs. Mine takes longer due to this classpath scanning (This link explains the importance of "Reducing or Avoiding the Use of Component Scanning" in app engine).
I added the following line to my servlet.xml
<bean id=”myComponentBean” class=”org.foo.MyComponent”/>
Now, regardless of whether I add #Controller or not, the controller does not get loaded. Any url results in 404.
Questions:
1) So how do I make a spring 3.x MVC controller behave as a web controller without relying on the comonent scanning?
2) When I filed a bug with google, I was asked to remove the "component scanning" & to "explicitly define the classes needed using classLoader.getResource()". How can I use classLoader.getResource() to load mvc controllers?
P.S: Classpath scanning on app engine has known issues. Discussing that will be a digression here. So I skipped the details.
you are already doing it right. define your controllers with <bean class="..." /> and put <mvc:annotation-driven /> in your servlet configuration. that is it!
UPDATE:
and you may need <context:annotation-config /> as well for some annotations(#EJB, #PersistenceContext, etc.) to get handled by spring.

How to deploy Custom Dataformat in camel

I am running Camel inside Karaf.
I have created a custom dataformat by implementing DataFormat interface.
Now I have my custom class.
In order to make it visible to my camel route inside karaf where to copy this class file?
Please provide guidance.
I'd just add it to my Camel application source code and deploy it with that bundle. If you need to reuse it across several bundles, then you could package it as a separate bundle and export/import it appropriately I suppose...

Resources