Spring Integration入站网关在队列为空时触发事件 [英] Spring integration inbound-gateway Fire an event when queue is empty

查看:116
本文介绍了Spring Integration入站网关在队列为空时触发事件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是新手,但是我会尽量保持警惕。

I'm a newbie around but I'll try to be consice.


{INPUT QUEUE}->[INBOUND-GATEWAY-1]-->[ROUTER]----------->(ACTIVATOR)<---------------
                                        \                                          /
                                         \-->{HOLD QUEUE}--->[INBOUND-GATEWAY-2]--^

我在这种情况下,我必须像前一种情况一样动态地改变流中的路由条件。来自队列的消息将发送到激活器进行处理,或者将另一个队列保留。在特定时间,我必须关闭INBOUND-GATEWAY-1,以便没有新消息进入流程,然后打开INBOUND-GATEWAY-2,以处理来自HOLD QUEUE的所有消息。一旦所有来自HOLD QUEUE的消息都被消耗掉,两个网关都必须像以前一样关闭/打开。这里的事情是我怎么知道什么时候HOLD QUEUE为空,所以我可以触发启动网关1的方法?

I'm having an scenario in which I have to dynamically change routing conditions in a flow like the former. Messages comming from a queue are sent to an activator to be processed, or another queue to be put on hold. At certain time, I have to close INBOUND-GATEWAY-1 so no new messages come into the flow, and open INBOUND-GATEWAY-2 to let all messages from HOLD QUEUE be processed. Once all messages from HOLD QUEUE were been consumed, both gateways must me closed/opened as they were before. The thing here is how could I know when HOLD QUEUE is empty so I could trigger a method in which gateway-1 could be started?

如果有人请,我将不胜感激可以帮助我。

I'd be grateful if somebody could help me.

预先感谢

推荐答案

经过一些调试和阅读,最后我找到了解决这个问题的方法。入站网关是JmsMessageDrivenEndpoint,它基于两个内部组件,即MessageListenerContainer和MessageListener。 MessageListenerContainer是负责调度MessageListener行为的负责人,因此,重写noMessageReceived和messageReceived并添加一些属性来控制所需的行为,我可以做到神奇。

After some debugging and reading, finally I came to a solution for this issue. An inbound-gateway is a JmsMessageDrivenEndpoint, based in two inner components, a MessageListenerContainer and a MessageListener. MessageListenerContainer is the one in charge at scheduling MessageListener behaviour so, overriding the noMessageReceived and messageReceived, and adding some attributes to control the desired behaviour, I could be able to do the "magic".

我的MessageListenerContainer实现就是这样。

My MessageListenerContainer implementation got like this.

public class ControlMessageListenerContainer extends DefaultMessageListenerContainer{

    private JmsMessageDrivenEndpoint mainInputGateway;

    private long timeOut;

    private long lastTimeReceived;  

    public PassControlMessageListenerContainer() {
        this.setAutoStartup(false);
    }

    @Override
    public void start() throws JmsException {
        /*When the container is started the lastTimeReceived is set to actial time*/
        lastTimeReceived = (new Date()).getTime();
        super.start();
    }

    @Override
    protected void noMessageReceived(Object invoker, Session session) {
        long actualTime = (new Date()).getTime();

        if((actualTime - lastTimeReceived) >= timeOut 
                && mainInputGateway != null && !mainInputGateway.isRunning()){
            mainInputGateway.start();
        }       
        super.noMessageReceived(invoker, session);
    }

    @Override
    protected void messageReceived(Object invoker, Session session) {
        /*lastTimeReceived is set again to actual time at new message arrive*/
        lastTimeReceived = (new Date()).getTime();
        super.messageReceived(invoker, session);
    }
}

最后,spring bean配置如下所示:

And finally, the spring bean config get like this:

<bean id="listenerContainer" 
    class="org.merol.ControlMessageListenerContainer">
    <property name="mainInputGateway" ref="mainGateway" />
    <property name="destination" ref="onHoldQueue" />
    <property name="timeOut" value="10000"/>
    <property name="connectionFactory" ref="connectionFactory"/>
</bean>

<bean id="messageListener" 
    class="org.springframework.integration.jms.ChannelPublishingJmsMessageListener">
    <property name="requestChannel" ref="outputChannel" />
</bean>

<bean id="inboundGateway" 
    class="org.springframework.integration.jms.JmsMessageDrivenEndpoint">
    <constructor-arg name="listenerContainer" ref="listenerContainer" />
    <constructor-arg name="listener" ref="messageListener" />
</bean>

希望这对其他人会有所帮助。

Hope this could be helpful for someone else.

感谢@Nicholas提供的线索。

Thanks to @Nicholas for the clues.

这篇关于Spring Integration入站网关在队列为空时触发事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆