背景
挂载文件夹方案各样的不爽
项目需要监听文件夹的变化,将文件内容以Message方式推送出去,但需监听的文件与服务运行不在同一台机器上,当时临时解决方案是将远程文件夹(Windows)通过SMB挂载到服务所在的机器(Linux)上, 但网络的不稳定以及远程文件夹各样的问题,让人不爽,于是各样的解决方案,Apache Camel似乎不错。
Why Blueprint?
不想让ava代码以独立的进程跑,需设置各样的监听、启动、停止脚本,让程序运行在Karaf是不错的选择,而使用Blueprint各样的优势(如无需编译,直接了当),值得一试
以下说明基于Camel 2.17.3, Camel-extra 2.15.0, Talend ESB 6.3.0/Karaf 4.0.7
Sample源码:
<?xml version="1.0" encoding="UTF-8"?>
<!--
Starter Blueprint Camel Definition TrialSamba
-->
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:camel="http://camel.apache.org/schema/blueprint"
xmlns:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.0.0"
xsi:schemaLocation="
http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd
http://camel.apache.org/schema/blueprint http://camel.apache.org/schema/blueprint/camel-blueprint.xsd">
<!-- Basic Bean Definitions-->
<bean id="fileStore" class="org.apache.camel.processor.idempotent.FileIdempotentRepository">
<!-- the filename for the store -->
<property name="fileStore" value="/tmp/smb/.filestore.dat"/>
<!-- the max filesize in bytes for the file. Camel will trunk and flush the cache
if the file gets bigger -->
<property name="maxFileStoreSize" value="512000"/>
<!-- the number of elements in our store -->
<property name="cacheSize" value="250"/>
</bean>
<bean id="smb" class="org.apacheextras.camel.component.jcifs.SmbComponent"/>
<!-- Osgi Service Related -->
<!--
Exposing Services :
...
References to Services :
<reference id="referenceId" availability="optional" interface="foo.bar.IBaz"/>
-->
<camelContext trace="false" xmlns="http://camel.apache.org/schema/blueprint">
<camel:route>
<camel:from uri="smb://domainName;username@IP/ShareFoldername/?password=yourpasswordhere&useFixedDelay=true&delay=10000&runLoggingLevel=debug&noop=true&idempotentRepository=#fileStore&antInclude=*.CMS"/>
<camel:log message="file: ${header.CamelFileName}"/>
<camel:to uri="file:/tmp/smb?tempFileName=processing.tmp"/>
</camel:route>
</camelContext>
</blueprint>
Route 设置说明:
Camel:from:
- SMB组件详细说明: http://camel.apache.org/jcifs.html
- useFixedDelay & delay属性: 网络不稳定,使用FixedDelay,用Poll方式比较保险,测试环境中,文件夹少了1000,暂时没发现性能问题
- noop:
因此项目中,被处理文件为只读,不能移动或者删除已处理文件,只能设置noop=true, 必须再对idempotent设置。若项目允许,设置move属性,甚至设置delete = true, 事情会变得简单
- idempotentRepository:默认设置为
MemoryMessageIdRepository, Bundle或者Karaf重启,并且没有移动或者删除已经处理文件,所有的文件都会重新处理,故此处,使用FileIdempotentRepository,如源码中的Bean#fileStore
- idempotentKey: 默认为文件名,根据需要可修改为:${file:name}-${file:size}
- include/exclude/antInclude/antExclude属性: 指定只处理特定文件,如Sample中,只处理*.CMS文件
camel:log
只是写Log, Log下处理的文件名
camel:to
- 源码中,只是写到本地文件,防止一些文件没写,就被其他处理,加入了tempFileName设置,写入文件时先被写为临时文件,写入完成后,再重命名为原文件名。
- 可根据需求接入其他Camel组件,比如可直接将文件内容发JMS Topic
SMB组件注册
不同于独立的Java App,需要为Blueprint注册SMB的组件类,加入Bean
<bean id="smb" class="org.apacheextras.camel.component.jcifs.SmbComponent"/>
Karaf运行
运行环境说明,Karaf使用 Talend ESB 6.3 自带的运行环境, 版本4.0.7
Samba不是Camel标准组件,必须额外安装, 在karaf中,手动增加repo, 在karaf下运行:
feature:repo-add mvn:org.apache-extras.camel-extra.karaf/camel-extra/2.15.0/xml/features
只找到了这个2.15.0版本, 并且发现若Camel > 2.18.0, 与camel-extra 2.15.0不兼容
安装组件
feature:install camel-jcifs
安装成功后,将Blueprint的XML文件放入deploy目录下即可,可以使用Bundle:list可以看到其运行状态