2

I'm fairly new to Spring JMS, and I've found lots of documentation and examples at the Spring site and elsewhere, but my use case doesn't seem to be described anywhere, or at least in a way I can understand. I hope you might be able to help.

I would like to create a publisher of a topic and several durable subscribers to that topic. I'm working on the first subscriber now, and it is intended to run hourly (on a timer) and drain the topic of messages and process them all at once (i.e. to send an email summarizing all messages).

I do not know how to configure this setup in Spring, although I feel like this should be easy. Advice would be tremendously helpful.

My plan, such as it is, was to have the timer invoke the "processBatch" method, which would call receiveAndConvert() in a loop until it timed out, building up its list of messages.

This doesn't seem to work, though, because the consumer isn't really subscribed to the topic. Certainly not before it's run, and potentially not afterward.

How can I configure this using Spring and/or direct ActiveMQ?

I'm not sure where I ended up with my XML is a useful place for this discussion to start, but I'll provide it in case it is helpful:

<beans>
    <!-- some unrelated beans -->

    <!-- my Active MQ connection factory -->
    <bean id="mqConnectionFactory" class="org.apache.activemq.pool.PooledConnectionFactory" destroy-method="stop">
        <property name="connectionFactory">
            <bean class="org.apache.activemq.ActiveMQConnectionFactory">
                <property name="brokerURL" value="vm://broker"/>
            </bean>
        </property>
    </bean>

    <!-- my topic -->
    <amq:topic id="completionsTopic" physicalName="completions.topic"/>

    <!-- my subscriber -->
    <bean id="emailer" class="com.j128.Emailer">
        <property name="jmsTemplate">
            <bean class="org.springframework.jms.core.JmsTemplate">
                <property name="connectionFactory" ref="mqConnectionFactory"/>
                <property name="defaultDestination" ref="completionsTopic"/>
                <property name="receiveTimeout" value="2000"/>
            </bean>
        </property>
    </bean>

    <!-- my scheduler and periodic call to the topic drainer -->
    <task:scheduler id="taskScheduler" pool-size="10"/>
    <task:scheduled-tasks>
        <!-- send emails hourly -->
        <task:scheduled ref="emailer" method="processBatch" cron="0 * * * *"/>
    </task:scheduled-tasks>

</beans>

But I'm certain I fundamentally have the wrong strategy and that there's a simple way to configure this.

Thank you for your assistance.

j128
  • 58
  • 1
  • 6

1 Answers1

0

Have a look at how-does-a-queue-compare-to-a-topic: "Only subscribers who had an active subscription at the time the broker receives the message will get a copy of the message."

And for a durable topic how-do-durable-queues-and-topics-work: "Durable topics however are different as they must logically persist an instance of each suitable message for every durable consumer - since each durable consumer gets their own copy of the message"

So with a non-durable topic, your plan wont work as the hourly job won't get any messages as it isn't running when the messages are published. If you set up a durable topic then it might work but it depends what you expect to happen when you say your subscriber will "drain the topic of messages". All it can do it read the messages published to it since it last run, it can't affect the messages going to other subscribers.

For a discussion around durable subscribers (I haven't used them on ActiveMQ) see this

Community
  • 1
  • 1
matt helliwell
  • 2,574
  • 16
  • 24