Jakarta Messaging - antes conhecida apenas como Java Message Service - (JMS) é a API que especifica como aplicações Java Enterprise enviam e recebem mensagens através de um Message Oriented Middleware (MOM). MOMs são um componente essencial para integração de operações entre sistemas corporativos diferentes.
Mensagens
O conceito de mensagem possui uma definição bastante ampla na computação. No contexto do JMS, mensagens são requisições assincronas ou eventos que são produzidos ou consumidos pelas aplicações. Essas mensagens geralmente contêm informações vitais necessárias para a coordenação entres os diferentes sistemas.
Arquitetura do JMS
Em um alto nível, a arquitetura do JMS consiste nos seguintes componentes:
- Provider: JMS é apenas uma API, então ela precisa de uma implementação que efetivamente direcione as mensagens, ou seja, o provider, também conhecido como message broker
- Client: a aplicação que produz ou consome mensagens atraves de algum provider
- Messages: os objetos que os clientes enviam ou recebem dos providers
- Administered Objects: objetos disponibilizados pelos brokers ao cliente (conexão e destino)
- Point to Point (P2P): 1 mensagem destinada a um único consumidor
- Publish-subscribe (pub-sub): 1 mensagem para N consumidores
modelo P2P |
modelo pub-sub |
Hello JMS
- através de um timer, envia uma mensagem para uma fila chamada HelloQueue a cada 3 segundos
- um tópico chamado PurchaseTopic que é observado pelo Operador de Cartão de Crédito e pelo Departamento Financeiro, ou seja, toda vez que uma operação de cartão de crédito chega nesse Tópico, as respectivas áreas são notificadas.
Enviando Mensagens para jms/HelloQueue
@Stateless
@LocalBean
public class TimedQueueProducer {
@Inject
private JMSContext jmsContext;
@Resource(lookup = "jms/HelloQueue")
private Queue queue;
@Schedule(hour = "*", minute = "*", second = "*/3", info = "Every 3 seconds", timezone = "UTC", persistent = false)
public void sendToQueue() {
TextMessage textMessage = jmsContext.createTextMessage("New Text Message");
JMSProducer producer = jmsContext.createProducer();
producer.send(queue, textMessage);
}
}
@MessageDriven(activationConfig = {
@ActivationConfigProperty(propertyName = "destinationLookup", propertyValue = "jms/HelloQueue")
})
public class QueueReceiver implements MessageListener {
private final static Logger LOG = Logger.getLogger(QueueReceiver.class.getName());
@Override
public void onMessage(Message message) {
TextMessage textMessage = (TextMessage) message;
try {
LOG.info(">>> received: " + textMessage.getText());
}
catch (JMSException e) {
e.printStackTrace();
}
}
}
Enviando Mensagens para jms/PurchaseTopic
@WebServlet(urlPatterns = "/hello")
public class ViewServelt extends HttpServlet {
@EJB
private TopicProducerService topicProducer;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String cvv = req.getParameter("cvv");
String number = req.getParameter("number");
topicProducer.sendMessage(new CreditCard(cvv, number));
resp.getWriter().println("<h1<Credit Card sent to the card operator topic...</h<");
}
}
@Stateless
@LocalBean
public class TopicProducerService {
@Inject
private JMSContext context;
@Resource(lookup = "jms/PurchaseTopic")
private Topic helloTopic;
public void sendMessage(CreditCard creditCard) {
JMSProducer producer = context.createProducer();
producer.send(helloTopic, creditCard);
}
}
@MessageDriven(activationConfig = {
@ActivationConfigProperty(propertyName = "destinationLookup", propertyValue = "jms/PurchaseTopic")
})
public class CardOperator implements MessageListener {
private static final Logger LOG = Logger.getLogger(CardOperator.class.getName());
@Override
public void onMessage(Message message) {
try {
CreditCard cc = message.getBody(CreditCard.class);
LOG.info(String.format("Received cc: %s", cc ));
}
catch (JMSException e) {
e.printStackTrace();
}
}
}
@MessageDriven(activationConfig = {
@ActivationConfigProperty(propertyName = "destinationLookup", propertyValue = "jms/PurchaseTopic")
})
public class FinancialDepartament implements MessageListener {
private static final Logger LOG = Logger.getLogger(FinancialDepartament.class.getName());
@Override
public void onMessage(Message message) {
try {
CreditCard cc = message.getBody(CreditCard.class);
LOG.info(String.format("Received cc: %s", cc ));
}
catch (JMSException e) {
e.printStackTrace();
}
}
}