【问题标题】:How to conditionally load a camel route based on a flag?如何根据标志有条件地加载骆驼路线?
【发布时间】:2015-04-09 10:07:43
【问题描述】:

我有一个使用 apache camel、activemq 等的应用程序。我还使用 camel-cache 来缓存对象。我正在尝试并行运行所有测试类以减少构建时间。这是我使用的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>

这将为每个测试类创建一个新的骆驼上下文。除了缓存的问题外,这将运行良好。我们有一个初始化缓存的路由,如下所示:

 <route id="xcache">
   <from uri="cache://xCache?maxElementsInMemory=1000&amp;overflowToDisk=true&amp;timeToLiveSeconds=300&amp;timeToIdleSeconds=200" />
   <log loggingLevel="INFO" logName="IFATMSTrace" message="X Cache configuration initialized." />
 </route>

多个 camelContexts 尝试使用相同的名称“xCache”初始化缓存并抛出异常。由于种种原因,我无法让每个上下文都创建自己的缓存。为了解决这个问题,我想在测试期间完全禁用缓存,以便测试能够通过

为此,我尝试使用 autoStartup 属性手动加载缓存路由

<route id="xcache" autoStartup="false">
  .....
</route>

然后在配置文件中定义一个标志,该标志在测试上下文中为 false,然后使用 controlbus 组件手动启动它。

 <route id="startDormantRoutes">
        <from uri="timer://runOnce?repeatCount=1&amp;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&amp;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]'

【问题讨论】:

  • 你是否容易将路由端点作为一个属性,例如&lt;from uri="${xcache.route}"&gt; 并为您的测试用例设置它stub:foo 和实时版本cache://xCache....。据我了解,这应该会阻止 cache: 端点被初始化。
  • 我想我可以做到,但感觉更像是一个 hack。有没有一种简单的方法可以有条件地添加一个路由,如果它没有启动就不会做任何初始化
  • 问题是骆驼扫描所有端点并初始化它找到的任何组件。根据我的经验,我要么需要对组件进行参数化以“隐藏”它,要么在您的测试中注册组件的自定义“模拟”版本。
  • 那么,在我的测试中,我可以模拟出缓存组件,以便根本不初始化“真正的”缓存组件吗?你能指出一些资源吗

标签: java caching apache-camel


【解决方案1】:

我将其添加为答案:

问题是骆驼扫描所有端点并初始化它找到的任何组件。

根据我的经验,如果你需要阻止一个组件初始化(也许它做了一些繁重的初始化,或者占用了一个端口,或者出于任何原因),我需要:

  1. 参数化组件端点以在测试中从骆驼“隐藏”组件。
  2. 或者,在您的测试中,注册组件的自定义“模拟”版本。
  3. 或者最后,您可以考虑使用完全不同的上下文,然后从您需要的上下文开始。

也许有更简单的方法可以做到这一点,但这是我的经验。

编辑:Claus Ibsen 提出了一种模拟组件的简单方法,您为什么不试试这个:

How to mock multiple components in camel unit test?

【讨论】:

    猜你喜欢
    • 2018-09-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-13
    • 2016-04-21
    • 2018-08-08
    • 1970-01-01
    • 2023-03-03
    相关资源
    最近更新 更多