jean-michel Douin, douin au cnam point fr

Slides:



Advertisements
Présentations similaires
La place accordée à l’expression des salariés sur leur travail et leurs conditions de travail dans l’entreprise Résultats sondage exclusif CSA/ANACT.
Advertisements

Mais vous comprenez qu’il s’agit d’une « tromperie ».
Le Nom L’adjectif Le verbe Objectif: Orthogram
ORTHOGRAM PM 3 ou 4 Ecrire: « a » ou « à » Référentiel page 6
Reporting de la Cellule Nationale Droit dOption Situation au 31 décembre 2011.
Présentation de la circonscription Année 2011/2012 Jeudi 24 novembre 2011.
Additions soustractions
Distance inter-locuteur
1 Plus loin dans lutilisation de Windows Vista ©Yves Roger Cornil - 2 août
Message Oriented Middleware
Message Oriented Middleware. Plan Pourquoi un nouveau type de middleware? Quelle lignée logicielle ? Historique JMS : Java Message Server Limplémentation.
Les numéros 70 –
Les numéros
Le, la, les words Possessive Adjectives MINE!!. 2 My in french is mon, ma,mes... Le word/ begins with a vowel: Mon La word: Ma Les word: Mes.
Xavier Mouranche Registre e-MUST Evaluation en Médecine dUrgence des Stratégies Thérapeutiques de lInfarctus du Myocarde.
Cours MIAGE « Architectures Orientées Services » Henry Boccon-Gibod 1 Architectures Orientées Services Composants de Service Exemple pratique de développement.
Algorithme et structure de données
JORAM Java Open Reliable Asynchronous Messaging
LICENCE MIAGE Introduction Programmation Orientée Objet JAVA philippe
LES TRIANGLES 1. Définitions 2. Constructions 3. Propriétés.
Données statistiques sur le droit doption au 31/01 8 février 2012.
Message-Driven Beans Michel Buffa UNSA modifié par Richard Grin (version 1.0, 21/11/11)
Correspondances en Onco-Urologie - Vol. III - n° 3 – juillet-août-septembre VESSIE Daprès James ND et al., N Engl J Med 2012;366:16:
Technologies et pédagogie actives en FGA. Plan de latelier 1.Introduction 2.Les technologies en éducation 3.iPads 4.TNI 5.Ordinateurs portables 6.Téléphones.
Enquête sur le Rapport de la Commission Bouchard-Taylor Jack Jedwab Directeur général Association détudes canadiennes 11 juin 2008.
Révision (p. 130, texte) Nombres (1-100).
La législation formation, les aides des pouvoirs publics
1 7 Langues niveaux débutant à avancé. 2 Allemand.
1 5 octobre 2011 / paw Présentation du 7 octobre 2011.
La méthodologie………………………………………………………….. p3 Les résultats
Structure(djs)TéléphoneFax ADRA R049,96,03,21 CHLEF027,77,22,66 /77,49, LAGHOUAT029,90,41,08029,90,42,47 OUM EL BOUAGHI032,42,16,26032,42,45,32.
BlueJ_XI 1 Java, les objets : tout de suite ! Gestion des erreurs : les exceptions Notes de cours associées au chapitre 11 tutorial BlueJ
Jack Jedwab Association détudes canadiennes Le 27 septembre 2008 Sondage post-Olympique.
Jack Jedwab Directeur général Association détudes canadiennes Octobre 2011 Jack Jedwab Directeur général Association détudes canadiennes Octobre 2011 Est-ce.
Le soccer & les turbans Sondage mené par lAssociation détudes canadiennes 14 juin 2013.
Présentation générale
Le drapeau canadien comme symbole de fierté nationale : une question de valeurs partagées Jack Jedwab Association détudes canadiennes 28 novembre 2012.
Les nombres.
Fierté envers les symboles et institutions canadiens Jack Jedwab Association détudes canadiennes 26 novembre 2012.
Conseil Administration AFRAC – 2 décembre Toulouse 1 Fermes de références Palmipèdes à foie gras Synthèse régionale – Midi Pyrénées Exercice
Projet poker 1/56. Introduction Présentation de léquipe Cadre du projet Enjeux Choix du sujet 2.
F Copyright © Oracle Corporation, Tous droits réservés. Créer des programmes avec Procedure Builder.
LES NOMBRES PREMIERS ET COMPOSÉS
Logiciel gratuit à télécharger à cette adresse :
Les chiffres & les nombres
Les Monnaies et billets du FRANC Les Monnaies Euro.
DUMP GAUCHE INTERFERENCES AVEC BOITIERS IFS D.G. – Le – 1/56.
1 CSI 2532 Lab5 Installation de JDBC Février 13, 2012.
Année universitaire Réalisé par: Dr. Aymen Ayari Cours Réseaux étendus LATRI 3 1.
Numbers Français I.
Jean-Marc Léger Président Léger Marketing Léger Marketing Les élections présidentielles américaines.
Introduction au Langage C
Proxy et plus Cnam Paris jean-michel Douin, douin au cnam point fr
MAGIE Réalisé par Mons. RITTER J-P Le 24 octobre 2004.
1 INETOP
Les Nombres 0 – 100 en français.
Aire d’une figure par encadrement
Copyright 2011 – Les Chiffres Copyright 2011 –
P.A. MARQUES S.A.S Z.I. de la Moussière F DROUE Tél.: + 33 (0) Fax + 33 (0)
Les fondements constitutionnels
MAGIE Réalisé par Mons. RITTER J-P Le 24 octobre 2004.
JEE 5 F.Pfister 2 institut eerie JEE – Une plateforme serveur  Développement et exécution d'applications réparties.
1/65 微距摄影 美丽的微距摄影 Encore une belle leçon de Macrophotographies venant du Soleil Levant Louis.
Certains droits réservés pour plus d’infos, cliquer sur l’icône.
Annexe Résultats provinciaux comparés à la moyenne canadienne
Cours n°4M2. ESCE (S. Sidhom) Séminaire ( 6-12 Février 2007 ) Promo. M2 ESCE-Tunis 2006/07 Conception d’un système d'information sur Internet Architecture.
La formation des maîtres et la manifestation de la compétence professionnelle à intégrer les technologies de l'information et des communications (TIC)
Bienvenue.
NSY102 1 NSY102 Conception de logiciels Intranet MOM Message-Oriented Middleware en utilisant JMS Java Message Service Cnam Paris jean-michel Douin, douin.
Transcription de la présentation:

jean-michel Douin, douin au cnam point fr NSY102 Conception de logiciels Intranet MOM Message-Oriented Middleware en utilisant JMS Java Message Service Cnam Paris jean-michel Douin, douin au cnam point fr version 13 Mai 2011

Sommaire Objectifs JMS une introduction Une démonstration Quelques patrons issus de la bibliographie Un langage de description JMS une introduction La spécification JMS Un ensemble d’interfaces Une implémentation « Open » OpenJMS Une démonstration Un exemple basique

Bibliographie utilisée 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/EnterpriseIntegrationPatterns_HohpeWoolf_ch03.pdf http://www.enterpriseintegrationpatterns.com/docs/jaoo_hohpeg_enterpriseintegrationpatterns.pdf JMS : L’indispensable tutoriel de Sun http://java.sun.com/products/jms/tutorial/index.html http://www.devx.com/Java/Article/20903/1954?pf=true http://marine.edu.ups-tlse.fr/~torguet/cours/m2miage/jms1.1/doc/api/ Joram http://www;objectweb.org La présentation de l’EPFL, (École polytechnique de Lausannne) http://lsrwww.epfl.ch/webdav/site/lsrwww/shared/Enseignement/SysRep07/Slides/JMS.pdf Architecture réparties en Java, de Annick Fron chez Dunod http://www.dunod.com/livre-dunod-9782100511419-architectures-reparties-en-java.html Using publish/subscribe messaging to distribute MIDI commands http://www.ibm.com/developerworks/websphere/library/techarticles/0412_ibbotson/0412_ibbotson.html

Pré-requis Notions des patrons Adaptateur, Procuration, Chaîne de responsabilités/Interceptor*, Observateur/observé, Fabrique. * rappelé annexe

Style RPC-OO/Messaging, schémas d’Uwe Zdun java-rmi .NET remoting CORBA Messaging JMS* IBM WebSphere MQ Microsoft MSMQ * implementations de Java Message Service

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 / applications Couplage faible assuré Les canaux de communications sont indépendants des applications Référence aux canaux plutôt qu’aux adresses de machines Serveur JMS, un courtier

Exemples … bien connus 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 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 listes de diffusion, logiciels de causerie, (« chat ») Abonnement d’un « client » à une liste de diffusion, Tous les abonnés reçoivent ce message, Publish-subscribe, mode push

Quelques patrons Patrons comme langage 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, … Quelques schémas en guise d’introduction …

Notation empruntée http://www.enterpriseintegrationpatterns.com/docs/jaoo_hohpeg_enterpriseintegrationpatterns.pdf

MOM, Les patrons (65) !, selon Gregor Hohpe Un échantillon !

Message construction Request Reply Return Address Correlation Identifier …

Patron Request-Reply Analogue à l’architecture « Client/Serveur » Canaux de communications Point à point « Unidirectionnel » Séparation des requêtes et de la réponse

Patron Return Address Plusieurs clients/consommateurs Identification du consommateur, « receveur » Dans le contenu du message émis

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 Each reply message should contain a Correlation Identifier, a unique identifier that indicates which request message this reply is for. Equip each message with a unique identifier Message ID (simple, but has limitations) GUID (Globally Unique ID) Business key (e.g. Order ID) Provider copies the ID to the reply message Consumer can match request and response

…MessageConstruction, fin de l’extrait Discussion Utile/inutile La suite ici http://www.enterpriseintegrationpatterns.com/eaipatterns.html

Message channels Point à Point Publish Subscribe Durable Subscriber Observateur/Observé ? Durable Subscriber Guaranteed Delivery …

Point à point Envoi d’un message sur un canal en point à point, assure qu’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

Publish/Subscribe ou Observateur/Observé http://book.itzero.com/read/MICROSOFT/0603/Sams.Microsoft.SQL.Server.2005.Notification.Services.Feb.2006_html/0672327791/ch01lev1sec2.html

Publish/Subscribe Observateur/Observé « sélectif » Souscription d’un sujet/thème (topic) Publication entraîne le réveil des souscripteurs mode push Si l’abonné est absent ? Sélection de la souscription ? En mode pull, les abonnés devront s’enquérir des notifications

Durable Subscriber Durable Subscriber Sauvegarde/Persistance du message jusqu’à ce que le souscripteur soit informé de la « publication » A durable subscription saves messages for an inactive subscriber and deliveres these saved messages when the subscriber reconnects. In this way, a subscriber will not loose any messages even though it disconnected. A durable subscription has no effect on the behavior of the subscriber or the messaging system while the subscriber is active (e.g., connected). A connected subscriber acts the same whether its subscription is durable or non-durable. The difference is in how the messaging system behaves when the subscriber is disconnected.

Reliable, Guaranteed Delivery Use Guaranteed Delivery to make messages persistent so that they are not lost even if the messaging system crashes. Pertes possibles, évitées des messages la persistance de ceux-ci, sur chaque poste

Message endpoints Messaging Adapter Patron Polling Consumer Patron Transactional Client …

Messaging Adapter Pattern Adaptateur / Wrapper Mise en forme, au bon format du contenu du message Connect an application to a messaging channel using a Message Endpoint, a client of the messaging system that the application can then use to send or receive messages

Patron Polling Consumer Récepteur synchrone, Le récepteur est bloqué jusqu’à ce que le message soit reçu This is also known as a synchronous receiver, because the receiver thread blocks until a message is received. We call it a Polling Consumer because the receiver polls for a message, processes it, then polls for another. As a convenience, messaging API’s usually provide a receive method that blocks until a message is delivered, in addition to methods like receiveNoWait() and Receive(0) that return immediately if no message is available. This difference is only apparent when the receiver is polling faster than messages are arriving.

Patron Transactional Client Opération atomique commit, rollback La session est achevée lors du commit Plusieurs Receiver/Sender Both a sender and a receiver can be transactional. With a sender, the message isn’t “really” added to the channel until the sender commits the transaction. With a receiver, the message isn’t “really” removed from the channel until the receiver commits the transaction. A sender that uses explicit transactions can be used with a receiver that uses implicit transactions, and vise versa. A single channel might have a combination of implicitly and explicitly transactional senders; it could also have a combination of receivers.

Message Routing Content Based Router Dynamic Router Recipient List Splitter/Agregator …. http://www.enterpriseintegrationpatterns.com/MessageRoutingIntro.html

Patron Content Based Router The Content-Based Router examines the message content and routes the message onto a different channel based on data contained in the message. The routing can be based on a number of criteria such as existence of fields, specific field values etc. When implementing a Content-Based Router, special caution should be taken to make the routing function easy to maintain as the router can become a point of frequent maintenance. In more sophisticated integration scenarios, the Content-Based Router can take on the form of a configurable rules engine that computes the destination channel based on a set of configurable rules. Selon le contenu du message, une sélection du canal de communication est effectuée

Dynamic Router En cours d’exécution, selon le contenu du message et certaines conditions/règles la sélection du canal est effectuée Besides the usual input and output channels the Dynamic Router uses an additional control channel. During system start-up, each potential recipient sends a special message to the Dynamic Router on this control channel, announcing its presence and listing the conditions under which it can handle a message. The Dynamic Router stores the 'preferences' for each participant in a rule base. When a message arrives, the Dynamic Router evaluates all rules and routes the message to the recipient whose rules are fulfilled. This allows for efficient, predictive routing without the maintenance dependency of the Dynamic Router on each potential recipient.

Patron Recipient List Un Canal par destinataire Envoie une copie du message sur chaque canal Store and forward The logic embedded in a Recipient List can be pictured as two separate parts even though the implementation is often coupled together. The first part computes a list of recipients. The second part simply traverses the list and sends a copy of the received message to each recipient. Just like a Content-Based Router, the Recipient List usually does not modify the message contents.

Splitter/Agregator Découpage et Assemblage du message http://www.enterpriseintegrationpatterns.com/Aggregator.html http://www.enterpriseintegrationpatterns.com/Sequencer.html Use a stateful filter, an Aggregator, to collect and store individual messages until a complete set of related messages has been received. Then, the Aggregator publishes a single message distilled from the individual messages Découpage et Assemblage du message

Message transformation ContentFilter Claim Check

Patron Content Filter Filtrage des informations « essentielles » http://www.enterpriseintegrationpatterns.com/ContentFilter.html The Content Filter does not necessarily just remove data elements. A Content Filter is also useful to simplify the structure of the message. Often times, messages are represented as tree structures. Many messages originating from external systems or packaged applications contain many levels of nested, repeating groups because they are modeled after generic, normalized database structures. Frequently, known constraints and assumptions make this level of nesting superfluous and a Content Filter can be used to 'flatten' the hierarchy into a simple list of elements than can be more easily understood and processed by other systems.

Patron Claim Check Persistance du message Reconstitution de celui-ci ciStore message data in a persistent store and pass a Claim Check to subsequent components. These components can use the Claim Check to retrieve the stored information. Persistance du message Reconstitution de celui-ci

System Management Supervision et contrôle Mesures du trafic … ControlBus Detour Mesures du trafic … Message History Test et mise au point Test Message

Patron ControlBus Outil de supervision A Control Bus provides a single point of control to manage and monitor a distributed solution. It connects multiple components to a central management console that can display the status of each component and monitor message traffic through the components. The console can also be used to send control commands to components, e.g. to change the message flow. We may want to route messages through additional steps, such as validation or logging. Because these steps can introduce performance overheads, we may want to be able to switch them on and off via the control bus. A Detour gives us this ability.

Patron Detour Débogage …

Message History Historique des opérations effectuées Therefore, attach a Message History to the message. The Message History is a list of all applications that the message passed through since its origination. The Message History maintains a list of all components that the message passed through. Every component that processes the message (including the originator) adds one entry to the list. The Message History should be part of the message header because it contains system-specific control information. Keeping this information in the header separates it from the message body that contains application specific data.

Patron Message store Duplication du message Persistance When using a Message Store, we can take advantage of the asynchronous nature of a messaging infrastructure. When we send a message to a channel, we send a duplicate of the message to a special channel to be collected by the Message Store. This can be performed by the component itself or we can insert a Wire Tap into the channel. We can consider the secondary channel that carries a copy of the message as part of the Control Bus. Sending a second message in a 'fire-and-forget' mode will not slow down the flow of the main application messages. It does, however, increase network traffic. That's why we may not store the complete message, but just a few key fields that are required for later analysis, such as a message ID, or the channel on which the message was sent and a timestamp.

Patron TestMessage Techniques de test …

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

Conclusion intermédiaire Transparents extraits de http://www.enterpriseintegrationpatterns.com/eaipatterns.html À lire donc

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 tenu 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();

Modèles Point à Point Queue Publish Subscibe Topic

JMS Queue Queue - Point à Point Schéma extrait du tutorial Le courtier/serveur JMS gère les files, les communications, la persistance

Topic - Publish-Subscribe JMS Topic Topic - Publish-Subscribe Schéma extrait du tutorial

La session au centre JNDI Context

Context JNDI Context Recherche de l’annuaire, ici OpenJMS 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.Context Ou bien en ligne de commande java … -Djava.naming.factory.initial=org.exolab.jms.jndi.InitialContextFactory -Djava.naming.provider.url=tcp://localhost:3035/ … Voir le fichier jndi.properties

Connection ConnectionFactory fabrique; fabrique = (ConnectionFactory) contexte.lookup("ConnectionFactory"); Connection connexion = fabrique.createConnection(); connexion.start(); It encapsulates an open connection with a JMS provider. It typically represents an open TCP/IP socket between a client and the service provider software. Its creation is where client authentication takes place. It can specify a unique client identifier. It provides a ConnectionMetaData object. It supports an optional ExceptionListener object.

Session Session session; session = connexion.createSession(false, Session.AUTO_ACKNOWLEDGE); It is a factory for its message producers and consumers. It supplies provider-optimized message factories. It is a factory for TemporaryTopics and TemporaryQueues. It provides a way to create Queue or Topic objects for those clients that need to dynamically manipulate provider-specific destination names. It supports a single series of transactions that combine work spanning its producers and consumers into atomic units. It defines a serial order for the messages it consumes and the messages it produces. It retains messages it consumes until they have been acknowledged. It serializes execution of message listeners registered with its message consumers. It is a factory for QueueBrowsers.

Destination (Queue par exemple) Destination dest; dest = (Destination) contexte.lookup("queue1"); Destination est un Objet JMS Queue / Topic

MessageProducer MessageProducer prod = session.createProducer(dest); TextMessage message; message = session.createTextMessage("hello"); prod.send(message);

MessageConsumer TextMessage message ; Message = (TextMessage)receiver.receive(); System.out.println(message.getText());

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()); }

Graphe de classes Queue extends Destination QueueConnectionFactory extends ConnectionFactory QueueConnection extends Connection QueueSession extends Session QueueSender extends MessageProducer QueueReceiver extends MessageConsumer idem pour Topic

Fabriques encore … ConnectionFactory fabrique = (ConnectionFactory) contexte.lookup("ConnectionFactory"); QueueConnectionFactory fabrique = (QueueConnectionFactory) contexte.lookup("JmsQueueConnectionFactory"); TopicConnectionFactory fabrique = (TopicConnectionFactory) contexte.lookup("JmsTopicConnectionFactory");

Point à Point Queue En résumé Persistance des messages Réception synchrone ou asynchrone

Queue : un exemple extrait de http://fiehnlab. ucdavis // JNDI contexte InitialContext 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();

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 souscripteur avant sa connexion

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();

Publisher, suite : envoi du message TextMessage message = session.createTextMessage("test"); sender.publish(message); Avec, voir transparent précédent TopicPublisher sender = session.createPublisher(topic);

Un extrait : le Subscriber // contexte JNDI contexte = new InitialContext(props); TopicConnectionFactory fabrique = … idem Publisher TopicSession session = … idem Publisher Topic topic = … idem Publisher in = session.createSubscriber(topic); in.setMessageListener(this); connexion.start(); } public void onMessage(Message message) { // traitement du message

DurableSubscriber Persistance jusqu’à ce que le souscripteur se réveille … Même architecture TopicSubscriber subscriber; subscriber = session.createDurableSubscriber( topic, subscriptionName); C’est tout

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

Souscription avec filtrage (2) Même architecture TopicSubscriber subscriber; subscriber = session.createDurableSubscriber( topic, subscriptionName " valeur >10 AND nom LIKE ‘urgent%’ "  , true); Le booleén true inhibe les messages publiés au sein de la même connexion À vérifier avec OpenJMS …

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()

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()

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 duplication 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

Message, quelques méthodes « content» « header » Un Message Affectation des champs du « header » JMSMessageID JMSCorrelationID JMSExpiration JMSReplyTo JMSDestination …

Message suite JMSMessageID: JMSCorrelationID: 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’identificateur envoyé

Message suite, quelques méthodes JMSExpiration: Durée de vie d’un message 0 : infini

Message JMSReplyTo: JMSDestination: Précisé par le client afin de répondre au message envoyé JMSDestination: Afin de connaître le destinataire

Patron Request Reply + Correlation ID Message msg = // (« header ») affectation du champ reply-to producer = session.CreateProducer(msg.getJMSReplyTo()); // (« content ») reply = session.createTextMessage("reply"); // (« header ») Correl-ID == Message-ID reply.setJMSCorrelationID(msg.getJMSMessageID()); producer.send(reply);

Un exemple, à suivre http://www.enterpriseintegrationpatterns.com/ObserverJmsExample.html http://www.enterpriseintegrationpatterns.com/index.html

Transaction & session Transfert de compte, débit-crédit, commit/rollback Voir http://java.sun.com/j2ee/1.4/docs/tutorial/doc/JMS6.html

Transaction un schéma void onMessage(Message msg){ try{ session = connexion.createTopicSession(true, Session.AUTO_ACKNOWLEDGE); void onMessage(Message msg){ try{ // un traitement, susceptible de lever une exception m2 = …; publisher.publish(m2); session.commit(); // acquittement des messages }catch(Exception e){ session.rollback(); // annulation des messages } assert session.getTransacted() == Session.SESSION_TRANSACTED;

Transaction comme Session JMS propose (seulement) les transactions au sein d’une même session Transaction distribuée avec les XASession Optionnel pour les fournisseurs de JMS Passerelle vers JTA (Java Transaction API) XASession XAQueueSession, XATopicSession

JMS et JMX Supervision et « management » à distance Voir http://lmi92.cnam.fr/NSY102/tp_nsy102_en_salle/tp_03_jms_jmx/   figure extraite de ce livre http://www.manning.com/sullins/

Conclusion JMS1.1 se trouve en J2EE1.4 À suivre Supervision, JMX Transactions Mise en oeuvre Distribuées JTA

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 Tomcat Support for TCP, RMI, HTTP and SSL protocol stacks Support for large numbers of destinations and subscribers

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 Sender queue1 100 D:\openjms-0.7.7-beta-1\examples\basic>start run Receiver queue1 100 D:\openjms-0.7.7-beta-1\examples\basic>start run DurableSuscriber meteo

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/ driver="org.hsqldb.jdbcDriver" url="jdbc:hsqldb:http://localhost:770/OPENJMSDB" user="sa" password=""/> Avec en préalable 1) java -cp ../lib/hsqldb1.8.jar org.hsqldb.WebServer -port 770 -silent true -database.0 file:OPENJMSDB -dbname.0 OPENJMSDB 2) dbtool -create -config D:\openjms-0.7.7-beta-1\config\openjms.xml

Alternative à OpenJMS http://activemq.apache.org/index.html

Annexe Exemple extrait de http://www.enterpriseintegrationpatterns.com Context context = // JNDI context ConnectionFactory factory = // … connection.start(); Requestor requestor = Requestor.newRequestor(connection,"request","reply","invalid"); Replier replier = Replier.newReplier(connection,"request","invalid"); requestor.send(); requestor.receiveSync();

Requestor initialize private Destination replyQueue; private MessageProducer requestProducer; private MessageConsumer replyConsumer; private MessageProducer invalidProducer; …. Destination requestQueue = JndiUtil.getDestination(requestQueueName); replyQueue = JndiUtil.getDestination(replyQueueName); Destination invalidQueue = JndiUtil.getDestination(invalidQueueName); requestProducer = session.createProducer(requestQueue); replyConsumer = session.createConsumer(replyQueue); invalidProducer = session.createProducer(invalidQueue); }

Replier initialize …. Destination requestQueue = JndiUtil.getDestination(requestQueueName); Destination invalidQueue = JndiUtil.getDestination(invalidQueueName); MessageConsumer requestConsumer = session.createConsumer(requestQueue); MessageListener listener = this; requestConsumer.setMessageListener(listener); invalidProducer = session.createProducer(invalidQueue);

Requestor send public void send() throws JMSException { TextMessage requestMessage = session.createTextMessage(); requestMessage.setText("Hello world."); requestMessage.setJMSReplyTo(replyQueue); requestProducer.send(requestMessage); System.out.println("Sent 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()); }

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.createProducer(replyDestination); TextMessage replyMessage = session.createTextMessage(); replyMessage.setText(contents); replyMessage.setJMSCorrelationID(requestMessage.getJMSMessageID()); replyProducer.send(replyMessage); System.out.println("Sent reply"); 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

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.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

Traces d’exécution avec OpenJMS Notez l’affectation de Correl ID, lors de la réponse

JMS et Chat Extrait de http://forums.devx.com/showthread.php?t=137396 Un bon exemple de mise en oeuvre

Interceptor : une variante « Chain of Responsability » http://bosy.dailydev.org/2007/04/interceptor-design-pattern.html http://longbeach.developpez.com/tutoriels/EJB3/Interceptors/ http://homepage.mac.com/cewcew/edu/cmsi688/InterceptorFilters.ppt.

Une implémentation légère

Interceptor<T> et une implémentation public interface Interceptor<T>{ public T invoke(T in) throws Exception; } public class TraceInterceptor<T> implements Interceptor<T>{ public T invoke(T in) throws Exception{ System.out.println(this.getClass().getName() + " : " + in); return in;

Dispatcher<T> public class Dispatcher<T> implements Interceptor<T>{ private Interceptor<T> interceptors[]; public Dispatcher(final Interceptor<T>... interceptors){ this.interceptors = interceptors; } // public Dispatcher(final Class<? extends Interceptor<T>>... interceptors) throws InstantiationException, IllegalAccessException{ syntaxe préférée mais Client ne se compile pas public Dispatcher(final Class<? extends Interceptor>... interceptors) throws InstantiationException, IllegalAccessException{ int i = 0; this.interceptors = new Interceptor[interceptors.length]; for(Class<? extends Interceptor> interceptor : interceptors){ this.interceptors[i] = interceptor.newInstance(); i++; public T invoke(final T in){ T out = in; for(Interceptor<T> interceptor : interceptors){ try{ out = interceptor.invoke(out); }catch(Exception e){} return out;

Le Client public class Client{ public static void main(String[] args) throws Exception{ Dispatcher<String> dispatcher1 = new Dispatcher<String>(new LoggingInterceptor<String>(), new TraceInterceptor<String>()); System.out.println(dispatcher1.invoke("test_1")); Dispatcher<String> dispatcher2 = new Dispatcher<String>(LoggingInterceptor.class, LoggingInterceptor.class); System.out.println(dispatcher2.invoke("test_2")); }