Visualizzazione post con etichetta JMS e MDB. Mostra tutti i post
Visualizzazione post con etichetta JMS e MDB. Mostra tutti i post

domenica 25 dicembre 2011

Esempio utilizzo MDB

Nel seguente esempio proviamo a :
  • Definire una coda JMS su Jboss 5.1;
  • Realizzare un programma client java che scriva sulla coda dei messaggi;
  • Realizzare un Message Driven Bean che legga il messaggio e lo tolga dalla coda JMS.
DEFINIRE CODA JMS

Sotto la directory default deploy creare una directory denominata code dove andremo a definire la nostra coda JMS.

A questo punto dalla console di amministrazione di Jboss (utenza e pwd di default sono admin admin).




Cliccando su Add a new Resource e seguendo il menu definiamo il nome della coda "MiaCoda" e il JNDI name "code/MiaCoda".
Una volta terminata la procedura possiamo verificare il corretto funzionamento guardando sotto la directory deploy/code, troveremo il file xml MiaCoda-service.xml.

DEFINIRE CLIENT JAVA

Definiamo un semplice progetto Java su eclipse, inserendo nel classpath tutte le librerie presenti nella directory client di Jboss.

Il codice nel main del programma è il seguente:

import java.util.Properties;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.MessageProducer;
import javax.jms.Queue;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.naming.Context;
import javax.naming.InitialContext;

public class MessageSender {

   
   
    public static void main(String[] args) throws Exception{
        ConnectionFactory connectionFactory;
        Destination destination;
        Properties p=new Properties();
        p.put(Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory");
        p.put(Context.URL_PKG_PREFIXES, "org.jboss.naming:org.jnp.interfaces");
        p.put(Context.PROVIDER_URL, "jnp://127.0.0.1:1099");
        Context ctx=new InitialContext(p);
        connectionFactory=(ConnectionFactory)ctx.lookup("/ConnectionFactory");
        destination=(Queue)ctx.lookup("/code/MiaCoda");
        System.out.println("La coda e la connessione sono stati recuperati");
        Connection connection=null;
        connection=connectionFactory.createConnection();
        Session session=connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        MessageProducer mp=session.createProducer(destination);
         TextMessage msg = session.createTextMessage();
          for (int i = 0; i < 5; i++) {
          msg.setText("Questo è il messaggio " + (i + 1));
          mp.send(msg);
          }
          connection.close();
          System.out.println("Messaggi inviati correttamente");
         
    }
   
}


Vengono scritti e inviati 5 messaggi.
Se proviamo ad eseguire il programma con Jboss acceso vediamo che da Console ci compare il seguente messaggio:

La coda e la connessione sono stati recuperati
Messaggi inviati correttamente


Quindi andando sulla console di amministrazione di Jboss in corrispondenza della coda "MiaCoda" troviamo:

Vediamo che risultano 0 consumer (nessuno ha letto i messaggi, non essendoci ancora l'MDB) e 5 messaggi presenti nella coda.




DEFINIRE IL MESSAGE DRIVEN BEAN

L' MDB ha il compito di connettersi alla coda e leggere i messaggi presenti.
Per realizzarlo creiamo un progetto Java inserendo nel classpath le librerie client di Jboss 5.1.
Per definire l'MDB annotiamo la classe con @MessageDriven, mentre la classe deve implementare l'interfaccia MessageListener (del package javax.jms).
Da notare la definizione dell'elemento activationConfig dove si specifica il tipo di Destination (in questo caso una coda) e il nome della coda ("code/MiaCoda").

Il codice è il seguente:

import javax.annotation.Resource;
import javax.ejb.ActivationConfigProperty;
import javax.ejb.MessageDriven;
import javax.ejb.MessageDrivenContext;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;

@MessageDriven(name="MessageBean",
activationConfig= {
        @ActivationConfigProperty(propertyName="destinationType",
                                    propertyValue="javax.jms.Queue"),
        @ActivationConfigProperty(propertyName="destination",
                                    propertyValue="code/MiaCoda")
                  }
        )

public class MessageBean implements MessageListener {
    @Resource
       private MessageDrivenContext mdc;

     
       public void onMessage(Message msg) {
         TextMessage tmsg = null;

       try
       {
             tmsg = (TextMessage) msg;
             System.out.println("MESSAGE BEAN: Messaggio ricevuto: " + tmsg.getText( ));
             System.out.println ("Metodo onMessage() richiamato");
       }
       catch (JMSException e) {
                               e.printStackTrace( );
                               mdc.setRollbackOnly( );
                              }
      catch (Throwable th)    {
                              th.printStackTrace();
                              }
       }
     
}


Una volta fatto ciò possiamo esportare il progetto come jar file all'interno della directory deploy di JBoss.

Una volta deployato subito si nota sulla console di Jboss che i messaggi messi nella coda sono stati consumati dall'MDB:


13:06:53,945 INFO  [STDOUT] MESSAGE BEAN: Messaggio ricevuto: Questo è il messaggio 2
13:06:53,945 INFO  [STDOUT] Metodo onMessage() richiamato
13:06:53,946 INFO  [STDOUT] MESSAGE BEAN: Messaggio ricevuto: Questo è il messaggio 3
13:06:53,946 INFO  [STDOUT] Metodo onMessage() richiamato
13:06:53,947 INFO  [STDOUT] MESSAGE BEAN: Messaggio ricevuto: Questo è il messaggio 1
13:06:53,947 INFO  [STDOUT] Metodo onMessage() richiamato
13:06:53,947 INFO  [STDOUT] MESSAGE BEAN: Messaggio ricevuto: Questo è il messaggio 4
13:06:53,948 INFO  [STDOUT] Metodo onMessage() richiamato
13:06:53,949 INFO  [STDOUT] MESSAGE BEAN: Messaggio ricevuto: Questo è il messaggio 5
13:06:53,950 INFO  [STDOUT] Metodo onMessage() richiamato


Andando sulla coda via console di amministrazione vediamo infatti che adesso il Campo Consumer count è pari a 1 mentre il Message Count a 0.
Tutti i messaggi sono stati letti quindi dall'MDB e la coda è stata svuotata.

SCRIVERE MESSAGGI SULLA CODA JMS VIA WEB APPLICATION

In questo caso realizziamo una semplice Web appplication con un form su cui si inserisce il messaggio in una textArea e si invia il tutto ad una servlet che si occupa di aggiungere il messaggio alla coda jms.
Si noti come in questo caso i riferimenti alla ConnectionFactory e alla Destination siano recuperati tramite l'annotazione @Resource e non tramite look up JNDI.

public class ScriviMessaggioSuCoda extends HttpServlet {
    private static final long serialVersionUID = 1L;
    @Resource(name="code/MiaCoda",mappedName="code/MiaCoda")
    private javax.jms.Destination codaTest;
    @Resource(name="ConnectionFactory",mappedName="ConnectionFactory")
    private javax.jms.ConnectionFactory connentionFactory;
    /**
     * @see HttpServlet#HttpServlet()
     */
    public ScriviMessaggioSuCoda() {
        super();
        // TODO Auto-generated constructor stub
    }

    /**
     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
        try
        {
        String messaggio=request.getParameter("txtMessage");
        Connection connection = connentionFactory.createConnection();
          connection=connentionFactory.createConnection();
        Session session=connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        MessageProducer mp=session.createProducer(codaTest);
        TextMessage msg = session.createTextMessage();
        msg.setText(messaggio);
        mp.send(msg);
        connection.close();
        System.out.println("Sending message");
        session.close ();
        PrintWriter wr=response.getWriter();
        wr.write("<b>Messaggio inviato</b>");
        wr.flush();
        }
        catch(Exception ex){
            ex.printStackTrace();
        }
         
       
    }

}