我想编写一个获取URI(可以是http,ftp,file,...)的Camel Route,然后获取数据并将其本地存储在文件中。
此URI-String可以是,例如:
基于此字符串,应使用正确的Camel组件来访问数据。像Java中的case / switch一样:
(1)接收URI(来自uri =" vm:incomingUri")
(2)选择"对"骆驼组件
switch(URI)
case HTTP: use Camel HTTP component
case FTP: use Camel FTP component
case JMS: use Camel JMS component
...
(3)使用"右"从该URI读取数据。骆驼组件
(4)在本地存储文件(到uri =" file:// ...)
实施例: 来自" vm:incomingUri"我读了一个字符串" ftp://localhost/example.txt"。现在最终需要发生的事情应该与此相同:
<route>
<from uri="ftp://localhost/example.txt"/>
<to uri="file://tmpDir/example.txt"/>
</route>
在Camel中看起来如何?
答案 0 :(得分:2)
我相信一个难点是,对于您提到的组件(HTTP,FTP,文件,JMS),您可能想要使用生产者或消费者:
制作人:
如果您使用的是Camel 2.16+,则可以使用新的"dynamic to"语法。它基本上与常规“to”相同,除了可以使用simple表达式(或者,optionnaly,另一种表达式)动态评估端点uri。或者,你可以使用content-enricher pattern的enrich
风格,它也支持从Camel 2.16开始的动态uris。
如果您使用的是较旧版本的Camel,或者您需要动态路由到多个端点(而不仅仅是一个端点),则可以使用recipient list模式。
这是一个例子。我们将通过调用端点来转换消息体;该端点的uri将在名为TargetUri
的标头中找到,并将针对每条消息动态评估。
// An instance of this class is registered as 'testbean' in the registry. Instead of
// sending to this bean, I could send to a FTP or HTTP endpoint, or whatever.
public class TestBean {
public String toUpperCase(final String str) {
return str.toUpperCase();
}
}
// This route sends a message to our example route for testing purpose. Of course, we
// could send any message as long as the 'TargetUri' header contains a valid endpoint uri
from("file:inbox?move=done&moveFailed=failed")
.setHeader("TargetUri").constant("bean:testbean?method=toUpperCase")
.setBody().constant("foo")
.to("direct:test");
// 1. The toD example :
from("direct:test")
.toD("${header.TargetUri}")
.to("log:myRoute");
// 2. The recipient list example :
from("direct:test")
.recipientList(header("TargetUri"))
.to("log:myRoute");
// 3. The enrich example :
from("direct:test")
.enrich().simple("${header.TargetUri}") // add an AggregationStrategy if necessary
.to("log:myRoute");
消费者:
使用Camel 2.16 +,您可以使用content-enricher pattern的pollEnrich
风格。
对于旧版本的Camel,您可以在处理器中使用ConsumerTemplate
。
// 4. The pollEnrich example (assuming the TargetUri header contains, e.g., a file
// or ftp uri) :
from("direct:test")
.pollEnrich().simple("${header.TargetUri}") // add an AggregationStrategy if necessary
.to("log:myRoute");
// 5. The ConsumerTemplate example (same assumption as above)
from("direct:test")
.process(new Processor() {
@Override
public void process(Exchange exchange) throws Exception {
String uri = exchange.getIn().getHeader("TargetUri", String.class);
ConsumerTemplate consumer = exchange.getContext().createConsumerTemplate();
final Object data = consumer.receiveBody(uri);
exchange.getIn().setBody(data);
}
})
.to("log:myRoute");
制作人或消费者?
可悲的是,我想不出任何真正优雅的解决方案来处理两者 - 我认为你必须根据uri和已知的组件路由到两个分支......这就是我可能做的事情(与Camel一起) 2.16 +),它不是很漂亮:
// This example only handles http and ftp endpoints properly
from("direct:test")
.choice()
.when(header("TargetUri").startsWith("http"))
.enrich().simple("${header.TargetUri}")
.endChoice()
.when(header("TargetUri").startsWith("ftp"))
.pollEnrich().simple("${header.TargetUri}")
.endChoice()
.end()
.to("log:myRoute");
答案 1 :(得分:1)
可以使用
<to uri="{{some.endpoint}}"/>
但你需要在属性中添加它。
<cm:property name="some.endpoint" value="SomeEndPoint"/>
您可以添加任何想要http,ftp,file,log,jms,vm等的端点。
SomeEndPoint的价值。
日志组件:日志:模拟
JMS组件: activemq:someQueueName
文件组件: file:// someFileShare
VMComponent: vm:toSomeRoute