在splitter tariterator期间,ftp使用者流下载seda队列失败

时间:2017-10-24 22:51:05

标签: apache-camel camel-ftp

首先介绍一下我的要求:

  • 从多个动态定义的读取中下载大型tar.gz文件 只有ftp / sftp网站。
  • 根据.tar.gz处理文件 条目名称的扩展名。
  • 使用Camel 2.19.3

我的解决方案是使用download = false定义新路由,以仅获取未处理文件的列表。示例路线是:

from("ftp://user@localhost/path?download=false&inProgressRepository=#inProgressRepo&idempotentRepository=#idemRepo&noop=true&readLock=changed&readLockMarkerFile=false&autoCreate=false&stepwise=false").to("seda:download?size=3&concurrentConsumers=3&blockWhenFull=true&purgeWhenStopping=true")

将文件名发送到使用streamDownload下载文件的seda队列,并将RemoteFile发送到定义为的处理路由器:

from("seda:download?size=3&concurrentConsumers=3&blockWhenFull=true&purgeWhenStopping=true")
.process({
    String fileName = exchange.getIn().getHeader(Exchange.FILE_NAME_ONLY, String.class);
    CamelContext context = exchange.getContext();
    ConsumerTemplate downloadConsumer = context.createConsumerTemplate();
    Producer unpackProducer = context.getRoute("unpack").getEndpoint().createProducer();
    Map<String,Object> parms = new HashMap<>();
    parms.put("fileName", fileName);
    parms.put("runLoggingLevel", "INFO");
    parms.put("consumer.bridgeErrorHandler", "true");
    parms.put("idempotentRepository", "#idemRepo");
    parms.put("noop", "true");
    parms.put("readLock", "changed");
    parms.put("readLockLoggingLevel", "INFO");
    parms.put("readLockMarkerFile", "false");
    parms.put("initialDelay", "0");
    parms.put("autoCreate", "false");
    parms.put("maximumReconnectAttempts", "0");
    parms.put("streamDownload", "true");
    parms.put("stepwise", "false");
    parms.put("throwExceptionOnConnectFailed", "true");
    parms.put("useList", "false");
    downloadConsumer.start();
    Exchange downloadExchange = downloadConsumer.receive(URISupport.normalizeUri(URISupport.appendParametersToURI("ftp://user@localhost/path", parms));
    unpackProducer.process(downloadExchange);
    if (downloadExchange.isFailed()) {
      LOGGER.error("unpack failed", downloadExchange.getException());
      exchange.setException(downloadExchange.getException());
    }
    downloadConsumer.doneUoW(downloadExchange);
    downloadConsumer.stop();
}

解压缩路由定义为:

from("direct:unpack").routeId("unpack")
.convertBodyTo(InputStream.class, null)
  .split(new TarSplitter()).streaming()
    .choice()
      .when(header(FILE_NAME).regex(XML_FILTER))
        .unmarshal().jacksonxml(POJO.class)
        .endChoice()
      .when(header(FILE_NAME).regex(XML2_FILTER))
        .unmarshal().jacksonxml(POJO2.class)
        .endChoice()
      .end()
    .end()
  .to("file://...")

首先,这是支持并发ftp消费者的好方法吗?我看到在同一个线程上创建并处理了新的FTPClient实例。有更好的解决方案吗?

其次,对于seda队列,处理流的是随机tar错误。如果使用direct而不是seda,那么只处理单个文件,则不会发生错误。这似乎指向并发问题。我错过了一些明显的东西吗?

提前感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

我的错误,需要添加binary = true。