terça-feira, 6 de maio de 2014

Tomcat + Spring + ActiveMQ Embedded Broker + Redelvery

Salve galera!

Não vou fazer um tutorial gigante de como configurar o ActiveMQ com Spring por que já existem vários por ai. Mas vou colocar as configurações necessárias para subir um Broker Embedded usando Spring num servidor Apache Tomcat trabalhando com Redelivery Messages.

Versões 

A versão current do ActiveMQ é 5.9. Não consegui fazer funcionar na última versão no Spring, então tive que usar a versão 3.1.1.RELEASE. A versão do Tomcat usada foi 7.0.41.

Maven Dependências 

Nessa relação deve ter coisas desnecessárias, mas como uso bastante coisa do Spring nesse projeto que fiz vou colocar a lista completa que já contempla MVC, JPA, Hibernate e tudo mais.

 3.1.1.RELEASE
 1.6
 2.5.0
 1.6.1


 
        

        
            javax
            javaee-api
            6.0
            provided
              

        

        
            javax.servlet.jsp
            jsp-api
            2.1
            provided
        

        
            javax.servlet
            jstl
            1.2
                                     

        

        
            org.springframework
            spring-context
            ${spring.version}           
        

        
            org.springframework
            spring-context-support
            ${spring.version}           
        

        
            org.springframework
            spring-core
            ${spring.version}                     
        

        
            org.springframework
            spring-web
            ${spring.version}
        

        
            org.springframework
            spring-beans
            ${spring.version}
        

        
            org.springframework
            spring-oxm
            ${spring.version}
        

        
            org.springframework
            spring-orm
            ${spring.version}
        

        
            org.springframework
            spring-webmvc
            ${spring.version}
          

        
            org.springframework
            spring-aspects
            ${spring.version}
                    

        
            org.springframework
            spring-tx
            ${spring.version}
             

        
            org.springframework.security
            spring-security-config
            ${spring.version}
        

        
            org.springframework.security
            spring-security-web
            ${spring.version}
          

        
            org.springframework.security
            spring-security-taglibs
            ${spring.version}
                     

        
            org.springframework.security
            spring-security-core
            ${spring.version}
          

        
            org.springframework
            spring-jms
            ${spring.version}
                     

        
            javax.servlet
            com.springsource.javax.servlet
            ${servlet-api.version}
            provided
        

        
            com.thoughtworks.xstream
            xstream
            1.3.1
        

             

        
            junit
            junit
            4.7
            test
        
     
        

        
            org.hibernate
            hibernate-entitymanager
            4.2.0.Final
        

        
            org.hibernate
            hibernate-validator
            4.2.0.Final           
         

        
            org.hibernate
            hibernate-c3p0
            4.2.0.Final
             

        
            org.hibernate
            hibernate-ehcache
            4.2.0.Final
               

        
            c3p0
            c3p0
            0.9.1.2
        
                                   
        
            net.sf.ehcache
            ehcache-core
            2.5.0
        
                            
        

        
            javassist
            javassist
            3.4.GA
               

        

        
            log4j
            log4j
            1.2.17           
        

        
            org.slf4j
            slf4j-api
            ${slf4j.version}           
        

        
            org.slf4j
            jcl-over-slf4j
            ${slf4j.version}           
        

        
            org.slf4j
            slf4j-log4j12
            ${slf4j.version}           
                             

        
            commons-io
            commons-io
            1.4
               
     
        
            cglib
            cglib
            2.2
                            

        
            org.apache.xbean
            xbean-spring
            3.6           
        
       
        
            org.apache.activemq
            activemq-all
            5.9.1           
                     

        
            org.apache.activemq
            activemq-pool
            5.9.1           
          

        
            javax.jms
            com.springsource.javax.jms
            1.1.0
                                                                                                                                                                  
                        
    
Spring Configuration Embedded Broker 

Aqui vou mostrar como configurar o Embedded Broker dentro do arquivo de configurações do Spring, sem precisar declarar nada no server.xml do Tomcat.

http://activemq.apache.org/how-do-i-embed-a-broker-inside-a-connection.html

No applicationContext.xml podemos fazer todas as configurações do Broker:


 

        
            
                   
              

                   
            
        

       

        
            
                
                    
                

                
                    
                

                
                    
                
                                 

           

       

                           
             
           

                                                                

    

 
                           
                   
                   
                   
   

                    

    
                   
        
  



Ou podemos externalizar as configurações e apontar o arquivo usando o brokerConfig:


 

                       

               

               

               

       

                    

    

               

        

    

 

Configuração Topic
    

        

    
Configuração MessageListener
 

     

         

         

         

         

         

                  

             

     
Código do Cnsumidor:
public class TopicConsumer extends SessionAwareMessageListener{

   public void onMessage(Message message, Session session) throws JMSException {

            try {

                //process message

                message.acknowledge(); // consume message

            } catch (Exception e) {               

                session.recover();

                throw new RuntimeException(e);

            }      

   }

}

Código do produtor:
@Service
public class TopicProducer  {

    @Resource(name = "jmsConnectionFactory")

    private ConnectionFactory connectionFactory;

    @Resource(name = "jmsTopicProducerConsumer")

    private Destination destination;

    private Connection connection;

    private Session session;

  public void produce(){

             connection = connectionFactory.createConnection();

            connection.start();

            session = connection.createSession(true, Session.CLIENT_ACKNOWLEDGE);                        TopicSession session

                            = connection.value.createTopicSession(false, Session.CLIENT_ACKNOWLEDGE);

                    TopicPublisher publisher = session.createPublisher((Topic) destination);

           TextMessage message = session.createTextMessage("Message Content");

           publisher.publish(message);

           connection.close();

 }

}

Redelivery Message 

Como podemos ver na configuração estamos criando um objeto redeliveryPolicy que define a política de reentrega das mensagens em caso de falha. Como não estamos trabalhando com mensagens transacionais, segundo a documentação do ActiveMQ, temos que usar o acknowledgeMode = Session.CLIENT_ACKNOWLEDGE. Trecho da documentação:

http://activemq.apache.org/message-redelivery-and-dlq-handling.html

Messages are redelivered to a client when any of the following occurs: 
  • A transacted session is used and rollback() is called. 
  • A transacted session is closed before commit is called. 
  •  A session is using CLIENT_ACKNOWLEDGE and Session.recover() is called. 

 Redelivery com Bridge 

Aqui um detalhe importante! Se estivermos consumindo as mensagens diretamente do Broker onde a mensagem é produzida não precisamos definir no Listener o acknowledgeMode como pode ver na configuração:
  
Mas caso estivermos usando uma Bridge, precisamos definir o tipo de recebimento no Listener para que a reentrega funcione.


Não tão simples mas também não tão complicado. É só prestar atenção nos detalhes que tudo funciona.

Até a próxima!

Nenhum comentário:

Postar um comentário