简体   繁体   English

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

[英]Apache Camel load XML routes and beans from file into CamelContext

So, now I am attempting to import routes from an XML file into the Java DSL. 因此,现在我正在尝试将路由从XML文件导入Java DSL。

I've been attempting to start with this link but since it's such a simple example, it doesn't really help me and doesn't point me to a more complicated example. 我一直在尝试从此链接开始,但是由于它是一个简单的示例,因此它并没有真正帮助我,也没有将我指向更复杂的示例。

My problem is that my Camel routes use beans. 我的问题是我的骆驼路线使用豆类。 Beans for the PropertiesComponent and FileIdempotentRepository and others are defined within the XML file for use by the routes in the XML file. 在XML文件中定义了PropertiesComponentFileIdempotentRepository以及其他FileIdempotentRepository ,供XML文件中的路由使用。

My original Spring configuration looked something like the following: 我最初的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>

So how do I convert this mess into something usable by the Java DSL to import routes from? 那么,如何将这种混乱转化为Java DSL可以用来导入路由的东西呢?

I understand from looking at that link that I need to do something like convert <camelContext> to <routes> . 通过查看该链接,我了解到我需要执行类似将<camelContext>转换为<routes> But leaving in the beans gives me an error along the lines of: 但是留给豆类给我一个类似以下的错误:

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

What do I need to change? 我需要更改什么? Or can I not have beans in the XML file in order for it to be imported by the Java used in the link? 还是我不能在XML文件中包含bean以便通过链接中使用的Java导入它?

Route definition in Camel can be XML based (Spring DSL or Blueprint DSL) or Java based (Java DSL). Camel中的路由定义可以基于XML(Spring DSL或Blueprint DSL)或基于Java(Java DSL)。 A route definition can be expressed equally in both languages. 路由定义可以用两种语言均等地表示。

In a Spring application you can define your beans in a file and your routes in other files which you import. 在Spring应用程序中,您可以在文件中定义bean,并在导入的其他文件中定义路由。 Routes defined in external files can refer to beans defined in your main file. 外部文件中定义的路由可以引用主文件中定义的bean。

spring-main.xml spring-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>

camel-routes.xml camel-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>

You can import more than one external file, of course. 当然,您可以导入多个外部文件。 Just name each RouteContext differently. 只是以不同的方式命名每个RouteContext

If you modify one of the RouteContext s you must then restart your application. 如果修改RouteContext之一,则必须重新启动应用程序。 If you need a more dynamic application, try using an OSGi container to run your Camel routes, so you can easily modularize your application and add/remove features at runtime. 如果需要更动态的应用程序,请尝试使用OSGi容器运行您的Camel路由,以便您可以轻松地模块化应用程序并在运行时添加/删除功能。

I guess I should've asked this a different way and maybe someone would have thought of this way. 我想我应该以不同的方式问这个问题,也许有人会想到这种方法。

It may give you all nightmares, I'm not sure. 我不确定这可能会给您带来噩梦。 Be warned. 被警告。

So since the concept is "have things potentially run from an XML file alongside Java" the following end result came about: 因此,由于该概念是“可以使XML文件与Java一起运行,所以可以得出以下最终结果:

    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();
}

Basically: create a CamelContext in the Spring XML file, initialize it, grab it, modify it to include routes built in Java. 基本上:在Spring XML文件中创建一个CamelContext,对其进行初始化,抓取,修改以包括Java内置的路由。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM