Camel in OSGi Container: Apply InterceptStrategy to all camel contexts
Asked Answered
A

3

22

I have several bundles (A, B, and C) deployed to an OSGi container, each containing a CamelContext and some routes. I have another bundle (M) with a CamelContext with a route (for collecting monitoring data) and a InterceptStrategy bean. I would like the InterceptStrategy bean from M to automatically apply to all of the other CamelContexts in the container (i.e., those in A, B, and C), without having to modify the other bundles.

Ultimately, the goal is to wiretap data from each CamelContext into the route in M, without having to make any changes to A, B, or C to explicitly route the Exchange. Is this approach or a similar approach doable?

All of the CamelContexts are configured using Spring XML.


Update: Additional Context

Bundles A, B, and C contain the core product responsible for processing data. Bundle M contains an optional monitoring tool, designed to measure certain parameters of the data flowing through A, B, and C. Currently, adding on the optional tool requires changing the routes in A, B, and C to add additional Processors to enrich the Exchange with the monitoring data and to read the monitoring data prior to <to /> endpoints.

The goal is to be able to drop in Bundle M into a already verified-as-working system with A, B, and C; and have it automatically apply to the existing routes without having to modify the configuration for the existing-and-working bundles. It is acceptable to make modifications to A, B, and C to support this, as long as the changes do not cause A, B, and C to rely on M to run (i.e., ABC must still run without M).

If there is a better means to do this than using interceptors, I am open to that. The primary goals are:

  1. Keep A, B, and C decoupled from M (particularly during development)
  2. Ensure integrating M with A, B, and C is as easy as possible
  3. Allow M to be integrated without having to manually change A, B, or C
Azerbaijan answered 22/4, 2015 at 23:29 Comment(0)
E
4

I dont think this is possible using InterceptorStrategy since that expects it is running in the same camel context. The only ways I am aware of working across multiple contexts is using the VM endpoint (which is obviously limited to the same JVM), however in this case you would probably be better utilising JMS, JMX or something similar.

JMS

Create an InterceptorStrategy for each camel context in A, B & C that publishes your messages to M

intercept().bean(transformForMonitoring).to("jms:queue:monitoring");

from("whatever:endpoint")
    .process(myProcessor)
    .to("target:endpoint");

You could also use the vm component on the intercept() if you dont want the overhead of JMS, however this limits your monitoring component to a single JVM.

JMX

This is a bit more complicated, but the basic idea is to tell the camel context to publish MBeans for A, B & C

<camelContext id="camel" xmlns="http://camel.apache.org/schema/spring">
  <jmxAgent id="agent" mbeanObjectDomainName="your.domain.name"/>
    ...
</camelContext>

and then have M connect to the JVM MBean Server and utilise something like NotificationListener to react to the Exchanges.

En answered 7/5, 2015 at 10:37 Comment(2)
I like the ideas you've presented here, but there is an issue which wasn't clear from my description: some of the steps of the monitoring code need to be executed synchronously in the routes in A, B, and C (since they, for example, set properties on the Exchange), so simply directing messages to an asychronous queue is insufficient. I see that in Camel 2.16.0 the direct-vm component will be able to handle a no-present-consumers condition, which would solve the issue. Do you know of any analogous mechanism available in Camel 2.12.0 that would allow for synchronous-but-optional routing?Azerbaijan
No, not one that will work across camel contexts, unless you want to use something like a web service call in the interceptor and just swallow any exception if there is no listener..En
K
2

One of the possibility is define a custom Tracer in Bundle 'M' and export it as osgi service.

In bundle A,B,C define osgi-reference to exported Tracer bean

Use camel JMX to enable trace.

This will result changes in bundle A,B,C but it will be minimal and it will also give ability to integrate and configure tracing (intercepting)

I have not tried this myself, but hth

Kelley answered 7/5, 2015 at 14:57 Comment(2)
We have tried something similar. The problem with this approach is that bundles A, B, and C will not start without M present, since the osgi:reference will not be satisfied. Is there a way around this?Azerbaijan
If you are using spring-dm...you can set cardinality [0..1] on the reference, If not can you try setting resolution as optional for the reference interface in manifest?Kelley
H
1

Either use Spring-DM, or better transform all your spring xml based routes to blueprint ones. This is the best supported way of using XML based Routes in Karaf/Osgi.

Holster answered 23/4, 2015 at 6:55 Comment(4)
Can you provide an example of how Spring-DM can help here? It's one of the things I originally looked at, but all of the solutions I found using it involved modifying bundles A, B, and C (for example to add a <osgi:reference> tag).Azerbaijan
In this case spring-dm makes sure all spring contextes are properly started, and the wiring of your Spring Beans is handled correctly. Of course it also is used to reference osgi services to be injected in your application.Holster
But that still doesn't help in this specific case (causing a bean to be available in other bundles without modifying the bundle containing it), as far as I can tell.Azerbaijan
No, for that you'll need the proper import-package export-package. But, if those are wired correctly the spring-dm extender helps to find thoseHolster

© 2022 - 2024 — McMap. All rights reserved.