OSGi容器中的骆驼:将InterceptStrategy应用于所有骆驼上下文

22
我有几个捆绑包(A,B和C)部署在一个OSGi容器中,每个包都包含一个CamelContext和一些路由。我有另一个捆绑包(M),其中包含一个带有路由(用于收集监控数据)和InterceptStrategy bean的CamelContext。我希望来自M的InterceptStrategy bean自动应用于容器中的所有其他CamelContext(即A,B和C中的那些),而无需修改其他捆绑包。
最终目标是将每个CamelContext中的数据导入M中的路由中,而无需对A、B或C进行任何更改以显式路由Exchange。这种方法或类似方法可行吗?
所有的CamelContext都使用Spring XML配置。
更新:其他上下文说明
捆绑包A、B和C包含负责处理数据的核心产品。捆绑包M包含一个可选的监控工具,旨在测量通过A、B和C流动的某些参数。目前,添加可选工具需要更改A、B和C中的路由,以添加额外的处理器来丰富Exchange数据并在端点之前读取监控数据。
目标是能够将Bundle M投入已经验证为工作正常的系统中,与A、B和C自动应用于现有路由,而无需修改现有且正常运行的捆绑包的配置。允许对A、B和C进行修改以支持此操作,只要更改不会使A、B和C依赖于M运行(即,ABC必须仍然在没有M的情况下运行)。
如果比使用拦截器更好的方法,我也可以接受。主要目标是:
1. 保持A、B和C与M分离(尤其是在开发过程中) 2. 确保将M与A、B和C集成尽可能简单 3. 允许M集成,而无需手动更改A、B或C
3个回答

4
我认为使用InterceptorStrategy不可能实现这一点,因为它期望在同一个Camel上下文中运行。我所知道跨多个上下文的唯一方法是使用VM端点(显然仅限于同一JVM),但在这种情况下,您最好使用JMS、JMX或类似的东西。 JMSA、B和C中的每个Camel上下文创建一个InterceptorStrategy,将您的消息发布到M
intercept().bean(transformForMonitoring).to("jms:queue:monitoring");

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

你还可以在intercept()中使用vm组件,如果你不想要JMS的开销,但这会将你的监控组件限制在单个JVM上。
JMX
这有点复杂,但基本思路是告诉Camel上下文为A、B和C发布MBeans。
<camelContext id="camel" xmlns="http://camel.apache.org/schema/spring">
  <jmxAgent id="agent" mbeanObjectDomainName="your.domain.name"/>
    ...
</camelContext>

然后,让M连接到JVM MBean服务器,并利用像NotificationListener这样的工具来响应交换操作。


1
我喜欢你在这里提出的想法,但有一个问题在我的描述中并不清楚:监视代码的某些步骤需要在ABC路由中同步执行(例如,在Exchange上设置属性),因此仅将消息定向到异步队列是不够的。我看到在Camel 2.16.0中,直接-vm组件将能够处理无消费者条件,这将解决该问题。您是否知道在Camel 2.12.0中是否有类似的机制可用于同步但可选的路由? - VeeArr
不,除非你想在拦截器中使用类似Web服务调用的东西并且如果没有监听器就忽略任何异常,否则它将无法跨越驼峰上下文工作。 - stringy05

2
其中一种可能性是在Bundle 'M'中定义一个自定义跟踪器并将其导出为OSGi服务。
在Bundle A、B、C中定义对导出的跟踪器Bean的OSGi引用。
使用Camel JMX启用跟踪。
这将导致Bundle A、B、C中的更改,但它将是最小的,并且还将提供集成和配置跟踪(拦截)的能力。
我自己没有尝试过这个方法,但希望能有所帮助。

我们尝试过类似的方法。这种方法的问题在于,如果没有M存在,捆绑包A、B和C将无法启动,因为osgi:reference无法满足。有没有什么解决办法? - VeeArr
1
如果您使用spring-dm......,则可以在引用上设置基数[0..1]。如果没有,您可以尝试在清单中将解析设置为可选的引用接口。 - Dhananjay

1

要么使用Spring-DM,要么将所有基于Spring XML的路由转换为Blueprint。这是在Karaf/Osgi中使用XML based Routes的最佳支持方式。


你能提供一个Spring-DM如何帮助的例子吗?这是我最初考虑的事情之一,但我发现使用它的所有解决方案都涉及修改Bundle A、B和C(例如添加<osgi:reference>标签)。 - VeeArr
在这种情况下,spring-dm 确保所有的 Spring 上下文都被正确启动,并且处理您的 Spring Beans 的连线。当然,它也用于引用 OSGi 服务以注入到您的应用程序中。 - Achim Nierbeck
但就我所知,在这种特定情况下(使一个bean在其他bundle中可用而不修改包含它的bundle),这仍然没有帮助。 - VeeArr
不,你需要正确的import-package和export-package。但是,如果这些被正确地连接,spring-dm extender可以帮助找到它们。 - Achim Nierbeck

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接