cnam paris jean-michel douin, douin au cnam point fr version 12...
TRANSCRIPT
JMS_GLG2031
JMS,MOM, MDBJava Message Service,
Message-Oriented Middleware
Message-Driven Bean
Cnam Parisjean-michel Douin, douin au cnam point fr
version 12 février 2013
JMS_GLG2032
Sommaire
• Objectifs– Quelques patrons « MOM » issus de la bibliographie
• JMS une introduction– La spécification JMS
• Un ensemble d’interfaces
– Une implémentation « Open » OpenJMS
• MDB– Message Driven Bean
• Une démonstration– Un exemple basique avec OpenJMS
JMS_GLG2033
Bibliographie utilisée
• Le support de cours de NSY102-2011
• Tous les Patrons présentés sont extraits de, Gregor Hohpe and Bobby Woolf– http://www.enterpriseintegrationpatterns.com/eaipatterns.html– http://www.enterpriseintegrationpatterns.com/docs/E nterpriseIntegrationPatterns_HohpeWoolf_ch03.pdf– http://www.enterpriseintegrationpatterns.com/docs/j aoo_hohpeg_enterpriseintegrationpatterns.pdf
• JMS : L’indispensable tutoriel de Sun– http://java.sun.com/products/jms/tutorial/index.htm l– http://www.devx.com/Java/Article/20903/1954?pf=true– http://lsrwww.epfl.ch/webdav/site/lsrwww/shared/Ens eignement/SysRep07/Slides/JMS.pdf
• Architecture réparties en Java, de Annick Fron chez Dunod– http://www.dunod.com/livre-dunod-9782100511419-arch itectures-reparties-en-java.html
• MDB– http://java.sun.com/j2ee/tutorial/1_3-fcs/doc/MDB.h tml– http://www.roseindia.net/ejb/example-of-messageBean .shtml
JMS_GLG2034
Style RPC-OO/Messaging, schémas d’Uwe Zdun
• Messaging– JMS*– IBM WebSphere MQ– Microsoft MSMQ
* implementations de Java Message Service
• RPC-OO– java-rmi– .NET remoting– CORBA
JMS_GLG2035
Message-Oriented Middleware Objectifs
• Envoi et réception de messages– Réceptions synchrone et asynchrone
• Modèles– Point à point– Publish-subscribe
• Fiabilité de la délivrance des messages– Différents formats de messages– Persistance souhaitable
• Indépendance des canaux de communication / applicat ions
• Couplage faible assuré– Les canaux de communications sont indépendants des applications
• Référence aux canaux plutôt qu’aux adresses de mach ines• Serveur JMS, un courtier
JMS_GLG2036
Modèles
• http://jkost.ergoway.gr/jnkjavaconnection/jmstutori al.html
• Point à point
– Plusieurs consommateurs peuvent attendre sur cette file,
– un seul seulement recevra ce message
• Publish/subscribe
– Plusieurs consommateurs peuvent attendre sur cette file,
– Tous les consommateurs recevront ce message
JMS_GLG2037
Exemples … bien connus
• Le mail d’internet– Un émetteur envoie un message à un destinataire,– Le récepteur reçoit ce message (sans action particulière),– Les messages sont persistants,– Point à Point, synchrone, asynchrone
• Les news d’internet, ou le forum de jfod …– Enregistrement d’un « client » à un sujet de discussion,– Un des « clients » décide de poster un message,– Les utilisateurs à leur initiative vont chercher l’information,– Publish-subscribe, mode pull
• Les listes de diffusion, logiciels de causerie, (« chat »)– Abonnement d’un « client » à une liste de diffusion,– Un des « clients » décide de poster un message,– Tous les abonnés reçoivent ce message,– Publish-subscribe, mode push
JMS_GLG2038
Quelques patrons
• Patrons à l’aide d’un « langage graphique » de description d’une architecture de type MOM
• Extraits de http://www.enterpriseintegrationpatterns.com/eaipatterns.html
Et
• Mark grand– MailBox, Retransmission, Connection Multiplexing, Publish-Subscribe, …
JMS_GLG2039
Notation empruntée
http://www.enterpriseintegrationpatterns.com/docs/jaoo_hohpeg_enterpriseintegrationpatterns.pdf
JMS_GLG20310
MOM, Les patrons (65) !, selon Gregor Hohpe
!
JMS_GLG20311
Message construction
• Request Reply• Return Address• Correlation Identifier• …
JMS_GLG20312
Patron Request-Reply
• Analogue à l’architecture « Client/Serveur »• Canaux de communications
– Point à point– « Unidirectionnel »– Séparation des requêtes et de la réponse
JMS_GLG20313
Patron Return Address
• Plusieurs clients/consommateurs
• Identification du consommateur, « receveur »– Dans le contenu du message émis
JMS_GLG20314
Patron Correlation Identifier
• Le message contient un identificateur de Corrélation – Un nombre unique permettant l’identification et le bon acheminement du message
• Message ID • GUID (Globally Unique ID)• Business key (e.g. ID de bon de commande, de facture)
– Producteur copie l’ID dans le message retourné– Le client/consommateur peut ainsi corréler la requête et sa réponse
JMS_GLG20315
…MessageConstruction, fin de l’extrait
• Discussion– Approche fonctionnelle informelle d’un patron.
• La suite ici– http://www.enterpriseintegrationpatterns.com/eaipatterns.html
JMS_GLG20316
Message channels
• Point à Point• Publish Subscribe
– Observateur/Observé ?
• Durable Subscriber• …
• Les bases de JMS …
JMS_GLG20317
Point à point
• Envoi d’un message sur un canal en point à point, – Un seul receveur aura ce message– La persistance peut être assurée
• Surtout si le récepteur n’est pas en ligne lors de l’émission
– Réception synchrone ou asynchrone
– Exemple déjà vu : le mail
JMS_GLG20318
Publish/Subscribe
• Observateur/Observé « sélectif »– Souscription à un sujet/thème (topic)– Publication sur ce thème entraîne le réveil des sou scripteurs abonnés
• mode push• Si l’abonné est absent ?• Sélection de la souscription ?
– En mode pull , les abonnés devront s’enquérir des notifications
JMS_GLG20319
Durable Subscriber
• Durable Subscriber• Sauvegarde/Persistance du message jusqu’à ce que le
souscripteur soit informé de la « publication »
JMS_GLG20320
Langage de description, à base de patrons
• MOM, possède les mêmes patrons !
– Message-oriented middleware (MOM) • IBM WebSphere MQ• Microsoft MSMQ• Java Message Service (JMS) Implementations
– EAI Suites• TIBCO, WebMethods, SeeBeyond, Vitria
– Asynchronous Web services• Sun’s Java API for XML Messaging (JAXM)• Microsoft’s Web Services Extensions (WSE)
– http://www.middleware.org/mom/basicmom.html
JMS_GLG20321
Conclusion intermédiaire
• Transparents extraits de– http://www.enterpriseintegrationpatterns.com/eaipatterns.html
• À lire donc
JMS_GLG20322
JMS, Java Message Service
• N’est qu’une spécification – http://java.sun.com/products/jms/docs.html
• Soit en java
– Un ensemble d’interfaces que tout fournisseur est t enu de respecter
– Une série de tests de « conformité » http://jmscts.sourceforge.net/
• Comment ?– « Patron fabrique »
• Proposés par les fournisseurs JMS• Exemple :
ConnectionFactory fabrique = contexte.lookup("ConnectionFactory");
Connection connexion = fabrique .createConnection();
JMS_GLG20323
Modèles
• Point à Point– Queue
• Publish Subscribe– Topic
JMS_GLG20324
JMS Queue
• Schéma extrait du tutorial• Le courtier/serveur JMS gère les files, les communications, la persistance
Queue - Point à Point
JMS_GLG20325
JMS Topic
• Schéma extrait du tutorial
Topic - Publish-Subscribe
JMS_GLG20326
En détail, la session au centre
JNDI Context 1)
2)
3)
4)
JMS_GLG20327
Context
• Recherche de l’annuaire, ici OpenJMS
// configuration dans le source Java
Hashtable<String,String> props;props = new Hashtable<String,String>();
props.put(Context.INITIAL_CONTEXT_FACTORY, "org.exolab.jms.jndi.InitialContextFactory" );
props.put(Context.PROVIDER_URL , "tcp://localhost:3035/" );Context contexte = new InitialContext(props);
Voir javax.naming.ContextOu bien en ligne de commandejava … -Djava.naming.factory.initial= org.exolab.jms.jndi.InitialContextFactory
-Djava.naming.provider.url= tcp://localhost:3035/ …Cf. le fichier jndi.properties
JNDI Context
JMS_GLG20328
Context
• Recherche de l’annuaire, ici OpenJMS
Context contexte = new InitialContext();
// configuration via la ligne de commandes
En ligne de commandejava … -
Djava.naming.factory.initial= org.exolab.jms.jndi.InitialContextFactory
-Djava.naming.provider.url= tcp://localhost:3035/ …
Cf. le fichier jndi.properties
JNDI Context
JMS_GLG20329
Connection
ConnectionFactory fabrique;
fabrique = (ConnectionFactory) contexte.lookup("ConnectionFactory");
Connection connexion = fabrique.createConnection();
connexion.start();
• Encapsulation d’une connexion avec le courtier JMS– Typique une connexion TCP/socket
JMS_GLG20330
Session
Session session;session = connexion.createSession(false,
Session.AUTO_ACKNOWLEDGE);
• // en mode transactionnel, commit(), rollback()• // session = connexion.createSession(true, • Session.AUTO_ACKNOWLEDGE);
• Création des files de messages et thèmes de publica tions• Ajout des transactions, et d’un envoi séquentiel de s messages• Accusé réception des messages envoyés
JMS_GLG20331
Destination (Queue par exemple)
Destination dest;
dest = (Destination) contexte.lookup ("queue1") ;
Destination est un Objet JMS
Queue / Topic
Recherche de ce nom auprès du courtier JMS
Avec OpenJMS l’administrateur doit préalablement cré er ces entrées
JMS_GLG20332
MessageProducer
• MessageProducer prod = session.createProducer(dest);
• TextMessage message;
• message = session.createTextMessage( "hello" );
• prod.send(message);
JMS_GLG20333
MessageConsumer
• TextMessage message ;• Message = (TextMessage)receiver.receive();• System.out.println(message.getText());
JMS_GLG20334
Réception asynchrone : MessageListener
public class Consumer implements MessageListener {
public void onMessage(Message message){
TextMessage message ;
Message = (TextMessage)receiver.receive();
System.out.println(message.getText());
}
}
JMS_GLG20335
Graphe de classes
Queue extends DestinationQueueConnectionFactory extends ConnectionFactoryQueueConnection extends ConnectionQueueSession extends SessionQueueSender extends MessageProducerQueueReceiver extends MessageConsumer
idem pour Topic
JMS_GLG20336
Fabriques encore …
• ConnectionFactory fabrique = (ConnectionFactory) contexte.lookup("ConnectionFactory");
• QueueConnectionFactory fabrique = (QueueConnectionFactory) contexte.lookup(" JmsQueueConnectionFactory ");
• Topic ConnectionFactory fabrique = (TopicConnectionFactory) contexte.lookup(" JmsTopicConnectionFactory ");
JMS_GLG20337
Point à Point Queue
• En résumé
– Persistance des messages
– Réception synchrone ou asynchrone
JMS_GLG20338
Queue : un exemple extrait de http://fiehnlab.ucdavis.edu/staff/wohlgemuth/java/jms-1
// JNDI contexteInitialContext ctx = new InitialContext(props);
QueueConnectionFactory qcf = (QueueConnectionFactory) ctx.lookup("JmsQueueConnectionFactory");
QueueConnection qc = qcf.createQueueConnection();Queue queue = (Queue) ctx.lookup("queue1");
QueueSession qs = qc.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
QueueReceiver receiver = qs.createReceiver(queue);qc.start();
JMS_GLG20339
Publish-Subscribe
• Même schéma– De programme,– Concept identique au canal de communication
• Mais les messages publiés ne sont pas persistants
– Les messages publiés ne sont pas connus du souscrip teur avant saconnexion
JMS_GLG20340
Extrait de programme, Publisher
// contexte : JNDI
contexte = new InitialContext(props);
TopicConnectionFactory fabrique = (TopicConnectionFactory) contexte.lookup("JmsTopicConnectionFactory");
TopicConnection connexion = fabrique.createTopicConnection();
TopicSession session = connexion.createTopicSession(false,
Session.AUTO_ACKNOWLEDGE);
Topic topic = (Topic) contexte.lookup(topicName);
TopicPublisher sender = session.createPublisher(topic);
connexion.start();
JMS_GLG20341
Publisher, suite : envoi du message
TextMessage message = session.createTextMessage(" test ");
sender.publish(message);
Avec cette affectation, voir transparent précédent
TopicPublisher sender = session.createPublisher(topic);
JMS_GLG20342
Un extrait : le Subscriber
// contexte JNDIcontexte = new InitialContext(props);
TopicConnectionFactory fabrique = … idem PublisherTopicSession session = … idem PublisherTopic topic = … idem Publisher
in = session.createSubscriber(topic);in.setMessageListener(this);
connexion.start();}
public void onMessage(Message message) {// traitement du message
}
JMS_GLG20343
DurableSubscriberDurableSubscriberDurableSubscriberDurableSubscriber
• Persistance jusqu’à ce que le souscripteur se révei lle …
Même architecture
• TopicSubscriber subscriber;
• subscriber = session.createDurableSubscriber(
• topic, subscriptionName );
C’est tout
JMS_GLG20344
Souscription avec filtrage
• Abonnement conditionnel, sélectif
• Sélection des messages sur – La valeur de leurs attributs
• Syntaxe sous-ensemble de SQL– NOT, AND, OR, IS NULL …– BETWEEN ..– LIKE …
http://openjms.sourceforge.net/modules/openjms/apidocs/org/exolab/jms/selector/Selector.html
JMS_GLG20345
Souscription avec filtrage (2)
Même architecture
TopicSubscriber subscriber;
subscriber = session.createDurableSubscriber(
topic, subscriptionName,
" valeur >10 AND nom LIKE ‘urgent%’ " ,
true );
Le booléen true inhibe les messages publiés au sein de la même connexion
JMS_GLG20346
Message
• TextMessage String getText(), setText()
• MapMessage <Clé,Valeur> setString(), getString()
• BytesMessage flot de byte writeBytes(), readBytes()
• StreamMessage flot type primitifs writeString(), …
• ObjectMessage Objet sérialisé getObject(), setObject()
JMS_GLG20347
Détail sur les accusés de réception(ACK)
• Mode Session. AUTO_ACKNOWLEDGE– ACK, envoyé automatiquement– À la fin de la méthode receive (synchone)– Ou à la fin de la méthode onMessage (asynchrone)
• Mode Session .CLIENT_ACKNOWLEDGE– ACK, effectué par le récepteur– Appel de la méthode message. acknowledge ()
JMS_GLG20348
Persistance, fiabilité, défaillance
• Le serveur JMS s’arrête …– À la remise en état, tous les messages (persistants ) sont de nouveau
envoyés …
-> cela engendre donc qu’un même message peut être reçu plusieurs fois …
– Mode Session. AUTO_ACKNOWLEDGE• Une table des ID des messages est conservée par le client, un test de
la présence du message dans cette table évite la du plication
– Mode Session. DUPS_OK_ACKNOWLEDGE• Lorsque la réception multiple ne pose pas de problè mes
– Mode Session .CLIENT_ACKNOWLEDGE• Une exception est levée (ExceptionListener), c’est au client d’en tenir
compte
JMS_GLG20349
Message, quelques méthodes
• Affectation des champs du « header »
• JMSMessageID• JMSCorrelationID• JMSExpiration• JMSReplyTo• JMSDestination• …
Un Message
« header» « content»
JMS_GLG20350
Message suite
• JMSMessageID: – L’identificateur unique du message
• JMSCorrelationID: – Identification du message pour le client– Lie une réponse à une requête,– Le client vérifiera que ce nombre correspond à l’id entificateur envoyé
• JMSExpiration: – Durée de vie d’un message– 0 : infini
• JMSReplyTo: – Précisé par le client afin de répondre au message e nvoyé
• JMSDestination: – Afin de connaître le destinataire
JMS_GLG20351
Patron Request Reply + Correlation ID
• Message msg =
• // (« header ») affectation du champ reply-to• producerproducerproducerproducer = = = = session.CreateProducersession.CreateProducersession.CreateProducersession.CreateProducer((((msg.getJMSReplyTomsg.getJMSReplyTomsg.getJMSReplyTomsg.getJMSReplyTo());());());());
• // (« content ») • replyreplyreplyreply = = = = session.createTextMessagesession.createTextMessagesession.createTextMessagesession.createTextMessage("("("("replyreplyreplyreply");");");");
• // (« header ») Correl-ID == Message-ID• reply.setJMSCorrelationIDreply.setJMSCorrelationIDreply.setJMSCorrelationIDreply.setJMSCorrelationID((((msg.getJMSMessageIDmsg.getJMSMessageIDmsg.getJMSMessageIDmsg.getJMSMessageID());());());());
• producer.sendproducer.sendproducer.sendproducer.send((((replyreplyreplyreply););););
JMS_GLG20352
Transaction un schéma
public void execute(Contexte ctxt){
try{
beginTransaction();envoi_du_message_m1();
envoi_du_message_m2();
commitTransaction();}catch(Exception e){
rollbackTransaction();}
}
}
JMS_GLG20353
Avec JMS
• session = connection.createSession( true , Session.AUTO_ACKNOWLEDGE);
• Les Méthodes
– session.commit() – session.rollback();
JMS_GLG20354
Un exemple, OpenJMS
public static void avecTransaction() throws NamingExce ption, JMSException {Connection connexion = null; Context contexte = null;try {
// initialisation classique, page suivanteSession session = null;try {
// envoi, d'un message aux 3 files ... Seules deux ont été déclarées
session=connexion.createSession(true, Session.AUTO_ACKNOWLEDGE);Destination dest = (Destination) contexte.lookup("qu eue1");MessageProducer sender = session.createProducer(dest) ;TextMessage message = session.createTextMessage("env oi_queue1");sender.send(message);
dest = (Destination) contexte.lookup("queue2");sender = session.createProducer(dest);message = session.createTextMessage("envoi_queue2") ;sender.send(message);
dest = (Destination) contexte.lookup("queue_introuva ble");
session.commit(); } catch (javax.naming.NameNotFoundException e) {
System.out.println(e.getMessage() + " est introuvab le, rollback");
session.rollback();} catch (Exception e) {}
JMS_GLG20355
Exemple, 2/2
// initialisation classique, c.f. page précédente
Hashtable<String, String> props = new Hashtable<Stri ng, String>();
props.put(Context.INITIAL_CONTEXT_FACTORY,
"org.exolab.jms.jndi.InitialContextFactory");
props.put(Context.PROVIDER_URL, "tcp://localhost:30 35/");
contexte = new InitialContext(props);
ConnectionFactory fabrique = (ConnectionFactory) con texte.lookup("ConnectionFactory");
connexion = fabrique.createConnection();
connexion.start();
JMS_GLG20356
Conclusion JMS
• Simple
• Quelques déclarations
• Deux modèles
– Point à point– Publish/subscribe
• Si le courtier est en panne …
JMS_GLG20357
MDB
• Message Driven Bean– http://download.oracle.com/docs/cd/B31017_01/web.10 13/b28221/undejbs005.htm
–
• Intégration/collaboration JMS / serveur J2EE
– Traitements asynchrones• Mail, base de données, impressions, …
– Usage d’annotations• @MessageDriven, @ ActivationConfigProperty, …
JMS_GLG20358
MDB j2EE
– Une instance MDB se comportera comme un écouteur• « MessageListener », méthode onMessage()
– l’EJB Container qui implémente MessageListener (JMS)• Il gère un « pool » de MDB
JMS_GLG20359
Un MDB
Annotation afin de devenir MDB
@MessageDriven(mappedName = " topic_mail ");
// mappedName : c’est le nom JNDI,
// choisi pour le thème de souscription
public class SendMailBean { // implements MessageListener
// inutile, c.f. annotation
public void onMessage(Message message){
// envoi du message/mail
}
}
http://download.oracle.com/javaee/5/api/javax/ejb/Me ssageDriven.htmlVoir aussi @Resource, javax.annotation.Resource
JMS_GLG20360
MDB, suite
Annotation d’annotation afin de devenir MDB, un vra ice sont surtout les paramètres de configuration JMS
@MessageDriven(mappedName = " topic_mail " ,activationConfig={ // un tableau d’annotations
@ActivationConfigProperty( // couples clé/valeurpropertyName= "destinationType" ,propertyValue="javax.jms.Topic"),
@ActivationConfigProperty(…)}
)
public class SendMailBean{ …}
JMS_GLG20361
MDB, cycle de vie
• http://download.oracle.com/docs/cd/B31017_01/web.10 13/b28221/undejbs005.htm
JMS_GLG20362
Annotation, @PostConstruct @PreDestroy
public class SendMailBean { // implementsMessageListener
// inutile, c.f. annotation
public void onMessage(Message message){// envoi du message/mail
}
@PostConstructpublic void postConstruct(){ …. }
@PreDestroypublic void preDestroy(){ …. }
}
JMS_GLG20363
Conclusion
• Discussion
• Démonstration d’OpenJMS
JMS_GLG20364
Annexe
• http://openjms.sourceforge.net/– Point-to-Point and publish-subscribe messaging models– Guaranteed delivery of messages– Synchronous and asynchronous message delivery– Persistence using JDBC
– Local transactions– Message filtering using SQL92-like selectors– Authentication– Administration GUI– XML-based configuration files– In-memory and database garbage collection– Automatic client disconnection detection– Applet support– Integrates with Servlet containers such as Jakarta Tomc at– Support for TCP, RMI, HTTP and SSL protocol stacks– Support for large numbers of destinations and subscri bers
JMS_GLG20365
OpenJMS
• 1) D:\openjms-0.7.7-beta-1\bin>set JAVA_HOME=C:\jdk1 .6.0• 2) D:\openjms-0.7.7-beta-1\bin>start startup
• D:\openjms-0.7.7-beta-1\bin>start admin
• Exemples fournis,– D:\openjms-0.7.7-beta-1\examples\basic>build– D:\openjms-0.7.7-beta-1\examples\basic>start run Send er queue1 100 – D:\openjms-0.7.7-beta-1\examples\basic>start run Rece iver queue1 100 – D:\openjms-0.7.7-beta-1\examples\basic>start run Dura bleSuscriber meteo
JMS_GLG20366
OpenJMS + hsqldb, /config/
• Par défaut derby est utilisée<DatabaseConfiguration>
<RdbmsDatabaseConfiguration
driver="org.apache.derby.jdbc.EmbeddedDriver"
url="jdbc:derby:openjmsdb;create=true"
user="openjms"
password="openjms"/>
</DatabaseConfiguration>
• hsqldb http://hsqldb.org/<DatabaseConfiguration>
<RdbmsDatabaseConfiguration
driver="org.hsqldb.jdbcDriver"
url="jdbc:hsqldb:http://localhost:770/OPENJMSDB"
user="sa"
password=""/>
</DatabaseConfiguration>
Avec en préalable
1) java -cp ../lib/hsqldb1.8.jar org.hsqldb.WebServe r -port 770 -silent true -database.0 file:OPENJMSDB -dbname.0 OPENJMSDB
2) dbtool -create -config D:\openjms-0.7.7-beta-1\con fig\openjms.xml
JMS_GLG20367
Alternative à OpenJMS
• http://activemq.apache.org/index.html
JMS_GLG20368
Annexe Exemple extrait dehttp://www.enterpriseintegrationpatterns.com
• Extrait de http://www.enterpriseintegrationpatterns.com/RequestReplyJmsExample.html
Context context = // JNDI contextConnectionFactory factory = // …connection.start();
Requestor requestor = Requestor.newRequestor(connecti on,"request","reply","invalid");Replier replier = Replier.newReplier(connection,"re quest","invalid");
requestor.send();requestor.receiveSync();
JMS_GLG20369
Requestor initialize
private Destination replyQueue;private MessageProducer requestProducer;private MessageConsumer replyConsumer;private MessageProducer invalidProducer;
….
Destination requestQueue = JndiUtil.getDestination(r equestQueueName);replyQueue = JndiUtil.getDestination(replyQueueName) ;Destination invalidQueue = JndiUtil.getDestination(i nvalidQueueName);
requestProducer = session.createProducer(requestQueu e);replyConsumer = session.createConsumer(replyQueue);invalidProducer = session.createProducer(invalidQueu e);
}
JMS_GLG20370
Replier initialize
….
Destination requestQueue = JndiUtil.getDestination(r equestQueueName);Destination invalidQueue = JndiUtil.getDestination(i nvalidQueueName);
MessageConsumer requestConsumer = session.createConsu mer(requestQueue);
MessageListener listener = this;requestConsumer.setMessageListener(listener);
invalidProducer = session.createProducer(invalidQueu e);
JMS_GLG20371
Requestor send
public void send() throws JMSException {TextMessage requestMessage = session.createTextMessag e();requestMessage.setText("Hello world.");requestMessage.setJMSReplyTo(replyQueue);requestProducer.send(requestMessage);
System.out.println("Sent request");System.out.println("\tTime: " + System.curren tTimeMillis() + " ms");System.out.println("\tMessage ID: " + requestMessage .getJMSMessageID());System.out.println("\tCorrel. ID: " + requestMessag e.getJMSCorrelationID());System.out.println("\tReply to: " + requestMessage .getJMSReplyTo());System.out.println("\tContents: " + requestMessag e.getText());
}}
JMS_GLG20372
Replier, onMessage
public void onMessage(Message message) {try {
if ((message instanceof TextMessage) && (message.getJMSReplyTo() != null)) {TextMessage requestMessage = (TextMessage) message;System.out.println("Received request");System.out.println("\tTime: " + System.currentTimeMillis() + " ms");System.out.println("\tMessage ID: " + requestMessage.getJMSMessageID());System.out.println("\tCorrel. ID: " + requestMessage.getJMSCorrelationID());System.out.println("\tReply to: " + requestMessage.getJMSReplyTo());System.out.println("\tContents: " + requestMessage.getText());
String contents = requestMessage.getText();Destination replyDestination = message.getJMSReplyTo ();MessageProducer replyProducer = session.createProduce r(replyDestination);TextMessage replyMessage = session.createTextMessage( );replyMessage.setText(contents);replyMessage.setJMSCorrelationID(requestMessage.get JMSMessageID());replyProducer.send(replyMessage);
System.out.println("Sent reply");System.out.println("\tTime: " + System.currentTimeMillis() + " ms");System.out.println("\tMessage ID: " + replyMessage.getJMSMessageID());System.out.println("\tCorrel. ID: " + replyMessage.getJMSCorrelationID());System.out.println("\tReply to: " + replyMessage.getJMSReplyTo());System.out.println("\tContents: " + replyMessage.getText());
} else { // envoi sur invalidProducer
JMS_GLG20373
Requestor receiveSync
public void receiveSync() throws JMSException {Message msg = replyConsumer.receive();if (msg instanceof TextMessage) {
TextMessage replyMessage = (TextMessage) msg;System.out.println("Received reply ");System.out.println("\tTime: " + System.curren tTimeMillis() + " ms");System.out.println("\tMessage ID: " + replyMessage.g etJMSMessageID());System.out.println("\tCorrel. ID: " + replyMessage. getJMSCorrelationID());System.out.println("\tReply to: " + replyMessage.g etJMSReplyTo());System.out.println("\tContents: " + replyMessage. getText());
} else { // envoi sur invalidProducer
JMS_GLG20374
Traces d’exécution avec OpenJMS
• Notez l’affectation de Correl ID, lors de la réponse
JMS_GLG20375
JMS et Chat
• Extrait de http://forums.devx.com/showthread.php?t=137396
• Un bon exemple de mise en oeuvre
JMS_GLG20376
Exemple de déploiement, JMS-MDB
• Source : https://cwiki.apache.org/GMOxDOC10/integrating-a-th ird-party-jms-provider.html