我目前正在研究基于camel的ETL应用程序,该应用程序处理日期目录中显示的文件组。这些文件需要作为由文件名开头确定的组一起处理。只有在完成文件(“.flag”)写入目录后才能处理文件。我知道camel文件组件有一个done文件选项,但只允许你检索与done文件同名的文件。应用程序需要连续运行并在日期滚动时开始轮询第二天的目录。
目录结构示例:
/process-directory
/03-09-2011
/03-10-2011
/GROUPNAME_ID1_staticfilename.xml
/GROUPNAME_staticfilename2.xml
/GROUPNAME.flag
/GROUPNAME2_ID1_staticfilename.xml
/GROUPNAME2_staticfilename2.xml
/GROUPNAME2_staticfilename3.xml
/GROUPNAME2.flag
我有以下路线(名称混淆)启动处理:
@Override
public void configure() throws Exception
{
getContext().addEndpoint("processShare", createProcessShareEndpoint());
from("processShare")
.process(new InputFileRouter())
.choice()
.when()
.simple("${header.processorName} == '" + InputFileType.TYPE1 + "'")
.to("seda://type1?size=1")
.when()
.simple("${header.processorName} == '" + InputFileType.TYPE2 + "'")
.to("seda://type2?size=1")
.when()
.simple("${header.processorName} == '" + InputFileType.TYPE3 + "'")
.to("seda://type3?size=1")
.when()
.simple("${header.processorName} == '" + InputFileType.TYPE4 + "'")
.to("seda://type4?size=1")
.when()
.simple("${header.processorName} == '" + InputFileType.TYPE5 + "'")
.to("seda://type5?size=1")
.when()
.simple("${header.processorName} == '" + InputFileType.TYPE6 + "'")
.to("seda://type6?size=1")
.when()
.simple("${header.processorName} == '" + InputFileType.TYPE7 + "'")
.to("seda://type7?size=1")
.otherwise()
.log(LoggingLevel.FATAL, "Unknown file type encountered during processing! --> ${body}");
}
我的问题是如何配置文件端点。我目前正在尝试以编程方式配置端点而没有太多运气。到目前为止,我对camel的体验一直是使用Spring DSL而不是Java DSL。
我沿着尝试实例化FileEndpoint对象的路线,但每当路由构建时,我得到一个错误,说文件属性为null。我相信这是因为我应该创建一个FileComponent而不是端点。我没有使用uri创建端点,因为我无法使用uri在目录名称中指定动态日期。
private FileEndpoint createProcessShareEndpoint() throws ConfigurationException
{
FileEndpoint endpoint = new FileEndpoint();
//Custom directory "ready to process" implementation.
endpoint.setProcessStrategy(getContext().getRegistry().lookup(
"inputFileProcessStrategy", MyFileInputProcessStrategy.class));
try
{
//Controls the number of files returned per directory poll.
endpoint.setMaxMessagesPerPoll(Integer.parseInt(
PropertiesUtil.getProperty(
AdapterConstants.OUTDIR_MAXFILES, "1")));
}
catch (NumberFormatException e)
{
throw new ConfigurationException(String.format(
"Property %s is required to be an integer.",
AdapterConstants.OUTDIR_MAXFILES), e);
}
Map<String, Object> consumerPropertiesMap = new HashMap<String, Object>();
//Controls the delay between directory polls.
consumerPropertiesMap.put("delay", PropertiesUtil.getProperty(
AdapterConstants.OUTDIR_POLLING_MILLIS));
//Controls which files are included in directory polls.
//Regex that matches file extensions (eg. {SOME_FILE}.flag)
consumerPropertiesMap.put("include", "^.*(." + PropertiesUtil.getProperty(
AdapterConstants.OUTDIR_FLAGFILE_EXTENSION, "flag") + ")");
endpoint.setConsumerProperties(consumerPropertiesMap);
GenericFileConfiguration configuration = new GenericFileConfiguration();
//Controls the directory to be polled by the endpoint.
if(CommandLineOptions.getInstance().getInputDirectory() != null)
{
configuration.setDirectory(CommandLineOptions.getInstance().getInputDirectory());
}
else
{
SimpleDateFormat dateFormat = new SimpleDateFormat(PropertiesUtil.getProperty(AdapterConstants.OUTDIR_DATE_FORMAT, "MM-dd-yyyy"));
configuration.setDirectory(
PropertiesUtil.getProperty(AdapterConstants.OUTDIR_ROOT) + "\\" +
dateFormat.format(new Date()));
}
endpoint.setConfiguration(configuration);
return endpoint;
在这种情况下,实现GenericFileProcessingStrategy是正确的做法吗?如果是这样,有什么例子吗?我查看过骆驼文件单元测试,但没有看到任何跳出来的东西。
配置端点我做错了什么?我觉得清理这个烂摊子的答案与问题3有关。
在轮询和日期更改时,您是否可以将文件端点配置为滚动日期文件夹?
一如既往地感谢您的帮助。
答案 0 :(得分:2)
您可以使用processStrategy选项从端点uri引用自定义ProcessStrategy,例如file:xxxx?processStrategy = #myProcess。注意我们如何用#前缀值来表示它应该从注册表中查找它。所以在Spring XML中你只需添加一个 &lt; bean id =“myProcess”...&gt;标签
在Java中,从CamelContext API中获取端点可能更容易:
FileEndpoint file = context.getEndpoint("file:xxx?aaa=123&bbb=456", FileEndpoint.class);
这允许您预先配置端点。当然,之后您可以使用FileEndpoint上的API来设置其他配置。
答案 1 :(得分:0)
在Java中,这是如何使用GenericFileProcessingStrategy的方法:
@Component
public class CustomGenericFileProcessingStrategy<T> extends GenericFileProcessStrategySupport<T> {
public CustomFileReadyToCopyProcessStrategy() {
}
public boolean begin(GenericFileOperations<T> operations, GenericFileEndpoint<T> endpoint, Exchange exchange, GenericFile<T> file) throws Exception {
super.begin(operations, endpoint, exchange, file);
...
}
public void commit(GenericFileOperations<T> operations, GenericFileEndpoint<T> endpoint, Exchange exchange, GenericFile<T> file) throws Exception {
super.commit(operations, endpoint, exchange, file);
...
}
public void rollback(GenericFileOperations<T> operations, GenericFileEndpoint<T> endpoint, Exchange exchange, GenericFile<T> file) throws Exception {
super.rollback(operations, endpoint, exchange, file);
...
}
}
然后创建路由Builer类:
public class myRoutes() extends RouteBuilder {
private final static CustomGenericFileProcessingStrategy customGenericFileProcessingStrategy;
public myRoutes(CustomGenericFileProcessingStrategy
customGenericFileProcessingStrategy) {
this.customGenericFileProcessingStrategy = customGenericFileProcessingStrategy ; }
@Override public void configure() throws Exception {
FileEndpoint fileEndPoint= camelContext.getEndpoint("file://mySourceDirectory");
fileEndPoint.setProcessStrategy(myCustomGenericFileProcessingStrategy );
from(fileEndPoint).setBody(...)process(...).toD(...);
...
}