Interface TopicSubscriber - NSY102 Conception de logiciels Intranet

Ce patron (RecipientList) mémorise (store) le message reçu et diffuse (forward) celui-ci ... Votre classe doit utiliser L'API Java Message Service (cf. certaines.
90KB taille 10 téléchargements 352 vues
NSY102 Conception de logiciels Intranet : Patrons et Canevas. Session de Juin 2007-durée : 2 heures Tous documents papiers autorisés

Cnam / Paris Sommaire : 3 questions indépendantes Question 1 (5 points) Question 2 (10 points) Question 3 (5 points)

: Patron Observateur : Patron « RecipientList » / RMI : Patron « Publish-Subscribe » / JMS

Question1 (5 points) : Patron Observateur / Pattern Observer

L’utilisation de ce patron engendre une notification aux observateurs inscrits, ces notifications sont initiées par l’observé, à la suite d’un changement d’état de celui-ci. Selon l’architecture des classes retenue, et le patron employé, une liste (instance de la classe Liste) est « observée », la classe Liste implémente toutes les méthodes de l’interface SujetObservé, et se charge de notifier les observateurs inscrits lors d’un changement d’état d’une liste. L’interface SujetObservé contient seulement deux méthodes : l’ajout et le retrait d’un observateur. public interface SujetObservé{ public void ajouterUnObservateur( Observateur obs ); public void retirerUnObservateur( Observateur obs ); }

L’interface Observateur ne comporte que la méthode de mise à jour, déclenchée, à la suite d’une notification : public interface Observateur{ public void miseAJour(SujetObservé s ); }

NSY102-examen-juin-2007

1/14

Question 1 : Complétez la classe Liste. (Les interfaces Iterable et List sont en annexe) public class Liste implements SujetObservé, Iterable { private List contenu = new ArrayList(); ??? // ajouter un Objet à la collection public void ajouter( T t ){ ??? } // supprimer un Objet de la collection public void retirer( T t ) { ??? } public boolean estPrésent( T t ){ return ??? } ??? ??? ??? }

Ci-dessous, un extrait de la classe de tests unitaires (TestsListe) : public class TestsListe extends junit.framework.TestCase private boolean notifié = false; public void test( ) { Liste l1 = new Liste(); l1.ajouter( 1 ); l1.ajouter( 2 ); l1.ajouter( 3 ); l1.ajouter( 4 ); assertFalse(" pas (encore) de notification attendue ???", notifié); l1.ajouterUnObservateur( new Observateur(){ public void miseAJour(SujetObservé s ){ notifié = true; assertTrue(" ???", s instanceof Liste); } }); l1.ajouter( 5 ); assertTrue("une notification est attendue ???",notifié); notifié = false; l1.ajouter( 6 ); assertTrue("une notification est attendue ???",notifié); }

NSY102-examen-juin-2007

2/14

Question2 (10 points) : Patron Diffuseur /Pattern RecipienList 1

(alias StoreAndForward)

: un message Ce patron (RecipientList) mémorise (store) le message reçu et diffuse (forward) celui-ci vers tous les destinataires agréés. A chaque type de message correspond une liste de destinataires. L’architecture des classes ci-dessous, reflète un usage de ce patron

L’interface Channel est commune au Patron RecipientList et aux receveurs des messages Receiver public interface Channel extends Remote, Serializable{ public void sendMessage( Message message) throws RemoteException; }

L’interface RecipientList hérite de l’interface Channel et permet d’ajouter la liste des receveurs agréés à une entrée compatible avec l’interface InputChannel. Cette association est mémorisée afin éventuellement de réémettre le message (L’interface Map est en annexe) 1

Inspiréde http://www.enterpriseintegrationpatterns.com/RecipientList.html

NSY102-examen-juin-2007

3/14

public interface RecipientList extends Channel{ public void addRoute(InputChannel source, Channel[] destinations) throws RemoteException; }

Le paramètre source doit implémenter l’interface InputChannel ci dessous : public interface InputChannel extends Serializable{}

Le paramètre destinations correspond aux destinataires agréés.

La classe nommée InputString ci-dessous implémente cette interface public class InputString implements InputChannel{ private static int nextValue=1; private int hashVal; private String str; public InputString(String str){ this.str = str; this.hashVal = nextValue++; } public int hashCode(){ return this.hashVal;} public boolean equals(Object obj){ InputString i = (InputString)obj; return this.hashVal == i.hashVal; } public String toString(){return "InputString : " + str;} }

La Classe associée au message reçu et diffusé est la suivante public class Message implements Serializable{ private InputChannel source; private String message; public Message(InputChannel source,String message){ this.source = source; this.message = message; } public InputChannel getSource(){ return this.source;} public String getMessage(){ return this.message;} public String toString(){return "";} }

NSY102-examen-juin-2007

4/14

Le patron (RecipientList), comme les receveurs (Receiver A,B,C,D) sont des services RMI.

rmi:

rmi :

Receiver

A*

B* * C* UnTest

D* * rmiregistry port 1099

Complétez les classes demandées en respectant les interfaces fournies et l’architecture suggérée : Question2-1) 2 points Proposez une réalisation possible pour la classe Receiver, par exemple, un affichage sur la console du message reçu est suffisant. public class Receiver /* …*/

implements Channel{

??? }

Question2-2) 5 points Complétez la classe RecipientListImpl. Cette classe maintient une liste de destinataires pour chaque source, (addRoute). L’envoi du message (sendMessage ) aux receveurs agréés, préalablement inscrits par l’appel de la méthode addRoute, utilise un « Thread » interne à cette classe.

public class RecipientListImpl /* …*/

implements RecipientList{

??? ???

private class RouterWorkThread implements Runnable{ ??? }

} Question2-3) 2 points Complétez cet extrait de la classe UnTest afin de reproduire le schéma ci-dessus : soit une instance du Patron classe RecipientList, et 4 receveurs (classe Receiver A, B, C, D). NSY102-examen-juin-2007

5/14

InputChannel in = new InputString("in"); Message message = new Message(in, “test”);

La création et l’initialisation d’un message correspondent à ces deux lignes

Question2-4) 1 point La classe InputString redéfinit les méthodes hashCode et equals , Pourquoi ?

Question3 (5 points) : un « Chat » avec JMS Question3-1) 1 point Le patron Publish-Subscribe semble approprié pourquoi ?

Client_1

Client_2

JMS Server

Client_3

Question3-2) 4 points Complétez la classe « ClientChatJMS », dont une instance représente un des clients du logiciel de causerie. Votre classe doit utiliser L’API Java Message Service (cf. certaines interfaces sont en annexe). public class ChatJMS implements ??? { ???

public ClientChatJMS() throws Exception { // Obtain a JNDI connection Hashtable props = new Hashtable(); props.put(Context.INITIAL_CONTEXT_FACTORY, "org.exolab.jms.jndi.InitialContextFactory"); props.put(Context.PROVIDER_URL, "tcp://localhost:3035/"); InitialContext jndi = new InitialContext(props); // Look up a JMS connection factory TopicConnectionFactory conFactory = (TopicConnectionFactory) jndi.lookup("JmsTopicConnectionFactory"); // Create a JMS connection

NSY102-examen-juin-2007

6/14

connection = conFactory.createTopicConnection(); Topic chatTopic = (Topic) jndi.lookup("chat");

??? ??? ???

// Start the JMS connection; allows messages to be delivered connection.start(); }

/* Close the JMS connection */ public void close() throws JMSException { connection.close(); }

public static void main(String[] args) { try { ClientChatJMS chat = new ClientChatJMS(); // Read from command line BufferedReader commandLine = new java.io.BufferedReader( new InputStreamReader(System.in));

while (true) { String s = commandLine.readLine(); if (s.equalsIgnoreCase("exit")) { chat.close(); System.exit(0); } else { chat.writeMessage(s); } } } catch (Exception e) {e.printStackTrace();}}

NSY102-examen-juin-2007

7/14

Annexes java.lang

Interface Iterable public interface Iterable

Implementing this interface allows an object to be the target of the "foreach" statement.

Method Summary Iterator iterator()

Returns an iterator over a set of elements of type T.

Method Detail iterator Iterator iterator()

Returns an iterator over a set of elements of type T. Returns: an Iterator.

java.util

Interface List partielle All Superinterfaces: Collection, Iterable public interface List extends Collection

Method Summary boolean add(E e)

Appends the specified element to the end of this list (optional operation). void add(int index, E element)

Inserts the specified element at the specified position in this list (optional operation). void clear()

Removes all of the elements from this list (optional operation). boolean contains(Object o) Returns true if this

list contains the specified element.

boolean equals(Object o)

NSY102-examen-juin-2007

8/14

Compares the specified object with this list for equality. E get(int index)

Returns the element at the specified position in this list. int hashCode()

Returns the hash code value for this list. boolean isEmpty()

Returns true if this list contains no elements. Iterator iterator()

Returns an iterator over the elements in this list in proper sequence. boolean remove(Object o)

Removes the first occurrence of the specified element from this list, if it is present (optional operation). E set(int index, E element)

Replaces the element at the specified position in this list with the specified element (optional operation). int size()

Returns the number of elements in this list.

java.util

Interface Map partielle Type Parameters: K - the type of keys maintained by this map V - the type of mapped values All Known Subinterfaces: SortedMap All Known Implementing Classes: HashMap, Hashtable TreeMap, WeakHashMap public interface Map

An object that maps keys to values. A map cannot contain duplicate keys; each key can map to at most one value.

Method Summary void clear()

Removes all of the mappings from this map (optional operation). boolean containsKey(Object key) Returns true if this map

contains a mapping for the specified key.

boolean containsValue(Object value) Returns true if this map maps

one or more keys to the specified

value. boolean equals(Object o)

Compares the specified object with this map for equality.

NSY102-examen-juin-2007

9/14

V get(Object key)

Returns the value to which the specified key is mapped, or null if this map contains no mapping for the key. int hashCode()

Returns the hash code value for this map. boolean isEmpty()

Returns true if this map contains no key-value mappings. Set keySet()

Returns a Set view of the keys contained in this map. V put(K key, V value)

Associates the specified value with the specified key in this map (optional operation). V remove(Object key)

Removes the mapping for a key from this map if it is present (optional operation). int size()

Returns the number of key-value mappings in this map.

javax.jms

Interface MessageListener public interface MessageListener A MessageListener object is used to receive asynchronously delivered messages. Each session must insure that it passes messages serially to the listener. This means that a listener assigned to one or more consumers of the same session can assume that the onMessage method is not called with the next message until the session has completed the last call.

Method Summary void

onMessage(Message message) Passes a message to the listener.

javax.jms

Interface Session Partielle All Superinterfaces: java.lang.Runnable All Known Subinterfaces: QueueSession, TopicSession, XAQueueSession, XASession, XATopicSession

NSY102-examen-juin-2007

10/14

public interface Session extends java.lang.Runnable A Session object is a single-threaded context for producing and consuming messages. Although it may allocate provider resources outside the Java virtual machine (JVM), it is considered a lightweight JMS object.

Field Summary static int AUTO_ACKNOWLEDGE

With this acknowledgment mode, the session automatically acknowledges a client's receipt of a message either when the session has successfully returned from a call to receive or when the message listener the session has called to process the message successfully returns. static int CLIENT_ACKNOWLEDGE

With this acknowledgment mode, the client acknowledges a consumed message by calling the message's acknowledge method. static int DUPS_OK_ACKNOWLEDGE

This acknowledgment mode instructs the session to lazily acknowledge the delivery of messages.

Method Summary void close()

Closes the session. void commit()

Commits all messages done in this transaction and releases any locks currently held. ObjectMessage createObjectMessage(java.io.Serializable object) Creates an initialized ObjectMessage object. TextMessage createTextMessage() Creates a TextMessage

object.

TextMessage createTextMessage(java.lang.String text) Creates an initialized TextMessage object. void setMessageListener(MessageListener listener)

Sets the session's distinguished message listener (optional).

javax.jms

Interface TopicSession All Superinterfaces:

NSY102-examen-juin-2007

11/14

java.lang.Runnable, Session public interface TopicSession extends Session A TopicSession object provides methods for creating TopicPublisher, TopicSubscriber, and TemporaryTopic objects. It also provides a method for deleting its client's durable subscribers.

Method Summary TopicSubscriber createDurableSubscriber(Topic topic, java.lang.String name)

Creates a durable subscriber to the specified topic. TopicSubscriber createDurableSubscriber(Topic topic, java.lang.String name, java.lang.String messageSelector, boolean noLocal)

Creates a durable subscriber to the specified topic, using a message selector or specifying whether messages published by its own connection should be delivered to it. TopicPublisher createPublisher(Topic topic)

Creates a publisher for the specified topic. TopicSubscriber createSubscriber(Topic topic)

Creates a nondurable subscriber to the specified topic. TopicSubscriber createSubscriber(Topic topic, java.lang.String messageSelector, boolean noLocal)

Creates a nondurable subscriber to the specified topic, using a message selector or specifying whether messages published by its own connection should be delivered to it. TemporaryTopic createTemporaryTopic() Creates a TemporaryTopic

object.

Topic createTopic(java.lang.String topicName) Creates a topic identity given a Topic name. void unsubscribe(java.lang.String name)

Unsubscribes a durable subscription that has been created by a client.

Methods inherited from interface javax.jms.Session close, commit, createBytesMessage, createMapMessage, createMessage, createObjectMessage, createObjectMessage, createStreamMessage, createTextMessage, createTextMessage, getMessageListener, getTransacted, recover, rollback, run, setMessageListener

javax.jms

Interface TopicPublisher NSY102-examen-juin-2007

12/14

All Superinterfaces: MessageProducer public interface TopicPublisher extends MessageProducer A client uses a TopicPublisher object to publish messages on a topic. A TopicPublisher object See Also: TopicSession.createPublisher(Topic)

Method Summary Topic getTopic() Gets the topic associated with this TopicPublisher. void

publish(Message message) Publishes a message to the topic.

void

publish(Message message, int deliveryMode, int priority, long timeToLive) Publishes a message to the topic, specifying delivery mode, priority, and time to live.

void

publish(Topic topic, Message message) Publishes a message to a topic for an unidentified message producer.

void

publish(Topic topic, Message message, int deliveryMode, int priority, long timeToLive)

Publishes a message to a topic for an unidentified message producer, specifying delivery mode, priority and time to live.

Interface TopicSubscriber All Superinterfaces: MessageConsumer public interface TopicSubscriber extends MessageConsumer A client uses a TopicSubscriber object to receive messages that have been published to a topic. A

Method Summary boolean

getNoLocal() Gets the NoLocal attribute for this subscriber.

Topic getTopic() Gets the Topic associated with this subscriber.

NSY102-examen-juin-2007

13/14

javax.jms

Interface TextMessage All Superinterfaces: Message public interface TextMessage extends Message A TextMessage object is used to send a message containing a java.lang.String. It inherits from the Message interface and adds a text message body. See Also: Session.createTextMessage(), Session.createTextMessage(String), BytesMessage, MapMessage, Message, ObjectMessage, StreamMessage, String Fields inherited from interface javax.jms.Message DEFAULT_DELIVERY_MODE, DEFAULT_PRIORITY, DEFAULT_TIME_TO_LIVE

Method Summary java.lang.String getText()

Gets the string containing this message's data. void setText(java.lang.String string)

Sets the string containing this message's data.

Methods inherited from interface javax.jms.Message acknowledge, clearBody, clearProperties, getBooleanProperty, getByteProperty, getDoubleProperty, getFloatProperty, getIntProperty, getJMSCorrelationID, getJMSCorrelationIDAsBytes, getJMSDeliveryMode, getJMSDestination, getJMSExpiration, getJMSMessageID, getJMSPriority, getJMSRedelivered, getJMSReplyTo, getJMSTimestamp, getJMSType, getLongProperty, getObjectProperty, getPropertyNames, getShortProperty, getStringProperty, propertyExists, setBooleanProperty, setByteProperty, setDoubleProperty, setFloatProperty, setIntProperty, setJMSCorrelationID, setJMSCorrelationIDAsBytes, setJMSDeliveryMode, setJMSDestination, setJMSExpiration, setJMSMessageID, setJMSPriority, setJMSRedelivered, setJMSReplyTo, setJMSTimestamp, setJMSType, setLongProperty, setObjectProperty, setShortProperty, setStringProperty

NSY102-examen-juin-2007

14/14