2012-07-29 32 views
1

我在服務器啓動時加載了以下靜態路由。它偵聽端口上的UDP消息,並將這些消息推送到下面路由中定義的seda隊列。在駱駝路由中創建動態過濾器(xpath)的選項

從( 「米娜:UDP:// hostipaddress:9998同步=假?」).wireTap( 「SEDA:sometag尺寸= 100 & blockWhenFull =真& multipleConsumers =真」);

現在我可以有多個客戶想要接收/訂閱這些消息。他們還想動態選擇他們需要的饋送。 每個客戶端都會向服務器發送訂閱請求(REST)(使用Spring-MVC,Jetty,Camel實現)。 一旦服務器收到請求創建一個新的駱駝路線,看起來像:

 from("seda:sometag?multipleConsumers=true") 
       .routeId(RouteIdCreator.createRouteId(toIP, toPort, "sometag")) 
       .filter() 
       .xpath(this.xpathFilter).unmarshal().jaxb("sometag").marshal() 
       .json().wireTap("mina:udp://client_ip_address:20001?sync=false"); 

一旦這條路被部署將開始UDP消息發送到client_ip_address:20001(如動態路由指定)

客戶端可以向服務器發送不同的過濾器。

在此情況下,服務器接收新的過濾器將執行下列操作 1.檢查是否存在運行路線(基於客戶端IP和端口) 2.如路線運行它停止該路線,並刪除該路由用舊的過濾器 3.然後它重新創建一個新的路由,它與xpathfilter中的最後一條路由不同。

我的問題是,第2步中需要大量的時間(停止和重新啓動)

是否有解決這個問題的方法嗎? 基本上我想改變路徑中的XPath表達式而不停止/遷移路由。

PS:我也在official Camel mailing list上發佈了這個。

回答

2

當您收到新的訂閱時,您可以嘗試將xpath過濾器存儲在數據庫中(基本上是一個簡單的表,其中ip和過濾器關聯)。然後,您可以從路由中的數據庫中讀取此過濾器,並將其用作過濾器。

from("seda:sometag?multipleConsumers=true") 
       .routeId(RouteIdCreator.createRouteId(toIP, toPort, "sometag")) 
       .setHeader("ip").constant(client_ip_adresse) 
       .filter().xpath(simple("${bean:xpathFilterComponent?methode=find}")) 
       .unmarshal().jaxb("sometag").marshal() 
       .json().wireTap("mina:udp://client_ip_address:20001?sync=false"); 

而且你的bean應該像

public class XpathFilterCompnent { 

     public void save(String ip, String filter){ 
     //store a filter for an ip in database, when a subscription is received 
     } 

     public void find(@Header("ip") String ip){ 
     String filter = ... //retreive filter from database 
     return filter; 
     } 
}