如何使用Apache Camel从队列浏览消息?

时间:2018-06-27 09:41:01

标签: apache-camel

我需要使用骆驼路线从活动的mq浏览消息,而不会消耗消息。

在确保原始队列保持完整的同时,将读取(仅浏览而不使用)JMS队列中的消息,并将其移动到数据库中。

public class CamelStarter {

   private static CamelContext camelContext;

            public static void main(String[] args) throws Exception {
                            camelContext = new DefaultCamelContext();
                            ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(ActiveMQConnectionFactory.DEFAULT_BROKER_URL);

                            camelContext.addComponent("jms",  JmsComponent.jmsComponent(connectionFactory));

                            camelContext.addRoutes(new RouteBuilder() {

                                            @Override
                                            public void configure() throws Exception {
                                                from("jms:queue:testQueue").to("browse:orderReceived") .to("jms:queue:testQueue1");
                                            }

                                            }
                            );

                            camelContext.start();

                            Thread.sleep(1000);

                             inspectReceivedOrders();

                            camelContext.stop();

            }

public static void inspectInceivedOrders(){

BrowsableEndpoint browse = camelContext.getEndpoint("browse:orderReceived", BrowsableEndpoint.class);
List<Exchange> exchanges = browse.getExchanges();
System.out.println("Browsing queue: "+ browse.getEndpointUri() + " size: " + exchanges.size());
for (Exchange exchange : exchanges) {
  String payload = exchange.getIn().getBody(String.class);
  String msgId = exchange.getIn().getHeader("JMSMessageID", String.class);
  System.out.println(msgId + "=" +payload);

}

2 个答案:

答案 0 :(得分:0)

Apache骆驼浏览组件正是为此目的而设计的。请查看here 中的文档。

由于您还没有提供任何其他信息,所以无法说更多。

假设您有一条这样的路线

from("activemq:somequeue).to("bean:someBean")  

from("activemq:somequeue).process(exchange -> {})  

要做的所有事情都将浏览端点放在这样的位置

from("activemq:somequeue).to("browse:someHandler").to("bean:someBean")   

然后编写这样的类

@Component
public class BrowseQueue {

  @Autowired
  CamelContext camelContext;

  public void inspect() {
    BrowsableEndpoint browse = camelContext.getEndpoint("browse:someHandler", BrowsableEndpoint.class);
    List<Exchange> exchanges = browse.getExchanges();


    for (Exchange exchange : exchanges) {
      ...... 
    }
  }

}

答案 1 :(得分:0)

据我所知,在骆驼中不可能读取(不消耗!)JMS消息:-( 我发现(在JEE应用程序中)的唯一解决方法是使用计时器定义启动EJB,持有QueueBrowser并将msg处理委托给Camel路由:

@Singleton
@Startup
public class MyQueueBrowser  {

    private TimerService timerService;

    @Resource(mappedName="java:/jms/queue/com.company.myqueue")
    private Queue sourceQueue;

    @Inject
    @JMSConnectionFactory("java:/ConnectionFactory")
    private JMSContext jmsContext;  

    @Inject
    @Uri("direct:readMessage")
    private ProducerTemplate camelEndpoint;


    @PostConstruct
    private void init() {       
        TimerConfig timerConfig = new TimerConfig(null, false);
        ScheduleExpression se = new ScheduleExpression().hour("*").minute("*/"+frequencyInMin);
        timerService.createCalendarTimer(se, timerConfig);
    }


    @Timeout
    public void scheduledExecution(Timer timer) throws Exception {      
        QueueBrowser browser = null;
        try {                       
            browser = jmsContext.createBrowser(sourceQueue);                                           
            Enumeration<Message> msgs = browser.getEnumeration();
            while ( msgs.hasMoreElements() ) { 
                Message jmsMsg = msgs.nextElement(); 
                // + here: read body and/or properties of jmsMsg                                            
                camelEndpoint.sendBodyAndHeader(body, myHeaderName, myHeaderValue);
            }                                                                               
        } catch (JMSRuntimeException jmsException) {
            ...
        } finally {        
            browser.close();
        }
    }


}