我在Scala中设置了一个简单的Apache Camel Route,如下所示:
import org.apache.camel.builder.RouteBuilder
import akka.actor.ActorRef
import akka.camel._
class SimpleRouteBuilder(val responder: ActorRef) extends RouteBuilder {
def configure {
from("file:C:\\datafiles\\input?noop=true&readLock=changed").to(responder)
}
}
我的问题是如何为新文件进行仅扫描?现在,它为目录中的每个文件发送一条消息。我希望以这样的方式让它只在我的驼峰应用程序启动后为创建的文件发送消息。
干杯!
更新:
好的,我找到了解决方案...... 实现一个时间戳actor,其唯一目的是检查(文件创建时间>应用程序开始时间)并将文件消息转发给循环路由器。
现在的路线是:
from(s"file:$directoryName?noop=true&readLock=changed&delay=$delay&recursive=true&include=$include").
convertBodyTo(classOf[java.io.File]).to(timestampActor)
时间戳演员的代码约为:
object TimestampActor {
def apply(timeMillis0: Long): Props = Props(new TimestampActor(timeMillis0))
}
// timeMillis0 is the time when the application has started
class TimestampActor(timeMillis0: Long ) extends Actor {
val messageRouterActor: ActorRef = context.system.actorFor(s"akka://${Constants.ActorSystemName}/user/${Constants.MessageRouterActorName}")
val logger: Logger = LoggerFactory.getLogger(classOf[TimestampActor])
def receive = {
case camelMessage: CamelMessage => {
// Need to unbox
self ! camelMessage.body.asInstanceOf[java.io.File]
}
case file: File => {
try {
val attrs: BasicFileAttributes = Files.readAttributes(file.toPath, classOf[BasicFileAttributes])
if (attrs.creationTime().toMillis >= timeMillis0) {
// Forward the message to the Round Robin message router
messageRouterActor ! file
}
}
catch {
case ioe:IOException => {
logger.error(s"Failed to get creation time for file ${file.getCanonicalPath}", ioe)
// Retry in 20 minutes
import context.dispatcher
context.system.scheduler.scheduleOnce(Duration.create(20, TimeUnit.MINUTES), self, file)
}
}
}
}
}
答案 0 :(得分:3)
您需要使用Apache Camel File Component的idempotent
选项。它将记住已处理的文件,并仅使用新文件。默认情况下,它会记住1000个条目,密钥将是文件的绝对路径,但您可以将其更改为您需要的内容。它会是这样的:
from("file:C:\\datafiles\\input?noop=true&readLock=changed&idempotent=true").to(responder)
此外,您可以使用不同类型的Idempotent存储库来执行更多花哨的工作。
答案 1 :(得分:0)
如果您担心丢失原始文件,我建议您使用多播。这样您就可以将文件的副本发送到备份文件夹。
from("file:C:\\datafiles\\input").multicast().to("backuplocation", "responder");
默认情况下,camel将处理放置在输入文件夹中的任何文件