jms - Grails and ActiveMQ: How to manage connections for DefaultMessageListenerContainer -


i'm looking alternative plugin approach (jms and/or camel routing plugin) consuming activemq grails. far good, i'm not able find solutions managing connection.

here's config/spring/resources.groovy:

import org.springframework.jms.connection.singleconnectionfactory import org.apache.activemq.activemqconnectionfactory import org.springframework.jms.listener.adapter.messagelisteneradapter import org.springframework.jms.listener.defaultmessagelistenercontainer  beans = {     jmsconnectionfactory(singleconnectionfactory) {         targetconnectionfactory = { activemqconnectionfactory cf ->             brokerurl = "tcp://localhost:61616"         }     }      jmsmessagelistener(messagelisteneradapter, ref("myservice")) {         defaultlistenermethod = "onincomingmessage"     }      jmscontainer(defaultmessagelistenercontainer) {         connectionfactory = jmsconnectionfactory         destinationname = "statussavedtopic"         messagelistener = jmsmessagelistener         autostartup = true          // tells magic sauce activemq topic         pubsubdomain = true     } } 

if set autostartup true, works fine run-app until save service, causing recompile. when happen, connection dropped (confirmed checking activemq web console), , no more messages received (obviously).

are there ways of ensuring jmscontainer stays alive, other not doing hand , using jms or routing plugins?

i'm answering myself because found solution.

the solution have embedded activemq broker in-process. post messages embedded broker, , don't have test availability or handle reconnects, obvious reasons - it's right there, in process.

activemq has way of connecting brokers messages in 1 delivered next, , activemq handles connection stuff automatically. both initial connection if broker down on app startup, or reconnecting if broker goes down in flight.

you're free choose storage embedded broker too. if persist messages disk, activemq take care of posting messages central broker if app goes down after message queued in embedded broker before activemq managed deliver central broker.

here's bean code in grails-app/conf/spring setting app up. i'm bit of spring noob, i'm sure there better ways. using methodinvokingfactorybean made easy not fancy initialization spring itself, helped me show on road.

activemqlocalmessagedeliveryconnection(org.springframework.beans.factory.config.methodinvokingfactorybean) {     targetclass = "com.myapp.activemqlocalbrokerhelper"     targetmethod = "createconnection"     arguments = [ref("grailsapplication")] }  activemqlocalmessagedeliveryproducersession(org.springframework.beans.factory.config.methodinvokingfactorybean) {     targetclass = "com.myapp.activemqlocalbrokerhelper"     targetmethod = "createproducersession"     arguments = [ref("activemqlocalmessagedeliveryconnection")] }  activemqlocalmessagedeliveryproducer(org.springframework.beans.factory.config.methodinvokingfactorybean) { bean ->     targetclass = "com.myapp.activemqlocalbrokerhelper"     targetmethod = "createproducer"     arguments = [ref("grailsapplication"), ref("activemqlocalmessagedeliveryproducersession")] } 

here's code activemqlocalbrokerhelper.

package com.myapp import java.io.file import org.apache.activemq.command.activemqdestination  class activemqlocalbrokerhelper {     static javax.jms.connection createconnection(grailsapplication) {         // http://activemq.apache.org/how-do-i-embed-a-broker-inside-a-connection.html         def localbrokername = "localmessagedelivery"          def broker = new org.apache.activemq.broker.brokerservice()         broker.setpersistent(false)         broker.setbrokername(localbrokername)         broker.start()          def connfactory = new org.apache.activemq.activemqconnectionfactory(broker.getvmconnectoruri());         def conn = connfactory.createconnection();         conn.start()          return conn     }      static javax.jms.session createproducersession(conn) {         def session = conn.createsession(true, javax.jms.session.auto_acknowledge);         return session     }      static javax.jms.messageproducer createproducer(grailsapplication, session) {         def destination  = session.createqueue("messagedelivery")         def producer = session.createproducer(destination)         producer.setdeliverymode(javax.jms.deliverymode.non_persistent)         return producer     } } 

that's need embedded activemq broker. particular 1 not persistent, , transactional. you're free use activemq java api whatever here, of course. enqueue , consume messages, use normal activemq apis. example:

def activemqlocalmessagedeliveryproducer // inject producer def activemqlocalmessagedeliveryproducersession // , session  void enqueue(string messagetext) {     def message = session.createtextmessage(messagetext)     producer.send(message)     session.commit() } 

for consuming:

def activemqlocalmessagedeliveryconnection // inject connection  void consume() {     def activemqsession = activemqlocalmessagedeliveryconnection.createsession(true, session.client_acknowledge);     def destination = activemqsession.createqueue("myqueuename")     def consumer = activemqsession.createconsumer(destination)     while (true) {         def message = consumer.receive()         // message     } } 

Comments

Popular posts from this blog

linux - xterm copying to CLIPBOARD using copy-selection causes automatic updating of CLIPBOARD upon mouse selection -

qt - Errors in generated MOC files for QT5 from cmake -