introdução a jms e message-driven bean comunicação assíncrona ricardo cavalcanti...

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

Upload: sophia-paz

Post on 07-Apr-2016

219 views

Category:

Documents


4 download

TRANSCRIPT

Page 1: Introdução a JMS e Message-Driven Bean Comunicação Assíncrona Ricardo Cavalcanti roc3@cin.ufpe.br Jobson Ronan jrjs@cin.ufpe.br

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 Comunicação Assíncrona Ricardo Cavalcanti roc3@cin.ufpe.br Jobson Ronan jrjs@cin.ufpe.br

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 Comunicação Assíncrona Ricardo Cavalcanti roc3@cin.ufpe.br Jobson Ronan jrjs@cin.ufpe.br

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 Comunicação Assíncrona Ricardo Cavalcanti roc3@cin.ufpe.br Jobson Ronan jrjs@cin.ufpe.br

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çãoInvocação de método remoto

Messaging

Aplicação AplicaçãoMessage

Middleware

Page 5: Introdução a JMS e Message-Driven Bean Comunicação Assíncrona Ricardo Cavalcanti roc3@cin.ufpe.br Jobson Ronan jrjs@cin.ufpe.br

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 Comunicação Assíncrona Ricardo Cavalcanti roc3@cin.ufpe.br Jobson Ronan jrjs@cin.ufpe.br

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 Comunicação Assíncrona Ricardo Cavalcanti roc3@cin.ufpe.br Jobson Ronan jrjs@cin.ufpe.br

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 Comunicação Assíncrona Ricardo Cavalcanti roc3@cin.ufpe.br Jobson Ronan jrjs@cin.ufpe.br

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 1Consumidor 1Fila

Produtor 2

Page 9: Introdução a JMS e Message-Driven Bean Comunicação Assíncrona Ricardo Cavalcanti roc3@cin.ufpe.br Jobson Ronan jrjs@cin.ufpe.br

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 Comunicação Assíncrona Ricardo Cavalcanti roc3@cin.ufpe.br Jobson Ronan jrjs@cin.ufpe.br

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 Comunicação Assíncrona Ricardo Cavalcanti roc3@cin.ufpe.br Jobson Ronan jrjs@cin.ufpe.br

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 Comunicação Assíncrona Ricardo Cavalcanti roc3@cin.ufpe.br Jobson Ronan jrjs@cin.ufpe.br

InterfacesINTERFACE PAI POINT-TO-POINT PUB/SUBConnectionFactory QueueConnectionFactory TopicConnectionFactoryConnection 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 Comunicação Assíncrona Ricardo Cavalcanti roc3@cin.ufpe.br Jobson Ronan jrjs@cin.ufpe.br

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 Comunicação Assíncrona Ricardo Cavalcanti roc3@cin.ufpe.br Jobson Ronan jrjs@cin.ufpe.br

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 Comunicação Assíncrona Ricardo Cavalcanti roc3@cin.ufpe.br Jobson Ronan jrjs@cin.ufpe.br

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 Comunicação Assíncrona Ricardo Cavalcanti roc3@cin.ufpe.br Jobson Ronan jrjs@cin.ufpe.br

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 Comunicação Assíncrona Ricardo Cavalcanti roc3@cin.ufpe.br Jobson Ronan jrjs@cin.ufpe.br

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 Comunicação Assíncrona Ricardo Cavalcanti roc3@cin.ufpe.br Jobson Ronan jrjs@cin.ufpe.br

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 Comunicação Assíncrona Ricardo Cavalcanti roc3@cin.ufpe.br Jobson Ronan jrjs@cin.ufpe.br

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 Comunicação Assíncrona Ricardo Cavalcanti roc3@cin.ufpe.br Jobson Ronan jrjs@cin.ufpe.br

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 Comunicação Assíncrona Ricardo Cavalcanti roc3@cin.ufpe.br Jobson Ronan jrjs@cin.ufpe.br

<?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 Comunicação Assíncrona Ricardo Cavalcanti roc3@cin.ufpe.br Jobson Ronan jrjs@cin.ufpe.br

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 Comunicação Assíncrona Ricardo Cavalcanti roc3@cin.ufpe.br Jobson Ronan jrjs@cin.ufpe.br

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 Comunicação Assíncrona Ricardo Cavalcanti roc3@cin.ufpe.br Jobson Ronan jrjs@cin.ufpe.br

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 Comunicação Assíncrona Ricardo Cavalcanti roc3@cin.ufpe.br Jobson Ronan jrjs@cin.ufpe.br

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 Comunicação Assíncrona Ricardo Cavalcanti roc3@cin.ufpe.br Jobson Ronan jrjs@cin.ufpe.br

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 Comunicação Assíncrona Ricardo Cavalcanti roc3@cin.ufpe.br Jobson Ronan jrjs@cin.ufpe.br

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 Comunicação Assíncrona Ricardo Cavalcanti roc3@cin.ufpe.br Jobson Ronan jrjs@cin.ufpe.br

...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 Comunicação Assíncrona Ricardo Cavalcanti roc3@cin.ufpe.br Jobson Ronan jrjs@cin.ufpe.br

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 Comunicação Assíncrona Ricardo Cavalcanti roc3@cin.ufpe.br Jobson Ronan jrjs@cin.ufpe.br

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 Comunicação Assíncrona Ricardo Cavalcanti roc3@cin.ufpe.br Jobson Ronan jrjs@cin.ufpe.br

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 Comunicação Assíncrona Ricardo Cavalcanti roc3@cin.ufpe.br Jobson Ronan jrjs@cin.ufpe.br

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 Comunicação Assíncrona Ricardo Cavalcanti roc3@cin.ufpe.br Jobson Ronan jrjs@cin.ufpe.br

Bom (resto) de fim de semana!