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!