【问题标题】:Remove file before pollEnrich will end the strategy在 pollEnrich 结束策略之前删除文件
【发布时间】:2016-03-17 17:59:59
【问题描述】:

如果我在路由处理交换之前删除文件,我会得到异常: GenericFileOperationFailedException:无法重命名文件。 PollEnrich 尝试将文件从 someFolder 移动到 someFolder/.camel 的策略。

from("wmq:queue:someQueue")//Here we get the message with information about the file
...//some logic
.pollEnrich("file:someFolder?fileName=someFile")
...//some logic
.choice()
    .when(...)//Here we compare checksum from message with checksum of the file
    .process(new SomeClassProcess)//And if they are different file will be deleted from someFolder
    .otherwise()
    .to(someAnotherFolder)
.end();    

我正在尝试使用 .rollback("errorMessage")

onException(RollbackExchangeException.class)
.log(LoggingLevel.WARN, "SomeExcptn");

from("wmq:queue:someQueue")
    ...//some logic
    .pollEnrich("file:someFolder?fileName=someFile")
    ...//some logic
    .choice()
        .when(...)
        .process(new SomeClassProcess)//it will delete someFile from someFolder
        .rollback()
        .otherwise()
        .to(someAnotherFolder)
    .end();

但是现在我在应用程序的日志中发现了垃圾 - CamelExecutionException。 它有效,但你能帮助解决它吗?

附:我不知道在向 pollEnrich 提供 URI 之前是否需要删除文件,这就是我不使用 noop=true 的原因。在 .otherwise() 中,我需要将文件移动到 .camel。

感谢您的建议!

【问题讨论】:

    标签: java apache-camel


    【解决方案1】:

    我认为您不需要使用任何处理器来删除文件。你可以这样做:

    @Produce(uri = "direct:start")
    ProducerTemplate producerTemplate;
    
    @Autowired
    CamelContext camelContext;
    
    
    @Before
    public void before() {
        File outputDir = new File("transfer/outbox");
        File tmpDir = new File("transfer/tmp");
        for (File file : outputDir.listFiles())
            file.delete();
        for (File file : tmpDir.listFiles())
            file.delete();
    }
    
    @Override
    public RouteBuilder createRouteBuilder() {
    
        return new RouteBuilder() {
            @Override
            public void configure() throws Exception {
                from("file:transfer/inbox?noop=true")
                    .to("file:transfer/tmp")
                    .pollEnrich("file:transfer/tmp")
                    .choice()
                      .when(header(Exchange.FILE_NAME).isEqualTo("Message1.txt"))
                        .log(LoggingLevel.ERROR, "${header[CamelFileName]} This file is discarded")
                      .otherwise()
                        .to("file:transfer/outbox")
                    .end();
            }
        };
    }
    
    @Test
    public void smokeTest() throws Exception {
    
        NotifyBuilder notifyBuilder = new NotifyBuilder(context)
            .wereSentTo("file:transfer/outbox").whenDone(1)//Just to make the test enough time to complete
            .create();
    
        notifyBuilder.matches(5, TimeUnit.SECONDS);
    
        File inputDur = new File("transfer/inbox/");
        assertEquals(inputDur.listFiles().length, 2); // Message1.txt, Message2.txt (no .camel because ?noop=true)
    
        File outputDir = new File("transfer/outbox/");
        assertEquals(outputDir.listFiles().length, 1); // Message2.txt
    
        File tmpDir = new File("transfer/tmp/");
        assertEquals(tmpDir.listFiles().length, 1); // .camel
    
    
    }
    

    或者如果您不关心自己记录,更合适的方法是使用消息过滤器而不是基于内容的路由器:

    from("file:/path/to/your/file")
      .filter(somePredicate)
      .to("file:/where/you/want/it/to/move")
    

    当camel在飞行中的交换中使用它时删除一个文件不需要做,camel确实用另一个后缀为.camelLock的文件锁定文件,以防止其他路线消耗他,但是用处理器修改这个文件根本不安全。

    另外,我在您的示例中没有看到任何 ?noop=true 。如果你想删除或移动文件,使用 ?noop 是没有关系的。

    【讨论】:

    • 感谢您的回答!我已经在问题中添加了信息,我希望现在足以解释我试图实现的目标 =)在您的第一个示例文件中,将保留在 sourceFolder 中,但如果校验和验证失败,我需要将其删除。
    • 很抱歉坚持,但我发布的第一个示例会起作用,我已经用我所做的实际测试编辑了我的初始答案。
    猜你喜欢
    • 2012-07-05
    • 1970-01-01
    • 1970-01-01
    • 2019-05-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-03
    • 1970-01-01
    相关资源
    最近更新 更多