Sei sulla pagina 1di 63

Java Message Service

Java message service (JMS) è l’insieme di


API che consentono lo scambio di messaggi
tra applicazioni Java distribuite sulla rete
La prima specifica JMS è stata rilasciata nel
1998, mentre l’ultima versione delle API è la
1.1 pubblicata nel 2002
La specifica è scaricabile dal sito della sun:
http://java.sun.com/products/jms/

RUGGERO RUSSO 2
Messaggio
In ambito JMS, un messaggio è un
raggruppamento di dati che viene inviato da
un sistema ad un altro
I dati sono solitamente utilizzati per notificare
eventi e sono pensati per essere utilizzati da
un programma su una macchina e non
direttamente da un utente umano
In un scenario distribuito un messaging
service può essere pensato come un
sistema distribuito di notifica di eventi

RUGGERO RUSSO 3
Messaging System
Con il termine messaging ci si riferisce ad un
meccanismo che consente la comunicazione
asincrona tra client remoti:
Un client invia un messaggio ad un ricevente (o ad un
gruppo di riceventi)
Il destinatario riceve il messaggio ed esegue le operazioni
corrispondenti, in un secondo momento
In questo senso un sistema di messaggistica
differisce da RMI in cui il mittente di un messaggio
(per esempio il client che invoca un metodo remoto,
che deve attendere la risposta dal server che
espone il metodo prima di continuare)
RUGGERO RUSSO 4
Messaging System (2)
E’ basato su paradigma peer-to-peer: un client può
ricevere e spedire messaggi a qualsiasi altro client
attraverso un provider:
Ciascun client si connette all’agente (gestore) della
messaggistica che fornisce gli strumenti per creare,
spedire, ricevere e leggere messaggi
In questo senso si può definire come messaging
system ogni sistema che consente la trasmissione di
pacchetti TCP/IP tra programmi client
Permette una comunicazione distribuita del tipo
loosely coupled (debolmente accoppiata)
Il mittente ed il ricevente, per comunicare, non devono
essere disponibili allo stesso tempo
RUGGERO RUSSO 5
Messaging System (3)
Grazie all’intermediazione del messaging agent (o
server) i client che inviano/ricevono messaggi non
hanno bisogno di avere conoscenza reciproca delle
caratteristiche dell’altro per poter comunicare
Differisce dalla comunicazione tightly coupled, e.g.
quella usata nel Remote Method Invocation (RMI),
che richiede ad un’applicazione client di conoscere i
metodi esposti su di un’interfaccia remota da un
applicazione server
Tutto ciò che il mittente ed il ricevente devono
conoscere è il formato (message format) e la
destinazione (destination) del messaggio

RUGGERO RUSSO 6
Messaging System (4)
ORB Modello
ORB
(RMI)
CLIENT SERVER

Message system

destination
MODELLO
CLIENT SERVER MESSAGE
ORIENTED

RUGGERO RUSSO 7
JMS – Generalità
Permettono comunicazioni di tipo:
Asincrono: il JMS provider consegna i messaggi al client
appena quest’ultimo si sia reso disponibile. Il provider li
consegnerà senza che il receiver abbia effettuato una
richiesta specifica
Affidabile: JMS può assicurare che un messaggio sia
consegnato una ed una sola volta.
Ulteriori livelli di robustezza sono garantiti in JMS:
Tramite il cosiddetto Guaranteed Message Delivery è
possibile prevenire una perdita di informazioni in caso di
malfunzionamento o di crash del message server,
rendendo i messaggi persistenti prima di essere recapitati
ai consumatori (per esempio mediante JDBC)

RUGGERO RUSSO 8
JMS – Generalità (2)
JMS non include:
Un sistema di Load balancing/Fault Tolerance: la
API JMS non specifica un modo in cui diversi
client possano cooperare al fine di implementare
un unico servizio critico
Notifica degli Errori
Amministrazione: JMS non definisce dei metodi
per la gestione di prodotti di messaggistica
Security: JMS non prevede API per il controllo
della privacy e dell’integrità del messaggio

RUGGERO RUSSO 9
Relazioni di JMS con
Altre Java API
Java DataBase Connectivity (JDBC) Software: per
garantire l’interazione con Data Base in modo
indipendente rispetto alla tecnologia sottostante
JavaBeans components
Enterprise JavaBeans Components: nella specifica
EJB 2.0 si definisce una forma asincrona di utilizzo
dei bean che vengono invocati quando un client JMS
invia un messaggio JMS
Java Naming and Directory Interface (JNDI): API
che fornisce i servizi di naming e directory (per
associare nomi a dati)
RUGGERO RUSSO 10
Architettura JMS
JMS Client: programma che manda o riceve i
messaggi JMS
Messaggio: ogni applicazione definisce un insieme
di messaggi da utilizzare nello scambio di
informazioni tra due o più client
JMS provider: sistema di messaggistica che
implementa JMS e realizza delle funzionalità
aggiuntive per l’amministrazione e il controllo della
comunicazione attraverso messaggi
Administered objects: sono oggetti JMS
preconfiguarti, creati da un amministratore ad uso dei
client. Incapsulano la logica specifica del JMS
provider nascondendola ai client, garantendo
maggiore portabilità al sistema complessivo.
RUGGERO RUSSO 11
Administered Objects
Connection Factory: oggetto utilizzato da un client
per realizzare la connessione con il provider
Destination (queue/topic): oggetto utilizzato da un
client per specificare l’origine del messaggio che
riceve o la destinazione del messaggio che invia
Sono sono vendor dependent, nel senso che la loro
implementazione specifica dipende dal provider del
servizio di messaggistica
Non sono gestiti all’interno del programma Java:
La creazione di ConnectionFactory e di Destination è
compito dell’amministratore JMS che deve inserirli all’interno
di un contesto JNDI in un opportuno namespace in modo
che possano essere recuperati da qualsiasi client mediante
le normali API JNDI

RUGGERO RUSSO 12
Administered Objects
(2)
Le interfacce JMS consentono allo sviluppatore di
astrarsi dai dettagli implementativi permettendo il
riutilizzo del codice al variare dell’implementazione
Per inviare messaggi (sender/publisher) o per
riceverli (receiver/subscriber), un’applicazione JMS
client utilizza i servizi JNDI per ottenere un oggetto di
tipo ConnectionFactory e uno o più oggetti di tipo
Destination (Queue o Topic)
Il “Naming” in JMS è gestito dall’amministratore di
sistema e non dai client al contrario di quanto accade
in RMI in cui alcune funzioni (e.g., bind) sono
espletate direttamente da server e client

RUGGERO RUSSO 13
Architettura JMS (2)
JNDI Namespace
Administrative
tools Dest CF
bind

ok up
lo
JMS Client
Logical JMS Provider
connection

Gli AT associano (bind) agli oggetti destination e connection


factory un nome all’interno di un namespace attraverso le JNDI API
I client JMS ricercano gli administered object (lookup) ed
instaurano una connessione logica ad essi tramite un JMS Provider

RUGGERO RUSSO 14
Modelli di messaging
(domini)
Point-to-point:
più client JMS possono condividere la stessa
destination (queue)
Un messaggio può essere consumato da un solo
destinatario
Permette una comunicazione uno-a-uno
Publish/Subscribe:
Un messaggio inserito nella destinazione (topic)
può essere inviato a tutti i destinatari (subscriber)
che si sono dichiarati interessati a riceverlo
Consente una comunicazione uno-a-molti
RUGGERO RUSSO 15
Point-to-point domain
Il modello di messaggistica point-to-point (PTP o p2p)
si basa sul concetto di coda, mittente (sender o
producer) e destinatario (receiver o consumer)
Ogni client JMS spedisce e riceve messaggi sia in
modalità sincrona che in modalità asincrona,
mediante canali virtuali conosciuti come “queues”
(code)
E’ un modello di tipo “pull- or polling-based”, ovvero i
messaggi vengono richiesti (prelevati) dalle code
anziché essere consegnati ai client in maniera
automatica

RUGGERO RUSSO 16
Point-to-point domain
(2)
Il modello PTP ha le seguenti caratteristiche:
Più produttori e più consumatori possono condividere la
stessa coda, ma …
Ogni messaggio ha solamente un “consumer”, ovvero
ogni messaggio può essere letto da un solo client
Mittente e destinatario non hanno nessuna dipendenza
temporale
Il ricevente notifica l’avvenuta ricezione e
processemento del messaggio (acknowledge)
Utile quando è necessario garantire che un
messaggio arrivi ad un solo destinatario che notifica
la corretta ricezione
RUGGERO RUSSO 17
Point-to-point domain
(3)

CONSUMER

PRELEVA
PRODUCER
QUEUE CONSUMER
INVIA
NOTIFICA

RUGGERO RUSSO 18
Publish/Subscribe
domain
Nel modello publish/subscribe (pub/sub) il producer
può spedire un messaggio a molti consumers (One to
Many), attraverso un canale virtuale chiamato topic
Uno stesso topic può essere condiviso da più
consumer ed utilizzato da più publisher
Per ricevere i messaggi, i consumer devono
“sottoscriversi” ad un topic
Qualsiasi messaggio spedito al topic viene
consegnato a tutti i consumer sottoscritti, ciascuno
dei quali riceve una copia identica di ciascun
messaggio inviato al topic

RUGGERO RUSSO 19
Publish/Subscribe
domain (2)
E’ principalmente un modello “push-based”:
i messaggi vengono automaticamente inviati in
broadcast ai consumer, senza che questi ne
abbiano fatto esplicita richiesta
E’ previsto la possibilità di consegnare
messaggi provenienti da più publisher (multi
publishers)
Secondo il modello pub/sub non c’è
dipendenza tra il producer e i consumer:
E’ il JMS provider che realizza l’operazione di
dispatching dei messaggi a tutti i client sottoscritti
RUGGERO RUSSO 20
Publish/Subscribe
domain (3)
Il Publisher ed i subscribers hanno una dipendenza
temporale:
Un client che si sottoscrive ad un topic può consumare
solamente messaggi pubblicati dopo la sua sottoscrizione
Il subscriber può continuare a consumare messaggi solo nel
periodo in cui rimane attivo. Durante il periodo di inattività i
messaggi che dovesse ricevere andrebbero persi
Per ovviare al problema il client JMS può usare una
sottoscrizione durevole, che gli consente di
disconnettersi e riconnettersi in un secondo momento
consumando i messaggi pubblicati durante il periodo
di disconnessione

RUGGERO RUSSO 21
Publish/Subscribe
domain (4)
Un subscriber ha due modi per specificare i messaggi
che è interessato a ricevere:
tramite una stringa che ne indichi il nome (nel caso più
semplice)
per mezzo di condizione booleane sui suoi parametri
Il modello publish/subscribe prevede due tipi di
interazione:
topic-based: le informazioni vengono suddivise in
argomenti (topic o subject), le sottoscrizioni e le
pubblicazioni vengono fatte scegliendo come
discriminante un argomento e viene utilizzato un canale
logico ideale (topic) che connette un publisher ai
subscriber
content-based: utilizza dei filtri per una selezione più
accurata delle informazioni da ricevere
22
Publish/Subscribe
domain (5)

n a CONSUMER
eg
o ns
c
consegna
PRODUCER TOPIC
INVIA CONSUMER
sottoscrive
co
ns
eg
na
CONSUMER

RUGGERO RUSSO 23
Modalità di ricezione
Un messaggio JMS può essere consumato secondo
due modalità:
Modalità sincrona: il subscriber (o il receiver)
prelevano direttamente il messaggio dalla coda
(operazione di fetch del messaggio), tramite
l’invocazione del metodo receive(). Il metodo è
sospensivo, il client rimane bloccato finché non arriva
il messaggio o fino allo scadere di un timeout
Modalità asincrona: il client si registra presso un
message listener attraverso un oggetto consumer. Se
un messaggio arriva alla destinazione, il JMS provider
consegna il messaggio chiamando il metodo
“onMessage” del listener

24
Attori JMS
Administered Objects:
ConnectionFactory
Destination
Connection
Session
MessageProducer
Message
MessageConsumer
RUGGERO RUSSO 25
Connection Factory
E’ l’oggetto utilizzato dal client per realizzare una
connessione con il message server
Incapsula un insieme di parametri di configurazione definiti
dall’amministratore
Ogni oggetto connection factory è una istanza delle
interfacce:
ConnectionFactory
QueueConnectionFactory o TopicConnectionFactory
(dipendentemente dal dominio)
Per poter recuperare un riferimento ad un connection
factory, il client JMS deve eseguire all’inizio una operazione
di lookup JNDI dell’oggetto

RUGGERO RUSSO 26
Connection Factory (2)
Nel caso di dominio point-to-point si utilizza l’interfaccia
QueueConnectionFactory
Context ctx = new InitialContext();
QueueConnectionFactory queueConnectionFactory =
(QueueConnectionFactory)ctx.lookup("MyQueueConnectionFactory");

Context è l’intefaccia base per la specifica di un naming


context. Definisce le operazioni base e.g. aggiungere e
rimuovere un binding nome-oggetto, fare il lookup ad un
oggetto associato ad uno specifico nome, fare la lista dei
binding etc.
Si crea un oggetto di tipo context
Si ottiene il contesto specifico dell’applicazione (con il
casting a QueueConnectionFactory)
Si recupera il riferimento logico all’oggetto con il metodo
lookup

RUGGERO RUSSO 27
Connection Factory (3)

Nel caso di dominio publish/subscribe si


utilizza l’interfaccia
TopicConnectionFactory
Context ctx = new InitialContext();
TopicConnectionFactory topicConnectionFactory =
(TopicConnectionFactory)ctx.lookup("MyTopicConnectionFactory");

RUGGERO RUSSO 28
Destination
È l’administered object che rappresenta l’astrazione di
una particolare destinazione
Anche in questo caso il client identifica la destinazione
mediante l’utilizzo delle API JNDI
Nel caso point-to-point, la destinazione è
rappresentata dall’interfaccia Queue
Nel caso di publish/subscribe, si usa l’interfaccia Topic

In JBoss la definizioni delle destination e l’attribuzione di un nome


alle varie code utilizzabili è gestita “dall’amministratore
dell’applicazion server” utilizzando la console oppure creando e
modificando opportunamente il file miaCoda-service.xml
Inserire il file creato in <JBoss_HOME\server\default\deploy
(nella console di jboss appare RUGGERO RUSSO
la nuova coda) 29
miaCoda.service.xml
<server>
<mbean code="org.jboss.mq.server.jmx.Queue"
name="jboss.mq.destination:service=Queue,name=miaCoda">
<depends optional-attribute-name="DestinationManager">
jboss.mq:service=DestinationManager
</depends>
</mbean>
</server>

RUGGERO RUSSO 30
Lookup delle
Destination
Un message client deve ottenere il riferimento alla
Destinazione invocando il metodo lookup passando
come input il nome della coda precedentemente
creato ed assegnandolo alla opportuna destination
facendone il casting al tipo di destinazione utilizzato

Queue queue = (Queue) jndiContext.lookup(“miaCoda");


Topic topic = (Topic) jndiContext.lookup(“mioTopic");

RUGGERO RUSSO 31
Connection
Rappresenta l’astrazione di una connessione attiva di
un JMS client con uno specifico JMS provider
Caratteristiche:
Incapsula una connessione aperta con il JMS provider
Generalmente è rappresentata da un socket TCP/IP aperta
tra client e provider
Crea una session (attraverso la creazione di un Session
Object)
Supporta opzionalmente un ExceptionListener
Una connection implementa l’interfaccia
ConnectionFactory.
In generale i client JMS utilizzano una sola
connessione; ma in casi di applicazioni più avanzate è
possibile far uso di più connessioni (e.g., un client che
fa da gateway tra due JMS provider)
RUGGERO RUSSO 32
Connection (2)
Dopo aver fatto il lookup di una connection factory, è
possibile creare un oggetto di tipo Connection
point-to-point domain:
Si ottiene un reference d’interfaccia QueueConnection
invocando il metodo create QueueConnection
sull’oggetto ConnectionFactory:
QueueConnection queueConnection =
queueConnectionFactory.createQueueConnection();
publish/subscribe domain:
si ottiene un reference d’interfaccia TopicConnection
invocando il metodo createTopicConnection() sull’oggetto
ConnectionFactory:
TopicConnection topicConnection =
topicConnectionFactory.createTopicConnection();
33
Ciclo di vita delle
Connessioni
Setup:
Quando la connessione viene creata è inizialmente in modalità
stopped, in attesa che il setup sia concluso:
Nessun messaggio può essere ricevuto
Start:
La connessione viene lanciata invocando su un oggetto
Connection il metodo start()
I messaggi cominciano ad essere prodotti e consumati
Pausa:
La consegna di messaggi può essere temporaneamente interrotta
invocando il metodo stop()
L’invio di tutti i messaggi è interrotta indipendentemente dalla
modalità (sincrona, asincrona, tramite listener)
Chiusura:
La connessione è definitivamente chiusa tramite il metodo close()
Le risorse sono rilasciate
Non si prevede un meccanismo per gestire l’ultimo messaggio
Se ci sono listener attivi la connessione rimane aperta fino alla fine
del loro processamento 34
Session
Una session viene creata a partire dall’oggetto
Connection
E’ il canale di comunicazione con una destinazione
E’ contesto entro cui vengono creati i producer, i
consumer ed i messaggi stessi
Fornisce un modo per creare queue e topic
temporanei (non gestiti amministrativamente)
Specifica il tipo di comunicazione (con notifica o
meno)
Session session = connection.createSession(false,
Session.AUTO_ACKNOWLEDGE);
RUGGERO RUSSO 35
Message
Cositutito da:
Header (obbligatorio): contiene
informazioni sul messaggio
Property (opzionale): contiene
alcune proprietà opzionali del
messaggio solitamente utilizzate
per gestire la compatibilità tra
sistemi di messaggistica differenti.
I suoi campi sono esaminati dai
un consumer mediante i
message selectors
Body (opzionale): contiene la
parte informativa trasferita
all’interno del messaggio
36
Message Header
L'header del messaggio contiene un numero
predefinito di campi, i cui valori vengono utilizzati sia
dal client che dal provider JMS per identificare ed
instradare il messaggio
JMSMessageID è l’identificatore che rappresenta
univocamente il messaggio
JMSDestination è il campo in cui vengono specificati la
coda o il topic di destinazione al quale il messaggio è
stato spedito
JMSTimestamp indica l'istante in cui il messaggio è stato
lanciato
JMSExpiration individua il tempo massimo in cui il
messaggio può rimanere memorizzato in una coda
JMSPriority attribuisce valori di importanza differenti a
seconda del tipo e del contenuto del messaggio
I valori di ciascun campo dell'header sono impostati o
prelevati tramite metodi del tipo setXXX() e
37
getXXX().
Message - Header (2)
Header Field Set By
JMSDestination Metodi di send or publish
JMSDeliveryMode Metodi di send or publish
JMSExpiration Metodi di send or publish
JMSPriority Metodi di send or publish
JMSMessageID Metodi di send or publish
JMSTimestamp Metodi di send or publish
JMSCorrelationID Client
JMSReplyTo Client

JMSType Client

JMSRedelivered JMSD provider


38
Message Body
Il Body è la parte che veicola l'informazione del
messaggio. In generale un messaggio JMS può
essere di diversi tipi:
Text Message: messaggio testuale
Map Message :coppie nome/valore in cui il nome è una
stringa ed il valore è un tipo primitivo java
Byte Message :uno stream di bytes
Stream Message: uno stream di valori primitivi java
Object Message: un oggetto di tipo serializable
Message: costituito dai soli campi header e properties
Buona prassi: utilizzare dove possibile text
message, in cui il body del messaggio sia un file
xml contenente il contenuto informativo da
trasferire e informazioni accessorie di gestione
della comunicazione (e.g. allarm_JMS)
39
Message Body (2)
Un oggetto message viene creato per mezzo dei
metodi create<messageType>() forniti
dall’interfaccia session per la produzione di ogni
singola tipologia di messaggio.
e.g.: in un dominio point-to-point per creare un
messaggio di tipo TextMessage utilizziamo il
seguente codice:
TextMessage txtMsg = queueSession.createTextMessage();
txtMsg.setText(“Ciao!”);
producer.send(txtMsg);
Si invoca il metodo
[…] createTextMessage() su
un oggetto queueSession
specifico per il dominio ptp

40
Message Producer
Il MessageProducer è l’oggetto che ha il compito di
inviare messaggi ad una destination
Implementa l’interfaccia MessageProducer ed è
generato da un oggetto session attraverso il
metodo createProducer()passandogli come
input il nome logico della destination a cui il producer
deve inviare i messaggi
MessageProducer producer = session.createProducer(Mia_Coda);
MessageProducer producer = session.createProducer(Mio_Topic);

Specializzando il tipo di messageProducer si ha:


QueueSender sender = queueSession.createSender(Coda);
TopicPublisher publisher = topicSession.createPublisher(Topic);

41
Message Consumer
E’ l’oggetto che ha il compito di ricevere i messaggi
provenienti da una destination
Come nel caso precedente è necessario conoscere la
session e la destination per inizializzare un oggetto di
tipo messageConsumer:
queueReceiver receiver = queueSession.createReceiver(Coda);
topicSubscriber subscriber =
topicSession.createSubscriber(Topic);

MessageConsumer consumer = session.createConsumer(Mia_Coda);


MessageConsumer consumer = session.createConsumer(Mio_Topic);

42
Modalità Asincrona
E’ la modalità standard di trasmissione di messaggi
in JMS
Il messageProducer non è tenuto ad attendere che
il messaggio sia ricevuto per continuare il suo
funzionamento e non è previsto un meccanismo di
consumo sequenziale di messaggi
Per supportare il consumo asincrono dei messaggi,
viene utilizzato un oggetto listener che
implementa l’interfaccia MessageListener
Utilizza il metodo onMessage() per definire le
operazioni da effettuare all’arrivo di un messaggio
RUGGERO RUSSO 43
Message Listener
Passi:
Generazione dell’oggetto listener
TopicListener topicListener = new TextListener();
QeueListener queueListener = new TextListener();

Settare l’oggetto listener creato passandolo come


input al metodo setMessageListener
dell’oggetto Receiver

TopicSubscriber.setMessageListener(topicListener);
QueueReceiver.setMessageListener(queueListener);

RUGGERO RUSSO 44
Message Listener
Il listener dopo essere stato connesso si mette in
ascolto di un messaggio avviando la connessione
queueConnection.start();
topicConnection.start();

All’arrivo di un messaggio viene invocato il metodo


onMessage()
public class TextListener implements MessageListener {
public void onMessage(Message message) {
try {
if (message instanceof TextMessage) {
TextMessage txtMsg = (TextMessage) message;
System.out.println("Ricevuto: " + txtMsg.getText());
. . .
} 45
Modalità Sincrona
I prodotti di messaging sono intrinsecamente
asincroni ma un MessageConsumer può ricevere i
messaggi anche in modo sincrono
Il consumer richiede esplicitamente alla
destinazione di prelevare il messaggio (fetch)
invocando il metodo receive
Il metodo receive() appartiene all’interaccia
javax.jms.MessageConsumer ed è sospensivo,
cioè rimane bloccato fino alla ricezione del
messaggio, a meno che non si espliciti un timeout
finito il quale il metodo termina

RUGGERO RUSSO 46
Modalità Sincrona (2)
public Message receive() throws JMSException
public Message receive(long timeout) throws
JMSException
Esempio di ricezione sincrona: timeout
while(<condition>) {
Message m = queueReceiver.receive(1000);
if( (m!=null)&&(m instanceof TextMessage) {
message = (TextMessage) m;
System.out.println("Rx:" + message.getText());

Indipendentemente dalla modalità di ricezione la


comunicazione viene conclusa invocando un’operazione di
close() sulla connessione
queueConnection.close();
topicConnection.close();

RUGGERO RUSSO 47
Message Selector
Oggetti utilizzati per filtrare messaggi in arrivo,
permettendo ad un consumer di specificare quali
sono i messaggi di suo interesse sulla base delle
informazioni contenute all’interno dei campi
property del messaggio
Assegnano il lavoro di filtraggio al provider JMS
anziché all’applicazione
Il filtraggio avviene a livello di server e permette di
inoltrare ai client lungo la rete i messaggi strettamente
necessari o utili, risparmiando così la banda del canale
Un message selector è una oggetto di tipo String
che contiene un’espressione

RUGGERO RUSSO 48
Impostazione di Message
Selector
I metodi createConsumer() e
createDurableSubscriber() permettono di
specificare un message selector, attraverso un
opportuno argomento
topicSubscriber subscriber = topicSession.createSubscriber(Topic,
String messageSelector);

La selezione dei messaggi avviene solamente sui valori


contenuti negli headers o nelle properties del messaggio.
Nessuna selezione può esser fatta a livello di body del
messaggio da parte del provider JMS. Tale selezione
può esser fatta invece a livello di applicazione

RUGGERO RUSSO 49
Durable Subscriber
Guaranteed Message Delivery:
Modalità che consente di prevenire perdita di informazioni
in caso di malfunzionamento o crash del sistema di
messaging
E’ necessario rendere persistenti i messaggi inviati prima di
essere recapitati, utilizzando file o JDBC: metodologia
store-and-forward
Il meccanismo di store deve essere impostato e richiesto
dal client JMS mentre viene materialmente realizzato dal
provider JMS
Un topicSubscriber semplice, diversamente da un
queueReceiver può ricevere messaggi solo nel periodo di
tempo in cui rimane attivo

RUGGERO RUSSO 50
Durable Subscriber (2)
Per rendere un subscriber persistente (durable) è
necessario creare delle sottoscrizioni durevoli
(durable subscriptions) in grado di ricevere messaggi
anche se il subscriber non è all’ascolto al momento
della generazione del messaggio
La sottoscrizione persistente dura dall’istante di
tempo in cui viene creata con il comando
topicSession.createDurableSubscriber(Mi
o_topic, userName)
Fino all’istante in cui viene cancellata con il comando
topicSession.unsubscribe()
Ciascuna durable subscription può avere un solo
subscriber attivo per volta
RUGGERO RUSSO 51
Durable Subscriber (3)
La creazione della durable subcription richiede di definire
univocamente la sottoscrizione attraverso:
Un clientID che rappresenta univocamente la connessione
Un topic ed un nome che rappresenta l’identificativo del
subscriber
L’identificativo univoco associato al durable subscriber serve al
JMS server per memorizzare i messaggi arrivati mentre il
subscriber non è attivo.
Quando il subscriber si riconnette il JMS server provvede a
inviare tutti i messaggi ancora validi accumulati fino a quel
momento
JBoss crea un file
<JBoss_HOME/db/jbossmq/Topic.mioDurableTopic.idxy-
nome.dat0 in cui vengono memorizzati finoa 1000 messaggi in
attesa di essere consumati

RUGGERO RUSSO 52
Durable Subscriber (4)

M1 M2 M3

Legenda:
creazione di un subscriber chiusura di una sottoscrizione
creazione di un durable subscr. Unsubscribe durable subscr.
RUGGERO RUSSO 53
Durable Subscriber (5)

In t0 un subscriber ordinario ed uno durable vengono


creati
In t1 viene inviato un messaggio ricevuto da entrambi
In t2 entrambe le connessioni vengono chiuse
In t3 viene lanciato un nuovo messaggio che viene
perso per il subscr. ordinario e memorizzato per il
subscr. Persistente
In t4 i due ricevitori tornano attivi, il primo si metterà
in ascolto di un messaggio mentre il secondo riceve
M2 precedentemente memorizzato
In t6 entrambe le connessioni vengono chiuse
(notare l’operazione di unsubscribe nel caso durable)

RUGGERO RUSSO 54
ESEMPI

RUGGERO RUSSO 55
Point-to-point

Passo1: creazione degli administered objects


Creazione della queue editando il file xml
miaCoda-service.xml o utilizzando gli strumenti di
gestione di JBoss (all’indirizzo:
http://localhost:8080/jmx-
console/HtmlAdaptor?action=inspectMBean&nam
e=jboss.mq%3Aservice%3DDestinationManager)
Creazione delle connection factory editando il file
jndi.properties

RUGGERO RUSSO 56
miaCoda.service.xml
<server>
<mbean code="org.jboss.mq.server.jmx.Queue"
name="jboss.mq.destination:service=Queue,name=miaCoda">
<depends optional-attribute-name="DestinationManager">
jboss.mq:service=DestinationManager
</depends>
</mbean>
</server>

RUGGERO RUSSO 57
Jndi.properties
Modalita’ 1

#jboss jNDI properties


java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.provider.url=jnp://localhost:1099
java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces

Modalita’ 2:
inserire le istruzioni per la creazione dell’Administ. Object
direttamente nel codice della classe (vedi esempio)

RUGGERO RUSSO 58
Point-to-point
Passo2: compilare i file java Sender.java e
Receiver.java
Passo3: eseguire Sender e Receiver

NOTA: in macchine in cui non esiste JBoss è necessario utilizzare


alcuni jar aggiuntivi da inserire nel classpath (esempio javax.jms)
RUGGERO RUSSO 59
Point-to-point

Provare che:
1. Il messaggio resta memorizzato finché non c’è un
receiver che lo consuma
2. Se viene lanciato un receiver prima che un
messaggio sia inviato, quello si mette in ascolto
della coda in attesa di un messaggio
3. Se due receiver sono contemporaneamente attivi
solo uno riceverà effettivamente il messaggio

RUGGERO RUSSO 60
Pub/Sub domain
Passo1: creazione degli administered objects
Creazione della queue editando il file xml mioTopic-
service.xml o utilizzando gli strumenti di gestione di
JBoss (all’indirizzo: http://localhost:8080/jmx-
console/HtmlAdaptor?action=inspectMBean&name=jb
oss.mq%3Aservice%3DDestinationManager)
Creazione delle connection factory editando il file
jndi.properties

RUGGERO RUSSO 61
mioTopic.service.xml
<server>
<mbean code="org.jboss.mq.server.jmx.Topic"
name="jboss.mq.destination:service=Topic,name=incendio">
<depends optional-attribute-name="DestinationManager">
jboss.mq:service=DestinationManager</depends>
</mbean>
</server>

RUGGERO RUSSO 62
Pub/Sub
Passo2: compilare i file java Publisher.java e
Subscriber.java
Passo3: eseguire Publisher e Subscriber

NOTA: in macchine in cui non esiste JBoss è necessario utilizzare


alcuni jar aggiuntivi da inserire nel classpath (esempio javax.jms)
RUGGERO RUSSO 63
Pub/Sub

Provare che:
1. I subscriber cominciano a ricevere messaggi dal
momento in cui sono attivi
2. Se nessun subscriber è attivo il messaggio viene
perso
3. I messaggi vengono inviati a tutti i subscriber attivi
e in ascolto sul topic specifico
4. Provare il funzionamento di messaggi inviati su
topic differenti
5. Provare il funzionamento dei selectors di subscriber
iscritti allo stesso topic
RUGGERO RUSSO 64

Potrebbero piacerti anche