This is a blog post I have had on my todo pad for a while meant to be written sooner. Anyway I got a bit of breather this morning, and wanted to get this done before the 2.10 is released.
BackgroundSo the issue people may have is when they run many Camel applications in the same JVM, such as in Apache ServiceMix, Apache Karaf, Fuse ESB, Fuse ESB Enterprise, Fuse Fabric, and the classic web and JEE servers such as Apache Tomcat, Jetty, JBoss, et all. Its the JMX naming.
So in the JMV we have a default JMX server in which we enlist Camel MBeans, allowing you to manage and monitor Camel apps using JMX. As there is one JMX server, and multiple Camel applications, then we need to ensure the MBeans have unique ObjectName's so they dont clash.
Apache Camel has out of the box a liberal strategy to cater for this, and in case of a clash, it will by default, auto remedy this by computing a unique name, using a counter based approach.
For example this may give you ObjectNames with names that contains the counter in the name such as:
The default naming strategy is to use the CamelContext id (eg name) and apply the counter in case of clash. So if you use unique CamelContext id in your Camel applications, then you already have unique ObjectName's in the JMX, and thus no clashes.
The default strategy in OSGi containers is a bit different, as the naming is prepended with the bundle id, which gives us out of the box names such as
And in case you have multiple Camel applications in the *same* bundle, then the naming will use the counter, like for non OSGi environments
Okay you have read so far, this is good. So lets get to the point where things have improved in Camel 2.10, and what you can do in previous Camel releases.
The issues is that in OSGi containers, the bundle-id would by default always be prepended, so controlling the naming was a bit harder. What you can do to remedy this in previous Camel releases is to use a custom org.apache.camel.spi.ManagementNamingStrategy, allowing you full control of the namings of the ObjectName's. The problem is that you would then need to implement this interface and code an implementation. So what we have done in Camel 2.10 is to let you configure the naming using a pattern style, much more easily.
To see this in action, lets walk through an use-case.
Walking through an exampleThis example is created by using the Camel Maven archetype to create a new OSGi Blueprint project, using the camel-archetype-blueprint. This is a simple example that can easily be deployed in an OSGi container such as Apache Karaf. When the project is created, I can compile and build the artifact using mvn install.
I have a vanilla Apache Karaf 2.2.7 extracted, and start it using bin/karaf.
__ __ ____
/ //_/____ __________ _/ __/
/ ,< / __ `/ ___/ __ `/ /_
/ /| |/ /_/ / / / /_/ / __/
/_/ |_|\__,_/_/ \__,_/_/
Apache Karaf (2.2.7)
and '[cmd] --help' for help on a specific command.
Installing Apache Camel in Karaf is now easier using the new chooseurl command as shown below:
karaf@root> features:chooseurl camel 2.10.0
adding feature url mvn:org.apache.camel.karaf/apache-camel/2.10.0/xml/features
karaf@root> features:install camel
After installing Camel I can install my application using:
karaf@root> osgi:install mvn:com.mycompany/blue/1.0
Bundle ID: 75
And then I can start the bundle by its id
karaf@root> osgi:start 75
And list the installed bundles
START LEVEL 100 , List Threshold: 50
ID State Blueprint Spring Level Name
[ 64] [Active ] [ ] [ ] [ 50] camel-core (2.10.0)
[ 65] [Active ] [Created ] [ ] [ 50] camel-karaf-commands (2.10.0)
[ 72] [Active ] [ ] [ ] [ 50] geronimo-jta_1.1_spec (1.1.1)
[ 73] [Active ] [ ] [ ] [ 50] camel-spring (2.10.0)
[ 74] [Active ] [Created ] [ ] [ 50] camel-blueprint (2.10.0)
[ 75] [Active ] [Created ] [ ] [ 80] A Camel Blueprint Route (1.0.0)
Then I start JConsole to see the JMX tree
|JMX name is 75-blueprintContext|
Now the issue for some users, is that they may uninstall their applications, and then at a later time install the application again. So lets uninstall our application
karaf@root> osgi:uninstall 75
And then at a later time we install it again. Now the OSGi container will assign the bundle a new bundle id (as it will never re-use a previous bundle id).
Notice: You can update/refresh your existing application, and keep the bundle id. Its only when you uninstall the bundle, that the bundle id, is discarded, and not used again.
karaf@root> osgi:install mvn:com.mycompany/blue/1.0
Bundle ID: 76
karaf@root> osgi:start 76
And if we see in JConsole we can see the Camel application now has a different JMX ObjectName.
|JMX name is now 76-blueprintContext|
There is a new managementNamePattern attribute in the
|Camel 2.10 using the new managementNamePattern attribute|
- #camelId# = the CamelContext id (eg the name)
- #name# = same as #camelId#
- #counter# = an incrementing counter
- #bundleId# = the OSGi bundle id (only for OSGi environments)
- #symbolicName# = the OSGi symbolic name (only for OSGi environments)
- #version# = the OSGi bundle version (only for OSGi environments)
Besides the tokens you can use literals, so for example you can do managementNamePattern="foo-#symbolicName#" to have foo- as pre-prended value.
I then rebuild the project using mvn install, and from Karaf I update my application using:
karaf@root> osgi:update 76
And when I look in JConsole now, I can see the JMX naming is no longer having the bundleId prefixed.
|JMX name is no longer having bundleId prefixed|
|Locked down JMX ObjectName|
Runtime insight to Camel applicationsMy application is now running in Apache Karaf, and I can use the Camel Karaf commands to give me some details about my application, such as the context-info command telling me a bit about the uptime, and number of messages (is called exchanges) processed by Camel:
karaf@root> camel:context-info blueprintContext
Camel Context blueprintContext
Uptime: 3 minutes
Exchanges Total: 39
Exchanges Completed: 39
Exchanges Failed: 0
Min Processing Time: 1ms
Max Processing Time: 366ms
Mean Processing Time: 11ms
Total Processing Time: 442ms
Last Processing Time: 3ms
Load Avg: 0.00, 0.00, 0.00
First Exchange Date: 2012-06-20 09:53:11
Last Exchange Completed Date: 2012-06-20 09:56:21
This is all text based, and using a tool such as Fuse IDE I can see all this in real time and visualized using EIP icons as shown below
|Fuse IDE with real time visual insight of my running Camel applications in any JVM|
|Fuse IDE can manage bundles running in the OSGi container|
And know that I talk about Fuse IDE, then it has a nice terminal built-in. This is something that Windows users may struggle with normally, as they would need to use cygwin or something alike to SSH into remote machines. The terminal in Fuse IDE can connect to any remote box, or local running instances such as Apache Karaf.
|Fuse IDE with SSH terminal to access Apache Karaf|