introdução a jms e message-driven bean

33
Introdução a JMS e Message-Driven Bean Comunicação Assíncrona Ricardo Cavalcanti [email protected] Jobson Ronan [email protected]

Upload: brad

Post on 16-Jan-2016

29 views

Category:

Documents


0 download

DESCRIPTION

Introdução a JMS e Message-Driven Bean. Comunicação Assíncrona. Ricardo Cavalcanti [email protected]. Jobson Ronan [email protected]. Por que usar um MDB?. Tipicamente devido a algumas limitações de RMI-IIOP - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Introdução a JMS e Message-Driven Bean

Introdução a JMS e Message-Driven Bean

Comunicação Assíncrona

Ricardo [email protected]

Jobson [email protected]

Page 2: Introdução a JMS e Message-Driven Bean

Por que usar um MDB?

Tipicamente devido a algumas limitações de RMI-IIOP Performance. Um cliente típico RMI-IIOP precisa

esperar enquanto o servidor está processando. Apenas quando o servidor completa o trabalho e o cliente recebe o resultado, este pode continuar seu processamento

Garantia. Quando um cliente RMI-IIOP invoca o servidor, este tem que restar rodando. Se o servidor ou a rede cair o cliente não pode efetuar a operação desejada

Page 3: Introdução a JMS e Message-Driven Bean

Por que usar um MDB?

Suporte para vários emissores e receptores. RMI-IIOP se limita a comunicação de um único cliente a um único servidor

Integração com outros sistemas MOM(Middleware Orientado a Mensagem).

Page 4: Introdução a JMS e Message-Driven Bean

Messaging

Mensagens são uma alternativa a invocação de métodos remotos.

A idéia é inserir uma camada entre o cliente e o servidor

Aplicação Aplicação

Invocação de método remoto

Messaging

Aplicação AplicaçãoMessage

Middleware

Page 5: Introdução a JMS e Message-Driven Bean

Messaging Vantagens

Processos não bloqueáveis Garantia de entrega Suporte a múltiplos emissores e

receptores

Page 6: Introdução a JMS e Message-Driven Bean

JMS – Java Message Service

JMS é um padrão para Messaging Tem como objetivo eliminar muitas

das desvantagem que MOMs encontraram com o passar dos anos

O Desenvolvedor aprende a usar a API de JMS e reusa seu código com diferentes implementações plugáveis de MOM (idéia similar APIs do J2EE, como JNDI e JDBC)

Page 7: Introdução a JMS e Message-Driven Bean

Domínios de Mensagens Publish/subscribe(pub/sub)

Análogo a assistir televisão. Pode haver muitos produtores de mensagens e muitos consumidores.

Produtor 1 Consumidor 1

Canal

Consumidor 2Produtor 2

Page 8: Introdução a JMS e Message-Driven Bean

Domínios de Mensagens Point-to-point(PTP)

Múltiplos produtores podem enviar mensagens para a fila mas cada mensagem é entregue a apenas um consumidor

Produtor 1

Consumidor 1Fila

Produtor 2

Page 9: Introdução a JMS e Message-Driven Bean

Usando a API JMS

Passos 1. Localizar o provedor JMS, instancia de

ConnectionFactory 2. Criar um conexão JMS 3. Criar uma Sessão JMS 4. Localizar o destino 5. Criar um JMS Provider ou um JMS

Consumer 6. Enviar ou Receber suas mensagens

Page 10: Introdução a JMS e Message-Driven Bean

Cliente

JNDI

Serviço de nomes

1. Obter o Driver JMS (ConnectionFactory)

4. Obter o destino JMS

2. Criar conexão

3. Criar sessão

5. Criar producer ou consumer

6. Enviar ou receber mensagens

JMS Connection Factory

JSM Connection

JMS Session

JSM Prosucer ou Consumer

Driver JMS do cliente

Servidor JMS

6. Enviar ou receber mensagens

Fila1

Fila2

Tópico1

Page 11: Introdução a JMS e Message-Driven Bean

Exemplo//..importspublic class Client {

public static void main (String[] args) throws Exception { Context ctxt = new InitialContext();

TopicConnectionFactory factory = (TopicConnectionFactory) ctxt.lookup("jms/TopicConnectionFactory");

TopicConnection connection = factory.createTopicConnection(); TopicSession session = connection.createTopicSession

(false, Session.AUTO_ACKNOWLEDGE);

Topic topic = (Topic) ctxt.lookup("jms/Topic");

TopicPublisher publisher = session.createPublisher(topic);

TextMessage msg = session.createTextMessage();

msg.setText("This is a test message.");

publisher.publish(msg); }}

Page 12: Introdução a JMS e Message-Driven Bean

Interfaces

INTERFACE PAI POINT-TO-POINT PUB/SUB

ConnectionFactory QueueConnectionFactory TopicConnectionFactory

Connection QueueConnection TopicConnection

Destination Queue Topic

Session QueueSession TopicSession

MessageProducer QueueSender TopicPublisher

MessageConsumer QueueReceiver, QueueBrowser

TopicSubscriber

Page 13: Introdução a JMS e Message-Driven Bean

Integração JMS-EJB

Motivação Possuir componentes Ejbs com

características como clientes “não-bloqueaveis” e comunicação n-ária

Page 14: Introdução a JMS e Message-Driven Bean

Integração JMS-EJB

Como implementar a integração?

Implementar objetos Java que recebem mensagens e realizam chamadas a componentes EJBs?

Reusar um tipo existente de componente EJB para receber Mensagens JMS?

Page 15: Introdução a JMS e Message-Driven Bean

Messsage-Driven Beans

O que são? Introduzido na especificação EJB 2.0 São componentes EJBs especiais capazes de

receber mensagens enviadas a filas e canais JMS

Invocados pelo Container dada a chegada de um mensagem ao destino que um MDB escuta

• Não se envia uma mensagem direto a um MDB(envia-se ao canal que o bean escuta)

• Proporcionando acoplamento fraco entre cliente e MDB (conhecimento do canal de comunicação)

Page 16: Introdução a JMS e Message-Driven Bean

Messsage-Driven Beans

Para efetuar a comunicação é necessário o uso de uma API específica, como JMS

Cliente Destino JMS

Instancias de Message-Driven

Beans

Pool de MDBs

Page 17: Introdução a JMS e Message-Driven Bean

Messsage-Driven Beans

Características Não possuem interface home, local home,

interface remota, nem interface local Possuem apenas um método que recebe

qualquer tipo de mensagem Não têm retorno, e também não lançam

exceções ao cliente São Stateless Podem ser ouvintes de uma fila, ou assinantes

durável ou não-durável de um canal(Topic)

Page 18: Introdução a JMS e Message-Driven Bean

Implementando MDBs

MDBs devem implementar duas interfaces javax.jms.MessageListener javax.ejb.MessageDrivenBean

Métodos de MessageDrivenBean e da especificação ejbRemove(): método da interface. Chamado pelo container

quando o message-driven bean está sendo removido do pool ejbCreate(): método definido na especificação (não está na

interface). É chamado quando um novo bean é criado pelo container

setMessageDrivenContext(MessageDrivenContext ctx): método da interface. Chamado antes do ejbCreate() quando o bean está sendo adicionado ao pool

Page 19: Introdução a JMS e Message-Driven Bean

Implementando MDBs

Método de MessageListener onMessage(Message m): chamado cada vez que uma

mensagem é enviada para o canal do bean (se o bean estiver ativado).

Page 20: Introdução a JMS e Message-Driven Bean

Implementando MDBspackage org.citi.pec.ejbs;//..imports/** * @ejb.bean name="ExecuterSQLMessage" * display-name="Name for Executer" * description="Description for Executer" * destination-type="javax.jms.Queue" * acknowledge-mode="Auto-acknowledge"* @jboss.destination-jndi-name name = "queue/MyQueueMDB" */public class ExecuterBean implements MessageDrivenBean, MessageListener { public void onMessage(Message message) { try { if (message instanceof TextMessage) { TextMessage text = (TextMessage) message; System.out.println(text.getText());

} } catch (JMSException e) {

throw new EJBException(e); } } public void setMessageDrivenContext(MessageDrivenContext ctx) throws EJBException {} public void ejbCreate() throws EJBException {} public void ejbRemove() throws EJBException {}}

Page 21: Introdução a JMS e Message-Driven Bean

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN“ "http://java.sun.com/dtd/ejb-jar_2_0.dtd">

<ejb-jar > <description><![CDATA[No Description.]]></description> <display-name>Generated by XDoclet</display-name>

<enterprise-beans> <message-driven > <description><![CDATA[Description for Executer]]></description> <display-name>Name for Executer</display-name> <ejb-name>ExecuterSQLMessage</ejb-name> <ejb-class>org.citi.pec.ejbs.ExecuterBean</ejb-class> <transaction-type>Container</transaction-type>

<acknowledge-mode>Auto-acknowledge</acknowledge-mode> <message-driven-destination> <destination-type>javax.jms.Queue</destination-type> </message-driven-destination>

</message-driven>

</ejb-jar>

Deployment Descriptors

...e se fosse Topic ???

Page 22: Introdução a JMS e Message-Driven Bean

Deployment Descriptors

Outras Tags <message-selector>

Usado para incluir um filtro SQL para cabeçalhos de mensagens. Apenas mensagens que combinarem com o filtro serão recebidas pelo bean. Exemplo:

<message-selector><![CDATA[Formato LIKE '%Imagem%‘ AND JMSExpiration > 0

AND Valor IS NOT NULL]]></message-selector>

Page 23: Introdução a JMS e Message-Driven Bean

Deployment Descriptors<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE jboss PUBLIC "-//JBoss//DTD JBOSS 3.2//EN“ "http://www.jboss.org/j2ee/dtd/jboss_3_2.dtd">

<jboss>

<enterprise-beans>

<message-driven> <ejb-name>ExecuterSQLMessage</ejb-name> <destination-jndi-name>queue/MyQueueMDB</destination-jndi-name> </message-driven>

</enterprise-beans>

<resource-managers> </resource-managers>

</jboss>

Page 24: Introdução a JMS e Message-Driven Bean

JBoss

...empacotar e fazer o deploy...

Warning no deploy: a fila referênciada (queue/MyQueueMDB)não existe, o JBoss criará uma nova fila temporária para o MDB

Page 25: Introdução a JMS e Message-Driven Bean

JBoss

Como a maioria das coisas no JBoss, JMS Topics e Queues são implementadas como MBeans

Para criar uma fila permanente no JBoss, basta adicionar uma declaração de um MBean no arquivo jbossmq-destinations-service.xml (diretório jms dentro do diretório deploy)

<!-- .... --><mbean code="org.jboss.mq.server.jmx.Queue“

name="jboss.mq.destination:service=Queue,name=MyQueueMDB">

<depends optional-attribute-name="DestinationManager">jboss.mq:service=DestinationManager

</depends></mbean><!-- .... -->

Page 26: Introdução a JMS e Message-Driven Bean

Implementando cliente Como um cliente JMS comum//..importspublic class MDBClient { public static void main(String[] args) throws Exception { Properties namingProperties = new Properties(); namingProperties.put(Context.INITIAL_CONTEXT_FACTORY,

"org.jnp.interfaces.NamingContextFactory"); namingProperties.put("java.naming.provider.url",

"jnp://localhost:1099"); namingProperties.put("java.naming.factory.url.pkgs",

"org.jboss.naming.client");

Context ctx = new InitialContext(namingProperties); QueueConnectionFactory cf = (QueueConnectionFactory)

ctx.lookup("XAConnectionFactory"); QueueConnection conn = cf.createQueueConnection(); QueueSession session = conn.createQueueSession(false,

Session.AUTO_ACKNOWLEDGE); Queue queue = (Queue) ctx.lookup("queue/MyQueueMDB"); QueueSender sender = session.createSender(queue); TextMessage message = session.createTextMessage(); message.setText("Hello World of Messaging!"); sender.send(message); }}

Page 27: Introdução a JMS e Message-Driven Bean

Exercício

Construa um MDB simples que recebe uma mensagem de texto e imprime seu conteúdo se a mensagem possuir no cabeçalho a informação “fonte : cliente”

Construa um cliente que envia uma Mensagem a fila na qual o MDB está escutando

Page 28: Introdução a JMS e Message-Driven Bean

...mas quem pode e deve ser um cliente de um bean: Servlets locais Beans locais Classes java remotas ...

Page 29: Introdução a JMS e Message-Driven Bean

Exercício (++)

“... How the pieces fit together?” Construa um Entity Bean CompraBean

com os segiuntes atributos: Código Cliente produtos (pode ser uma string contendo todos

os produtos) valor total status da compra (um booleano que indica se a

compra foi validada ou não)

Page 30: Introdução a JMS e Message-Driven Bean

Exercício (++)

Construa um MDB ValidadorBean que recebe uma mensagem contendo os dados de uma compra e simula uma verificação de perfil de compra. Em seguida ele altera o estado do CompraBean Correspondente para validado você pode usar um "Thread.sleep()"

para simular um processo demorado

Page 31: Introdução a JMS e Message-Driven Bean

Exercício (++)

Crie um ValueObject para o Bean Compra (CompraVO)

Construa um SessionBean stateless que contém o método efetuarCompra(CompraVO compra) que Cria um CompraBean equicvalente ao

CompraVO passado por parametro E em seguida envia uma mensagem ao

ValidadorBean, solicitando a validação da compra

Page 32: Introdução a JMS e Message-Driven Bean

Exercício (++)

Crie um cliente simples que efetua uma compra através o session Bean que você implementou

...E...

Page 33: Introdução a JMS e Message-Driven Bean

Bom (resto) de fim de semana!