Apache Camel将XML路由和bean从文件加载到CamelContext中

时间:2016-12-06 15:20:27

标签: java spring apache-camel

所以,现在我正在尝试将路径从XML文件导入Java DSL。

我一直试图从this link开始,但由于它是一个如此简单的例子,它并没有真正帮助我,并没有指向我更多复杂的例子。

我的问题是我的Camel路由使用bean。 PropertiesComponentFileIdempotentRepository及其他的Bean在XML文件中定义,供XML文件中的路由使用。

我原来的Spring配置如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
 http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd">

<bean id="bean1" class="class1" />
<bean id="bean2" class="class2" />
<bean id="bean3" class="FileIdempotentRepository"> [...] </bean>
<bean id="properties" class="PropertiesComponent"> [...] </bean>

  <camelContext xmlns="http://camel.apache.org/schema/spring">
      <route>
          <from uri="{{someplace}}&amp;filter=#bean1" />
          <setHeader headerName="FileRepoKey">
              <simple>${file:name}-${file:modified}</simple>
          </setHeader>
          <idempotentConsumer messageIdRepositoryRef="bean3">
              <header>FileRepoKey</header>
              <process ref="bean2" />
              <to uri="{{otherplace}}"/>
          </idempotentConsumer>
      </route>
  </camelContext>
</beans>

那么我如何将这个混乱转换为Java DSL可用于从中导入路由的东西?

通过查看我需要执行的操作,例如将<camelContext>转换为<routes>,我理解了这一点。但留在豆子里给我一个错误:

Exception in thread "main" javax.xml.bind.UnmarshalException: unexpected element (uri:"http://www.springframework.org/schema/beans", local:"beans"). Expected elements are [...]

我需要改变什么?或者我可以在XML文件中没有bean,以便由链接中使用的Java导入它吗?

2 个答案:

答案 0 :(得分:0)

Camel中的路由定义可以是基于XML(Spring DSL或Blueprint DSL)或基于Java(Java DSL)。路线定义可以用两种语言表达。

在Spring应用程序中,您可以在文件中定义bean,并在导入的其他文件中定义路由。外部文件中定义的路由可以引用主文件中定义的bean。

<强>弹簧main.xml中

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
 http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd">

    <bean id="bean1" class="class1" />
    <bean id="bean2" class="class2" />
    <bean id="bean3" class="FileIdempotentRepository"> [...] </bean>
    <bean id="properties" class="PropertiesComponent"> [...] </bean>

    <import resource="camel-routes.xml"/>
    <camelContext xmlns="http://camel.apache.org/schema/spring">
        <routeContextRef ref="ExternalRoutes"/>
    </camelContext>
</beans>

<强>驼routes.xml

<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="
   http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
   http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd">

    <routeContext id="ExternalRoutes" xmlns="http://camel.apache.org/schema/spring">

        <route id="ARoute">
            <from uri="direct:startHere" />
            <to uri="bean:bean3" />
        </route>
    </routeContext>
</beans>

当然,您可以导入多个外部文件。只需以不同方式命名每个RouteContext

如果您修改其中一个RouteContext,则必须重新启动应用程序。如果您需要更动态的应用程序,请尝试使用an OSGi container来运行Camel路由,这样您就可以轻松地模块化应用程序并在运行时添加/删除功能。

答案 1 :(得分:0)

我想我应该以不同的方式问这个问题,也许有人会想到这种方式。

它可能会让你做所有的噩梦,我不确定。警告。

因为这个概念是&#34;有可能从XML文件和Java一起运行的东西&#34;结果如下:

    public static void main(String[] args) throws Exception {

    Main main = new Main();

    //the XML file has a CamelContext in it. 
    main.setApplicationContextUri("myRoutes.xml");
    main.start();//instantiates the CamelContext so we can use it in Java
    List<CamelContext> camelContexts = main.getCamelContexts(); //should only have 1 item in the list
    CamelContext context = camelContexts.get(0);

    //in order to add a component to the registry the following is needed for set up
    //  afterwards, should just be able to add anything to the registry with registry.put("name", object)
    final SimpleRegistry registry = new SimpleRegistry();
    final CompositeRegistry compositeRegistry = new CompositeRegistry();
    compositeRegistry.addRegistry(context.getRegistry());
    compositeRegistry.addRegistry(registry);
    ((DefaultCamelContext) context).setRegistry(compositeRegistry);

    final FileIdempotentRepository myFileStore = new FileIdempotentRepository();
    File myFile = new File("idempotentRepoFiles/myFileStore.txt");

    final TimeStampFileFilter<?> myFileFilter = new TimeStampFileFilter<Object>(0L);
    registry.put("myFileFilter", myFileFilter);

    //512MB
    myFileStore.setMaxFileStoreSize(536870912L);
    myFileStore.setFileStore(myFile);
    myFileStore.setCacheSize(100000);

    //add a route to the CamelContext that was initially created in the XML file
    context.addRoutes(new RouteBuilder() {

        @Override
        public void configure() throws Exception {
            onException(myException.class)
                .handled(true);
            onException(GenericFileOperationFailedException.class)
                .onException(SocketException.class)
                .maximumRedeliveries(2)
                .redeliveryDelay(5000L)
                ;
            Processor myProcessor = new myProcessor();
            from("{{myStart}}&filter=#myFileFilter")
            .setHeader("myFileRepoKey", simple("${file:name}-${file:modified}"))
            .idempotentConsumer(header("myFileRepoKey"), myFileStore)
            .process(myProcessor)
            .to("{{myEnd}}")
            ;

        }

    });

    context.start();
    main.run();
}

基本上:在Spring XML文件中创建一个CamelContext,初始化它,抓取它,修改它以包含用Java构建的路由。