2014-03-06 71 views
2

我使用Apache Camel的文件組件遇到了一個奇怪的障礙。問題的要點是:我使用文件組件來加載目錄中的所有消息。然後我使用處理器對加載的文件執行一些操作。如果該過程成功,那麼我將該文件移至其他位置並刪除原始文件。如果這個過程失敗了,我會把信息留在原來的目錄中。代碼看起來像這樣:Apache Camel:在處理後將消息放回原始位置

from("fileLocation") 
    .process(new MessageProcessor()) 
    .choice() 
     .when(header("processPassed").isEqualTo(true)) 
      .to("file:newLocation") 
    .otherwise() 
     .to("fileLocation"); 

如果處理器通過,那麼一切都很好。但是,如果處理器發生故障,並且我試圖將消息返回到其原始位置,則不起作用。任何想法如何解決這個問題?

回答

2

我覺得有兩個問題影響你。首先,您不能將文件寫回原始位置,因爲駱駝正在處理它,其次有可能會重複處理同一文件。爲了解決這個問題,你可以使用兩個選項:

  1. preMove使用工作目錄
  2. idempotent防止同一文件進行第二次處理。

這裏是你的代碼稍加修改的版本,我認爲做什麼你需要File Endpoint文檔中獲得

from("file:fileLocation?idempotent=true&preMove=working") 
     .process(new MessageProcessor()) 
     .choice() 
      .when(header("processPassed").isEqualTo(true)) 
       .to("file:newLocation") 
     .otherwise() 
      .to("file:fileLocation"); 

更多細節。

1

閱讀documentation,您可以指定一個moveFailed選項。 將文件放置在某個錯誤文件夾中,而不是原始位置是件好事。然後你會知道在哪裏尋找壞文件。

更新: 由於需要將文件保留在原位,所以您需要設置一個持久的idempotent存儲庫。

這主要是從文檔複製,並將處理後的文件的絕對文件路徑保存到磁盤上的文件 - 以便它永遠不會再處理相同的(文件名)。

<!-- this is our file based idempotent store configured to use the .filestore.dat as file --> 
<bean id="fileStore" class="org.apache.camel.processor.idempotent.FileIdempotentRepository"> 
    <!-- the filename for the store --> 
    <property name="fileStore" value="some/folder/.idempotentrepo/filestore.dat"/> 
    <!-- the max filesize in bytes for the file.--> 
    <property name="maxFileStoreSize" value="<some size>"/> 
</bean> 

<camelContext xmlns="http://camel.apache.org/schema/spring"> 
    <route> 
     <from uri="file://some/folder/?idempotentRepository=#fileStore&amp;noop=true"/> 
     <to uri="mock:result"/> 
    </route> 
</camelContext> 
+0

無限循環=非常糟糕! – vikingsteve

+0

我同意將文件移動到錯誤文件夾,但將它們留作原始位置是必需的。 – David

+0

然後你需要建立一個[Idempotent Consumer](http://camel.apache.org/idempotent-consumer.html)。在文件端點上指定noop = true作爲on選項將執行此操作,但只適用於1000個條目或只要應用程序未重新啓動。答案是用持久冪等解決方案的例子更新的。 –