Announcement Announcement Module
Collapse
No announcement yet.
Dynamic Destinations Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Dynamic Destinations

    Hi,

    In my scenario I have to create destinations and consumers at runtime. Since I cant predict the list of destinations, they will be created using a well known naming convention. I am using an embedded ActiveMQ broker.

    As far as I can see, I cannot use MessageListenerContainer for dealing with message consumption, since it is always attached to a fixed destination.

    So I tried to extend DynamicDestinationResolver to deal with destination and consumer creation.


    Code:
    package br.com.segware.sigma.jms.resolver;
    
    import java.util.HashMap;
    
    import javax.jms.Destination;
    import javax.jms.JMSException;
    import javax.jms.MessageConsumer;
    import javax.jms.Session;
    
    import org.springframework.jms.support.destination.DynamicDestinationResolver;
    
    import br.com.segware.sigma.jms.listener.ProcessamentoEventosMessageListener;
    
    public class RecepcaoDestinationResolver extends DynamicDestinationResolver {
    
    	HashMap<String,Destination> filasRecepcao = new HashMap<String,Destination>();
    	@Override
    	public Destination resolveDestinationName(Session session,
    			String destinationName, boolean pubSubDomain) throws JMSException {
    		Destination destination = filasRecepcao.get(destinationName);
    		if(destination==null){
    			destination = session.createQueue(destinationName);
    			MessageConsumer consumer = session.createConsumer(destination);
    			consumer.setMessageListener(new ProcessamentoEventosMessageListener());	
    			filasRecepcao.put(destinationName,destination);
    		}
    		return destination;		
    	}
    	
    
    }
    Before sending the message, i set jmsTemplate destination resover:

    Code:
    package br.com.segware.sigma.service;
    
    import java.util.List;
    
    import javax.jms.ConnectionFactory;
    import javax.jms.Destination;
    import javax.jms.JMSException;
    import javax.jms.Message;
    import javax.jms.Session;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.jms.core.JmsTemplate;
    import org.springframework.jms.core.MessageCreator;
    import org.springframework.stereotype.Component;
    
    import br.com.segware.sigma.jms.resolver.RecepcaoDestinationResolver;
    import br.com.segware.sigma.pojo.EventoRecebido;
    import br.com.segware.sigma.service.iface.RecepcaoEventosService;
    
    @Component
    public class RecepcaoEventosServiceImpl implements RecepcaoEventosService{
    	@Autowired
    	private JmsTemplate jmsTemplate;	
    	
    	@Autowired
    	private Destination destination;
    	
    	@Autowired
    	RecepcaoDestinationResolver destinationResolver;
        
    	
        public void setConnectionFactory(ConnectionFactory cf) {
            this.jmsTemplate = new JmsTemplate();
            this.jmsTemplate.setConnectionFactory(cf);
        }
      
    
    
    	public JmsTemplate getJmsTemplate() {
    		return jmsTemplate;
    	}
    
    
    	public void setJmsTemplate(JmsTemplate jmsTemplate) {
    		this.jmsTemplate = jmsTemplate;
    	}
    	
    	public List<Long> receberEventos(List<EventoRecebido> listaEventos)
    			throws Exception {
    				
    		
    		jmsTemplate.setDestinationResolver(destinationResolver);
    
    		this.jmsTemplate.send("testQueueCreation", new MessageCreator() {
                public Message createMessage(Session session) throws JMSException {            	
                  Message m = session.createMessage();                           
                  return m;
                }
            });
    		
    		return null;
    	}
    	
    }
    Debugging the application, I can see that the resolveDestinationName method of DynamicDestinationResover is called, the destination and consumer are created, but the message is not sent.

    I am guessing that for some reason the connection.start method is not being called by jmsTemplate

    I've already search a solution to this problem but I was not able to find any.

    Any Ideas?
    Is it possible to achive what i want using spring JMS?

    Thanks in advance.

  • #2
    I think you can achieve that by simply invoking the jmsTemplate's method :

    public void send(String destinationName, MessageCreator messageCreator)

    The destination will be dynamically resolved using the destinationName string.
    So personally, I would move the "filasRecepcao" map to RecepcaoEventosServiceImpl class and remove the "private Destination destination" from this class
    Last edited by beaupral; May 22nd, 2011, 02:33 PM.

    Comment


    • #3
      Thanks for answering!
      I've been involved with other things in work, so thats why i took so long to reply your post.

      Well, unfortunately, the destination is resolved, but not created automatically. Thats why i have to use DynamicDestinationResolver, so i can have access to the jms Session and possibly create the queue.

      I am using CachingConnectionFactory, and than I found that calling createConnection from connectionFactory and than callig connection.start(), the messages are sent and consumed.
      I am closing conection at the end of process, so it can return to the pool.
      But I think its not a good design and i am having problems with memory usage and blocked threads (tomcat stops responding) when the number of created queues is to high (300).

      So, if anyone can help I would apreciated.
      Thanks in advance.

      Comment

      Working...
      X