如何在From()

时间:2015-09-03 07:00:36

标签: apache ftp apache-camel camel-ftp

Apache Camel中所述,它允许在To()中编写动态URI,它是否允许在From()中编写动态URI。 因为我需要调用多个FTP位置来根据配置下载文件,我将把它存储在数据库中。

(FTPHost, FTPUser, FTPPassword, FTPSourceDir, FTPDestDir)

我将从数据库中读取这些配置,并在运行时动态地将其传递给Camel路由。

示例: 这是我必须动态编写的驼峰路由示例

<Route>
    <from uri="ftp://${ftpUser}@${ftpHost}:${ftpPort}/${FTPSourceDir}?password=${ftpPassword}&delete=true"/>
    <to uri="${ftpDestinationDir}"/>
</Route>

正如您在示例中所看到的,我需要动态传递这些提到的参数。 那么如何在From()

中使用动态uri

5 个答案:

答案 0 :(得分:6)

您可以从属性文件中读取它,如下所示,

in

ftpUser,ftpHost .... - 都是在Test.properties中声明的键

如果您想动态地从交换中获取这些变量,则不能像您在示例中提到的那样以常规方式执行此操作。您必须使用消费者模板,如下所示,

<bean id="bridgePropertyPlaceholder" class="org.apache.camel.spring.spi.BridgePropertyPlaceholderConfigurer">
    <property name="location" value="classpath:/config/Test.properties"/>
  </bean> 

<Route>
    <from uri="ftp://{{ftpUser})@${{ftpHost}}:{{ftpPort}}/${{FTPSourceDir}}?password={{ftpPassword}}&delete=true"/>
    <to uri="{{ftpDestinationDir}}"/>
</Route>

你必须从春豆或骆驼制作人那里做到这一点。使用者模板将使用给定的组件,该生产者模板将调用camel-context.xml

中声明的直接组件

注意:消费者和生产者模板的成本很高。你可以将两者注入弹簧容器中,让弹簧处理生命周期。

答案 1 :(得分:5)

从camel 2.16 on-wards,我们可以使用pollenrich组件定义轮询消费者,如文件,ftp..etc,动态url /参数值如下所示

<route>
  <from uri="direct:start"/>
  <pollEnrich>
    <simple>file:inbox?fileName=${body.fileName}</simple>
  </pollEnrich>
  <to uri="direct:result"/>
</route>

它真棒!

参考:http://camel.apache.org/content-enricher.html

答案 2 :(得分:1)

我帮助一个操作消息代理的团队每天切换大约一百万条消息。有超过50个目的地,我们必须通过所有文件共享品牌轮询文件(FTP,SFTP,NFS /文件:...)。与单个FILE连接器相比,每个侦听不同本地/远程目录的最多50个部署确实是一个开销,根据每个部分的具体时间表和安全设置,这些连接器能够在50个位置轮询文件...相同的故事获取来自pop3和IMAP邮箱的电子邮件。

在Camel中,解决方案的概要如下:

  • 您别无选择,只能使用java DSL至少配置路径的 from()部分,并使用您确实可以从数据库读取/构建的URI或从中获取的URI发起新路由的管理员请求。 XML DSL只允许injecting properties在构建Camel上下文时解析一次,之后再也不会解决。
  • 基本思路是启动路由,让它们运行(监听或轮询精确资源),然后关闭&amp;使用 Camel上下文 API按需重建它们以管理RouteDefinitions,Routes和可能的Endpoints的状态
  • 就个人而言,我喜欢在极简主义路线上实现这种动态的from()实例化,只需要来自&#39;来自&#39;路径的一部分,即from(uri).to("direct:inboundQueue").routeId("myRoute"),然后在java或XML中定义处理剩余过程的公共路径块:from("direct:inboundQueue").process(..).etc... .to(outUri)
  • 我强烈建议将 Camel Spring框架结合使用,尤其是Spring MVC(或Spring Integration HttpGateway)这样您就可以快速构建REST,SOAP,HTTP / JSP或JMX bean接口,以管理Spring + Camel容器中的路由创建,销毁和更新,nicely integrated
  • 然后,您可以在Spring应用程序上下文中声明一个扩展SpringRouteBuilder的bean,就像使用java DSL in Spring构建Camel路由一样;在强制@Override configure()方法实现中,您应保存由from(uri)方法构建的 routeDefinition 对象,并为其指定已知的String route-id 使用.routeId(route-id)方法;例如,您可以使用route-id作为已创建和启动的路径定义对象的Map中的键,以及URI的数据库中的键。
  • 然后使用新方法扩展您声明的SpringRouteBuilder bean createRoute(route-id) updateRoute(route-id) removeRoute(路线-ID);创建或更新所需的关联route-id参数将从数据库或其他注册表中获取,并且在RouteBuilder bean中运行的相关方法将利用getContext()工具来检索当前{{1 }},反过来用于ModelCamelContextstopRoute(route-id),然后removeRoute(route-id) 这里是您需要routeDefinition对象的地方 addRouteDefinition(,以及最后)(注意:注意可能不会删除的鬼端点,如removeRoute() javadoc中所述)
  • 您的管理界面(通常采用处理HTTP / REST / SOAP流量的Spring @Controller组件/ bean的形式)确实可以很容易地获得先前创建的startRoute(route-id)扩展Bean注入Spring中的控制器bean,因此可以访问已添加到SpringRouteBuilder扩展Bean的所有必需的createRoute(route-id)updateRoute(route-id)removeRoute(route-id)方法。

这很好用。适用于所有错误处理和验证代码的确切实现是在此处发布的代码太多,但是您拥有相关的所有链接&#34;如何&#34;&#34;在上面。

答案 3 :(得分:0)

我认为您可以在Camel路线中实施您的要求。

因为您想要轮询多个FTP站点,所以您必须以某种方式触发此过程。也许你可以基于Quartz2计时器来做这件事。触发后,您可以阅读已配置的FTP站点from your database

为了轮询给定的FTP站点,您可以使用Content Enricher pattern轮询(请参阅:pollEnrich)动态评估的URI。

您的最终基本路线可能看起来像这样(伪代码):

from("quarz...")
to("sql...")
pollEnrich("ftp...")
...

答案 4 :(得分:0)

Use Camel endpoint with spring spel expression.

Set up a Camel endpoint in the context so it can be accessed from any bean:

        <camelContext id="camel" xmlns="http://camel.apache.org/schema/spring">
            <endpoint id="inventoryQueue" uri="#{config.jms.inventoryQueueFromUri}"/>
        </camelContext>

Now you can reference the inventoryQueue endpoint within the `@Consume` annotation as follows:
        @org.apache.camel.Consume(ref = "inventoryQueue")
        public void updateInventory(Inventory inventory) {
            // update
        }

    Or:
    <route>
        <from ref="inventoryQueue"/>
        <to uri="jms:incomingOrders"/>
    </route>