我目前正在尝试优先处理通过复杂应用程序的消息(JMS)。
在我最关心的部分中,用户将消息插入到DB中的表中,如表INPUT
,列DESTINATION
,PRIORITY
,MESSAGE
。优先级列不是强制性的,其他都是强制性的。
然后,应用程序从该表中的条目获取信息,并使用JMSPriority = PRIORITY
头创建JMS。 Body填充了BODY列,然后JMS被发送到DESTINATION
中指定的队列。
代码链接:
//pull requests from database and set headers
from(RouteConstants.READ_REQUESTS_FROM_DATABASE) //this is a route formed by SQL
.transacted("PROPAGATION_REQUIRED_JBOSS")
.process(setHeaderProperties)
.to("direct:jms");
//send JMS to destination
from("direct:jms").setBody(simple("${property.MESSAGE}"))
.convertBodyTo(String.class).recipientList(
simple("jms:queue:${property.DESTINATION}?
exchangePattern=InOnly&jmsMessageType=Text&preserveMessageQos=true
&disableReplyTo=true"));
public class SetHeaderProperties implements Processor {
public void process(Exchange exchange) throws Exception {
LinkedCaseInsensitiveMap body = (LinkedCaseInsensitiveMap) exchange.getIn().getBody();
exchange.setProperty("MESSAGE", body.get("MESSAGE").toString());
exchange.setProperty("DESTINATION", body.get("DESTINATION").toString());
Long priority = getPriorityQuery(); //DAO method that returns value of PRIORITY or null if empty
if(priority != null) exchange.setProperty("PRIORITY", priority);
}
//Receive the JMS. Consider this point to be the same that the message was sent to in the second snippet
from("jms:queue:input-msgs").
log(LoggingLevel.DEBUG, CAMEL_LOGGER_NAME, "Received JMSPriority: ${header.JMSPriority}"). //This getter is problematic, see below snippets
process(generalMessageProcessor);
只要填充了PRIORITY
列,应用程序就会表现得很好。当PRIORITY
的值是null
时,getter总是返回4
。我理解,优先级4
是默认的,我可以正确处理消息,但我需要能够区分优先级4在数据库表中被设置为固定值并因此被请求,或者如果优先级根本没有设置,因此程序在以下处理器内的行为应该略有不同。
这是可能吗?我想避免更改数据库的DDL,而且我不能只在SetHeaderProperties
处理器中分叉程序,因为无论如何信息都会在GeneralMessageProcessor
中重写,并且setter处理器没有暴露所有必需的类和字段。
我想这个天真的答案是每当我需要检查优先级时再次调用DAO查询,但这会使数据库紧张,我想知道是否有更优雅的解决方案。
是的,值4
是默认的JMS优先级。因此,每条消息都有一个优先级,并且没有像null
优先级或根本没有优先级的事情。
但是,一个非常简单的解决方法是不会使数据库紧张,而是设置另一个消息头,如prioritySetByApplication
或您喜欢的任何名称。然后,您可以使用此标头来区分默认优先级和4
的“显式”优先级。