我在服务器启动时加载了以下静态路由。它侦听端口上的UDP消息,并将这些消息推送到下面路由中定义的seda队列。
从( “米娜:UDP:// hostipaddress:9998同步=假”).wireTap( “SEDA:sometag大小= 100安培; blockWhenFull =真安培; multipleConsumers =真”);
现在我可以拥有多个想要接收/订阅这些消息的客户端。他们还想动态选择他们需要的Feed。 每个客户端向服务器发送订阅请求(REST)(使用Spring-MVC,Jetty,Camel实现)。 一旦服务器收到请求,我就创建一个新的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");
部署此路由后,它将开始向client_ip_address:20001发送UDP消息(如上面的动态路由中所指定的那样。)
客户端可以向服务器发送不同的过滤器。
如果此服务器收到新过滤器,则执行以下操作 1.检查是否有路由运行(基于客户端IP和端口) 2.如果路线正在运行,它将停止该路线并使用旧过滤器删除此路线 3.然后它重新创建一条新路线,该路线仅与xpathfilter中的最后一条路线不同。
我的问题是第2步需要花费很多时间(停止并重启)
有没有办法解决这个问题? 基本上我想更改路由中的XPath表达式而不停止/迁移路由。
PS:我也在official Camel mailing list上发布了这个帖子。
答案 0 :(得分: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;
}
}