Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial
  • Lezione 13 di 68
  • livello ninja
Indice lezioni

Message Driven Bean

Message driven beans: scopriamo come gestire comunicazioni asincrone tra lato client e server di un'applicazione utilizzando l'esempio pratico di un e-commerce.
Message driven beans: scopriamo come gestire comunicazioni asincrone tra lato client e server di un'applicazione utilizzando l'esempio pratico di un e-commerce.
Link copiato negli appunti

JMS: Publish and subscribe e Point to point

Nella piattaforma JEE, JMS (Java Message Service) è un'API che fornisce un'interfaccia standard per i sistemi MOM (Message Oriented Middleware).
Un MOM è un sistema che consente lo scambio di messaggi in modo asincrono. Avere un'interfaccia standard per l'accesso ad un qualsiasi MOM consente lo sviluppo di applicazioni portabili, asincrone, orientate ai messaggi. Con JMS abbiamo a disposizione due possibili modelli di messaggi:

  1. Publish and subscribe
  2. Point to point

Comprendere questi modelli è estremamente importante per poter utilizzare architetture che usano di Message Driven Bean. In entrambi i modelli la struttura fondamentale è il canale virtuale sul quale arrivano i messaggi. Nel caso di modello Publish and subscribe il canale viene denominato Topic, ed un producer (applicativo trasmittente) invia messaggi ai consumer (riceventi) in modalità broadcast.

I consumer scelgono di registrarsi ad una particolare Topic e ricevono le notifiche di messaggi senza effettuare alcun polling. Un singolo messaggio viene inviato a tutti i subscriber. Un subscriber non perde un messaggio se inattivo, la registrazione infatti può essere configurata come durevole, consentendo ai subscriber di disconnettersi e riconnettersi senza perdite.

Nel modello Point to point il canale viene chiamato Queue e il funzionamento è differente. Infatti in questo caso i consumer devono effettuare polling sulla Queue e un messaggio verrà consumato da un solo consumer.

In un application server come JBoss Wildfly, possiamo definire canali Topic e Queue e avere bean EJB registrati su di essi per realizzare dei consumer. Questi bean vengono chiamati Message Driven Bean. Un MDB condivide due caratteristiche con i Session Bean Stateless: non mantiene uno stato conversazionale e l'application server
ne crea e gestisce un pool di istanze.

Quando arriva un messaggio su Topic o Queue a cui l'MDB è registrato, onMessage() viene invocato dal Container; all'interno del metodo possiamo poi accedere al messaggio ed eseguire la logica.

Un esempio pratico: l'e-commerce

Supponiamo di gestire un sito Web per grossisti di abbigliamento sviluppato in JEE 7 e che un qualsiasi negoziante possa registrarsi ed effettuare ordini attraverso di esso. Il business del grossista si espande in quanto alcuni clienti, che a loro volta fanno e-commerce, chiedono di effettuare dai loro sistemi ordini diretti al sistema JEE 7, gestendo cosi i casi in cui un utente acquista un prodotto non immediatamente disponibile.

Ipotizziamo inoltre che i sistemi siano realizzati con tecnologie eterogenee. Per poter far fronte a questo requisito decidiamo di utilizzare JMS configurando una Queue sull'application server in grado di ricevere ordini (ad esempio in formato XML) da sistemi esterni. Realizziamo contestualmente degli MDB che processino gli ordini registrandoli sul sistema JEE 7.

Prima di addentrarci nel codice è bene comprendere come configurare una Queue o Topic su JBoss Wildfly. Nella directory standalone\configuration della home directory di JBoss Wildfly, troviamo vari XML il cui nome inizia per "standalone", questi file rappresentano diverse configurazioni di JBoss con singola istanza server (nessun Cluster). Possiamo avviare JBoss specificando uno di questi file.

Nella tab "Servers" di JBoss Developer Studio apriamo le proprietà dell'istanza di JBoss configurata in installazione, selezioniamo il link "Runtime Environment" e scegliamo standalone-full.xml invece di standalone.xml:

Figura 1. JBoss Developer Studio 9.1.0 Configurazione JBoss.
JBoss Developer Studio 9.1.0 Configurazione JBoss

Editiamo standalone-full.xml con un qualsiasi editor ed individuiamo la parte che riguarda JMS:

Figura 2. Direttive JMS in standalone-full.xml.
Direttive JMS in standalone-full.xml

Questa porzione del file di configurazione mostra diverse connection factory e canali Queue. Possiamo utilizzare le connection factory esistenti aggiungendo una Queue, ShippingQueue; per completezza se avessimo voluto aggiungere una Topic avremmo inserito nelle destination:

<jms-topic name="ShippingTopic">
     <entry name="java:jboss/exported/jms/topic/ShippingTopic"/>
   </jms-topic>

Nel progetto ProgettoEjb1 creiamo il package it.html.progetto1.mdb.ejb32 e al suo interno una classe che implementa l'MDB per la ricezione di un ordine:

package it.html.progetto1.mdb.ejb32;
import javax.ejb.ActivationConfigProperty;
import javax.ejb.MessageDriven;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;
@MessageDriven(
		name="ShippingProcessor",
		activationConfig={
				@ActivationConfigProperty(
						propertyName="destinationType",
						propertyValue="javax.jms.Queue"),
				@ActivationConfigProperty(
						propertyName="destinationLookup",
						propertyValue="java:jboss/exported/jms/queue/ShippingQueue")
		}
)
public class ShippingProcessor implements MessageListener {
	@Override
	public void onMessage(Message msg) {
		TextMessage order = (TextMessage)msg;
		try {
			System.out.println(order.getText());
		} catch (JMSException e) {
			e.printStackTrace();
		}
	}
}

L'annotation @MessageDriven permette di marcare la classe come MDB, all'interno di esso
utilizziamo l'annotation @ActivationConfigProperty per definire il canale (Queue o Topic) e la destinazione, ovvero il JNDI name che identifica il canale definito in standalone-full-xml.

Un MDB deve implementare l'interfaccia javax.jms.MessageListener che definisce diversi metodi tra cui onMessage() invocato dal Container sull'evento di ricezione di un messaggio. Un messaggio JMS è costituito da una parte relativa agli headers, una relativa alle properties e, infine, la parte relativa al body. Nel nostro esempio abbiamo utilizzato soltanto il body specificando un messaggio di tipo testuale.

In realtà il body può contenere diverse tipologie di messaggi come, ad esempio, javax.jms.ObjectMessage nel caso di invio di un oggetto relativo ad una classe (come per la nostra classe personalizzata Order).

Ti consigliamo anche