如何根据标志有条件地加载骆驼路线?
How to conditionally load a camel route based on a flag?
我有一个使用 apache camel、activemq 等的应用程序。我还使用 camel-cache 来缓存对象。我正在尝试 运行 我的所有测试 class 并行以减少构建时间。这是我使用的maven配置
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.18.1</version>
<configuration>
<parallel>classes</parallel>
<useUnlimitedThreads>true</useUnlimitedThreads>
</configuration>
</plugin>
这会为每个测试创建一个新的 camel 上下文 class。这 运行 很好,除了缓存的问题。我们有一个初始化缓存的路由,如下所示:
<route id="xcache">
<from uri="cache://xCache?maxElementsInMemory=1000&overflowToDisk=true&timeToLiveSeconds=300&timeToIdleSeconds=200" />
<log loggingLevel="INFO" logName="IFATMSTrace" message="X Cache configuration initialized." />
</route>
多个camelContext尝试初始化同名缓存'xCache'并抛出异常。由于各种原因,我无法让每个上下文都创建自己的缓存。为了解决这个问题,我想在测试期间完全禁用缓存,以便测试可以通过
为此,我尝试使用 autoStartup 属性手动加载缓存路由
<route id="xcache" autoStartup="false">
.....
</route>
然后在配置文件中定义了一个在测试上下文中为假的标志,然后使用控制总线组件手动启动它。
<route id="startDormantRoutes">
<from uri="timer://runOnce?repeatCount=1&delay=2000" />
<setProperty propertyName="isCacheEnabled">
<simple>${bean:myUtils?method=isCacheEnabled}</simple>
</setProperty>
<log loggingLevel="DEBUG" logName="IFATMSTrace" message="Cache Enabled : ${property.isCacheEnabled}" />
<choice>
<when>
<simple>${property.isCacheEnabled} == "true"</simple>
<to uri="controlbus:route?routeId=xcache&action=start" />
</when>
</choice>
</route>
这应该已经解决了我的问题,但是在关闭 camelcontext 期间发生了一个 NullPointerException
pool-1-thread-16] SpringCamelContext WARN Error occurred while shutting down service: org.apache.camel.impl.RouteService@63442e11. This exception will be ignored.
java.lang.NullPointerException
at org.apache.camel.component.cache.CacheConsumer.doStop(CacheConsumer.java:47)[camel-cache-2.12.0.redhat-610379.jar:2.12.0.redhat-610379]
at org.apache.camel.support.ServiceSupport.stop(ServiceSupport.java:102)[camel-core-2.12.0.redhat-610379.jar:2.12.0.redhat-610379]
并且测试用例进一步全部失败,除了 xCache 已经定义或类似的东西。
进一步调查,我发现即使根本没有加载 xcache 路由,也会加载一些与该路由相关的子服务
[ pool-1-thread-1] SpringCamelContext DEBUG Using ComponentResolver: org.apache.camel.impl.DefaultComponentResolver@4de49608 to resolve component with name: cache
[ pool-1-thread-1] DefaultComponentResolver DEBUG Found component: cache in registry: null
[ pool-1-thread-1] DefaultComponentResolver DEBUG Found component: cache via type: org.apache.camel.component.cache.CacheComponent via: META-INF/services/org/apache/camel/component/cache
[ pool-1-thread-1] DefaultManagementAgent DEBUG Registered MBean with ObjectName: org.apache.camel:context=myAdapterCamelContext,type=components,name="cache"
[ pool-1-thread-1] DefaultComponent DEBUG Creating endpoint uri=[cache://xCache], path=[xCache]
[ pool-1-thread-1] SpringCamelContext DEBUG cache://xCache converted to endpoint: Endpoint[cache://xCache] by component: org.apache.camel.component.cache.CacheComponent@7cc8ff30
[ pool-1-thread-1] DefaultManagementAgent DEBUG Registered MBean with ObjectName: org.apache.camel:context=myAdapterCamelContext,type=endpoints,name="cache://xCache"
[ pool-1-thread-1] DefaultChannel DEBUG Initialize channel for target: 'To[cache://xCache]'
我将此添加为答案:
问题是 camel 会扫描所有端点并初始化它找到的任何组件。
根据我的经验,如果您需要停止某个组件的初始化(可能它进行了一些繁重的初始化,或者占用了一个端口,或者出于其他原因),我要么需要:
- 将组件端点参数化为 "hide" 测试中来自 camel 的组件。
- 或者,在您的测试中,注册组件的自定义 "mock" 版本。
- 或者最后你可以考虑拥有完全不同的上下文,然后只启动你需要的上下文。
也许有更简单的方法,但这是我的经验。
编辑:Claus Ibsen 提出了一种简单的模拟组件的方法,你为什么不试试这个:
How to mock multiple components in camel unit test?
我有一个使用 apache camel、activemq 等的应用程序。我还使用 camel-cache 来缓存对象。我正在尝试 运行 我的所有测试 class 并行以减少构建时间。这是我使用的maven配置
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.18.1</version>
<configuration>
<parallel>classes</parallel>
<useUnlimitedThreads>true</useUnlimitedThreads>
</configuration>
</plugin>
这会为每个测试创建一个新的 camel 上下文 class。这 运行 很好,除了缓存的问题。我们有一个初始化缓存的路由,如下所示:
<route id="xcache">
<from uri="cache://xCache?maxElementsInMemory=1000&overflowToDisk=true&timeToLiveSeconds=300&timeToIdleSeconds=200" />
<log loggingLevel="INFO" logName="IFATMSTrace" message="X Cache configuration initialized." />
</route>
多个camelContext尝试初始化同名缓存'xCache'并抛出异常。由于各种原因,我无法让每个上下文都创建自己的缓存。为了解决这个问题,我想在测试期间完全禁用缓存,以便测试可以通过
为此,我尝试使用 autoStartup 属性手动加载缓存路由
<route id="xcache" autoStartup="false">
.....
</route>
然后在配置文件中定义了一个在测试上下文中为假的标志,然后使用控制总线组件手动启动它。
<route id="startDormantRoutes">
<from uri="timer://runOnce?repeatCount=1&delay=2000" />
<setProperty propertyName="isCacheEnabled">
<simple>${bean:myUtils?method=isCacheEnabled}</simple>
</setProperty>
<log loggingLevel="DEBUG" logName="IFATMSTrace" message="Cache Enabled : ${property.isCacheEnabled}" />
<choice>
<when>
<simple>${property.isCacheEnabled} == "true"</simple>
<to uri="controlbus:route?routeId=xcache&action=start" />
</when>
</choice>
</route>
这应该已经解决了我的问题,但是在关闭 camelcontext 期间发生了一个 NullPointerException
pool-1-thread-16] SpringCamelContext WARN Error occurred while shutting down service: org.apache.camel.impl.RouteService@63442e11. This exception will be ignored.
java.lang.NullPointerException
at org.apache.camel.component.cache.CacheConsumer.doStop(CacheConsumer.java:47)[camel-cache-2.12.0.redhat-610379.jar:2.12.0.redhat-610379]
at org.apache.camel.support.ServiceSupport.stop(ServiceSupport.java:102)[camel-core-2.12.0.redhat-610379.jar:2.12.0.redhat-610379]
并且测试用例进一步全部失败,除了 xCache 已经定义或类似的东西。
进一步调查,我发现即使根本没有加载 xcache 路由,也会加载一些与该路由相关的子服务
[ pool-1-thread-1] SpringCamelContext DEBUG Using ComponentResolver: org.apache.camel.impl.DefaultComponentResolver@4de49608 to resolve component with name: cache
[ pool-1-thread-1] DefaultComponentResolver DEBUG Found component: cache in registry: null
[ pool-1-thread-1] DefaultComponentResolver DEBUG Found component: cache via type: org.apache.camel.component.cache.CacheComponent via: META-INF/services/org/apache/camel/component/cache
[ pool-1-thread-1] DefaultManagementAgent DEBUG Registered MBean with ObjectName: org.apache.camel:context=myAdapterCamelContext,type=components,name="cache"
[ pool-1-thread-1] DefaultComponent DEBUG Creating endpoint uri=[cache://xCache], path=[xCache]
[ pool-1-thread-1] SpringCamelContext DEBUG cache://xCache converted to endpoint: Endpoint[cache://xCache] by component: org.apache.camel.component.cache.CacheComponent@7cc8ff30
[ pool-1-thread-1] DefaultManagementAgent DEBUG Registered MBean with ObjectName: org.apache.camel:context=myAdapterCamelContext,type=endpoints,name="cache://xCache"
[ pool-1-thread-1] DefaultChannel DEBUG Initialize channel for target: 'To[cache://xCache]'
我将此添加为答案:
问题是 camel 会扫描所有端点并初始化它找到的任何组件。
根据我的经验,如果您需要停止某个组件的初始化(可能它进行了一些繁重的初始化,或者占用了一个端口,或者出于其他原因),我要么需要:
- 将组件端点参数化为 "hide" 测试中来自 camel 的组件。
- 或者,在您的测试中,注册组件的自定义 "mock" 版本。
- 或者最后你可以考虑拥有完全不同的上下文,然后只启动你需要的上下文。
也许有更简单的方法,但这是我的经验。
编辑:Claus Ibsen 提出了一种简单的模拟组件的方法,你为什么不试试这个:
How to mock multiple components in camel unit test?