Documentazione Contatti      
Documentazione > Tutorial > SIB: IBM WebSphere System Integration Bus
Hide
Best Practices
EJB
Frameworks
Howto
J2EE
J2ME and Wireless
J2SE
JSP e Servlet
Java Application Server
Java IDE/Tools
Java Media
Java Security
Java Sys Admin
Java e XML
Java e SQL
OpenSource Java
Patterns
Repository
Tesi
UML
Web Services
Slide
White Paper di jws.it
project management
Eventi
Groovy



Lo Story board di Google Chrome


Un giorno le macchine riusciranno...
a risolvere tutti i problemi, ma mai nessuna di esse potra' porne uno. Einstein


MQSQL - Driver JDBC



  Visualizza Commenti (0) Aggiungi Commento    
 
SIB: IBM WebSphere System Integration Bus
By Gabriele A. Rigamonti
18 settembre 2007

  SIB: IBM WebSphere System Integration Bus
Program Gli Strumenti e la Preparazione dell’ambiente
Program Esempio Applicativo : Sistema Elaborazione Ordini
Program Modulo di Elaborazione
Program Modulo di Mediazione
Program Modulo Client (inserimento ordini)
Program Conclusioni e Risorse

WebSphere Application Server dalla versione 6.0 (ora siamo alla 6.1) è caratterizzato dalla presenza di un nuovo 'message engine' scritto completamente in java;questo sistema di messaggistica consolida il supporto per la gestione delle code del publish/subscribe e dei web services. E'  stato  anche  introdotto il concetto di 'integration bus' ovvero uno strato software , totalmente integrato all'interno di WebSphere,che permette in modo semplice e sicuro, di utilizzare diversi protocolli (JMS,SOAP,HTTP) per ricevere e scambiare messaggi.

Mediante l'utilizzo del bus i consumatori e i produttori di messaggi sono completamente svincolati, sia per quanto riguarda il protocollo di trasmissione, sia per quanto riguarda il formato del messaggio. Questa indipendenza (dei protocollo e dei formati) viene realizzata utilizzando uno standard comune per la rappresentazione dei messaggi all'interno del bus.

Le nuove funzionalità di integrazione , introdotte dalla 6.0 sono:

Bus
E’ lo strato ‘logico’ che viene interposto tra produttori e consumatori  che  prende il nome di: System Integration Bus (SIB)  esso garantisce anche un ottimo livello di qualità del servizio e scalabilità,e' possibile infatti distribuire il bus su più processori e macchine.

Destinazioni
Una destinazione rappresenta un punto di transito per ogni messaggio inserito nel bus;puo' essere una coda un topic oppure  rappresentare il punto di ingresso (inbound) o di uscita (outbound) di un servizio web.

Mediazioni
Le mediazioni permettono di dotare le destinazioni di 'logica' e sono implementate mediante  degli handler  indipendenti dal protocollo utilizzato (JMS,SOAP,MQ).Questo è posibile grazie alla trasformazione dei messaggi in modo automatico all’interno del bus in un formato ‘protocol neutral’.
Con le mediazioni è possibile trasformare un messaggio da un formato ad un altro (protocol switch)   (es da JMS a SOAP) ed  eseguire delle logiche di ‘routing dinamico’.

Da questa breve introduzione appare chiaro che WebSphere e' equipaggiato per poter lavorare sfruttando le potenzialità del concetto di Enterprise Service Bus che rappresenta un cardine dell'architettura SOA.

Fai il download  di ApplicazioneSIB.zip, l'applicazione usata per gli esempi di questo articolo.  



Gli Strumenti e la Preparazione dell’ambiente top

Gli strumenti necessari per questo tutorial sono l’application server WebSpehere Application Server 6.0 o superiore (trial download)  e come ambiente di sviluppo RAD 7.0 (trial download) oppure l’Application Server Toolkit (ASTK).



Per prima cosa è necessario impostare tutte le componenti dell’application server necessarie per l’infrastruttura di messaggistica.Questa fase deve essere eseguita utilizzando la console operativa che risponde ad un URL del tipo: http://ipmacchina:9060/admin.

Per ragioni di praticità le singole configurazioni da apportare sono descritte in formato tabellare:

Creazione Bus e registrazione del membro
 Creazione Bus  Integrazione servizi >bus  inserire OrdiniBus (non attivare la sicurezza)>Avanti>Fine>Salva
 Membri del Bus  Integrazione servizi >bus>
OrdiniBus>Membri del Bus
 Aggiungi>Server>Avanti>Fine>Salva

Creazione delle Destinazioni e della Mediazione
 Destinazioni  Integrazione servizi >bus>
OrdiniBus>Destinazioni
Nuovo>Coda>Avanti>ItaliaDestination>Avanti>Fine>Salva
Nuovo>Coda>Avanti>EsteroDestination>Avanti>Fine>Salva
 Mediazioni  Integrazione servizi >bus>
OrdiniBus>Mediazioni
 Nuovo>Nome Mediazione=RoutingMediation,Elenco gestori= RoutingMediation >OK>Salva

 
Definizione proprietà di contesto sulla mediazione
 Mediazioni
(Proprietà Contesto)
Integrazione servizi >bus>
OrdiniBus>Mediazioni>
RoutingMediation
Proprietà Contesto>Nuovo>Nome=DestinationPerEstero,Tipo contesto=String,Valore Contesto= EsteroDestination>OK>Salva 


Binding della mediazione con la destinazione

 Associamo
la mediazione alla destinazione

 Integrazione servizi >bus>
OrdiniBus>Destinazioni
 Selezionare ItaliaDestination>Esegui mediazione>RoutingMediation >Avanti>Fine>Salva


Definizione componenti per messaggistica JMS
Ambito server 
 
 JMS Connection Factory Risorse>JMS>Provider JMS Default Message Provider>Produzione di connessioni Nuovo>Nome=OrdiniCF,jndi=jms/OrdiniCF,Nome bus=OrdiniBus>OK>Salva
 Queue Risorse>JMS>Provider JMS Default Message Provider>Code Nuovo>Nome= ItaliaQueue,jndi=jms/ ItaliaQueue,Nome bus=OrdiniBus,Nome coda/destinazione=ItaliaDestination>OK>Salva

  Nuovo>Nome= EsteroQueue,jndi=jms/ EsteroQueue,Nome bus=OrdiniBus,Nome coda/destinazione=EsteroDestination>OK>Salva
  Activation Risorse>JMS>Provider JMS Default Message Provider>specifiche di attivazione Nuovo>Nome= AttivaItalia,jndi=eis/AttivaItalia,jnd destinazione=jms/ItaliaQueue,Nome bus=OrdiniBus>OK>Salva
   Nuovo>Nome=AttivaEstero,jndi=eis/AttivaEstero,jndi destinazione=jms/EsteroQueue,Nome bus=OrdiniBus>OK>Salva


 



Esempio Applicativo : Sistema Elaborazione Ordini top
Supponiamo di voler simulare un sistema per l’elaborazione ordini (Fig. 1) all’interno del quale quest'ultimi vengono inviati (all’interno di un messaggio) ad una destinazione (ItaliaDestination) associata alla coda (ItaliaQueue) ,avente appunto il compito di ricevere gli ordini destinati al mercato italiano.

Legata a  questa destinazione, è stata definita una mediazione (RoutingMediation) il cui scopo è quello di controllare (analizzando il contenuto del messaggio) se si tratta di un ordine ‘estero’ ed in caso positivo,sempre la mediazione, eseguirà il routing  dinamico indirizzando le informazioni verso la nuova destinazione (EsteroDestination)  che rappresenta nel bus la coda (EsteroQueue).
Una volta che gli ordini sono stati smistati verso le loro code di competenza verranno elaborati dai relativi MDB (Message Driver Bean).

messaggi validi:

        ITALIA_ORDN=150_ARTICOLO=126_QTA=12_PRZ=88.23

        ESTERO_ORDN=18_ARTICOLO=45_QTA=1_PRZ=456,00

messaggi non validi

        ITA_ORDN=41_ARTICOLO=145_QTA=2_PRZ=51.21 (manca ITALIA/ESTERO)

        ITALIAESTERO_ORDN=18_ARTICOLO=45_QTA=1_PRZ=456,00 (ITALIA ESTERO entrambi presenti)


 

Figura 1 - Componenti di messaggistica utilizzati per la gestione ordini.

 

Modulo di Elaborazione top
L’applicazione in dettaglio.
Il progetto che andremo a realizzare è scomponibile in tre unità indipendenti:

•    Modulo di Elaborazione

•    Modulo di Mediazione

•    Modulo Client


Modulo Elaborazione
e’ composto da una applicazione Enterprise (ProcessaOrdiniEAR)  contenente al suo interno un modulo EJB (ProcessaOrdiniEJB) nel quale vengono definiti i due MDB responsabili della gestione finale dell’ordine.
Il binding dei due  MDB sulle code di input (in breve dove ascoltano i messaggi in arrivo)  e’ realizzato sfruttando i Resource Adapter  definiti nella specifica Java Connector Architecture (JCA) 1.5 .
L'impostazione dell'adapter avviene mediante l’utilizzo di una specifica di attivazione che deve essere definita dall’amministratore. (Fig.2)

 


Figura 2 - Specifica di attivazione


Modulo di Mediazione top
Il modulo di Mediazione e’ composto anche’sso da un applicazione Enterprise  (MediazioneOrdiniEAR) che contiene il modulo EJB (MediazioneOrdiniEJB.
Ogni mediazione deve implementare l’interfaccia: MediationHandler che definisce il metodo:
 
public boolean handle(MessageContext arg0) throws MessageContextException

Non appena il messaggio arriva alla destinazione il metodo handle viene invocato dal ‘mediation framework’ e riceve in input un oggetto (che implementa l’interfaccia MessageContext )  dal quale è possibile recuperare la struttura del messaggio ed i valori impostati a livello di configurazione.
Il metodo handle ritorna un valore booleano che assume il seguente significato: se true allora il messaggio viene inoltrato verso la destinazione successiva (forward routine path) se presente, altrimenti viene consumato;in caso contrario: false il messaggio viene cancellato dalla destinazione.

package routing;


import commonj.sdo.DataObject;

public class OrdiniRoutingMediation implements MediationHandler {

    private static final String  _descrizioneErrore_1="Formato messaggio errato!";
  private static final String  _descrizioneErrore_2="Ordine scartato ! , non si tratta di un ordine italia/estero";
    private static final String  _descrizioneErrore_3="Ordine scartato ! , deve essere italia/estero non entrambi";
    private static final String  _descrizioneErrore_4="Destinazione Errata, controllare la configurazione!";
    private static final String  _info="Messaggio arrivato alla mediazione : ";
   
1    public boolean handle(MessageContext arg0) throws MessageContextException {       
2        boolean inoltra=true;
3        boolean italia=false;
4        boolean estero=false;
5        SIMessageContext sim = (SIMessageContext) arg0;
6        SIMessage message = sim.getSIMessage();
7        try {
8            if (message.getFormat().equals("JMS:text")) {               
9                DataGraph dataGraph = message.getDataGraph();
10                DataObject root = dataGraph.getRootObject();
11                DataObject jmsMessage = root.getDataObject("data");
12                String ordineBody = jmsMessage.getString("value");               
13                    if (ordineBody.indexOf("ITALIA") != -1) italia=true;   
14                    if (ordineBody.indexOf("ESTERO") != -1) estero=true;
15                    if ( italia && estero) {               
16                                                                  inoltra=false;
17                        logMessage(_descrizioneErrore_3);
18                    }                           
19                    if ( ! (italia | estero)) {
20                        inoltra=false;
21                        logMessage(_descrizioneErrore_2);
22                    }
23                if (estero){
24                    String destinazioneEstero=getContextProperty(sim,"DestinazionePerEstero"
25                    if (destinazioneEstero != null ){   
26                        makeRouting(sim,destinazioneEstero);       
27                    }else {
28                        inoltra=false;   
29                        this.logMessage(_descrizioneErrore_4);           
30                    }                               
31                }               
32            } else {       
33                inoltra=false;
34                logMessage(_descrizioneErrore_1);           
35            }   
36        } catch (SIException ex) {
37            inoltra=false;
38            logMessage(ex.getStackTrace().toString());
39        }       
40        return inoltra;
41    }
42
43    /*
44    * esegue un routing verso una nuova destinazione
45    */
46    private void makeRouting(SIMessageContext msgCtx,String destination) {
47
48        String busName = msgCtx.getSession().getBusName();
49        SIMessage message = msgCtx.getSIMessage();
50        List frp = message.getForwardRoutingPath();
51
52        SIDestinationAddressFactory factory = SIDestinationAddressFactory
53                .getInstance();
54        SIDestinationAddress newAddress = factory.createSIDestinationAddress(
55                destination, busName);
56       
57        frp.add(newAddress);
58        message.setForwardRoutingPath(frp);
59    }
60    /*
61    * ritorna il valore della context property associata alla destinazione
62    */
63    private String getContextProperty(SIMessageContext msgCtx,String property) {       
64        String prop=null;
65        if (property !=null) {   
66            prop=(String)msgCtx.getProperty(property);
67        }   
68        return prop;
69    }   
70    private void logMessage(String msg){
71        System.out.println(getClass().getName() + " "+msg);
72    }
73   }

Analizziamo i punti più importanti del codice della mediazione.

 5-6 viene estratto un oggetto di tipo SIMessageContext che fornisce un riferimento ad un oggetto di tipo SIMessage
 8 controlla se il messaggio sulla destinazione e’ stato generato da un producer di tipo JMS
 9-12 a partire dalla rappresentazione in formato SDO (System Data Object) viene recuperato il corpo del messaggio
inviato (es: ITALIA_ORDN=150_ARTICOLO=126_QTA=12_PRZ=88.23 )
 13-22 verifica se l’header contiene ITALIA/ESTERO
 23-31 Se l’header e’ riferito ad un ordine estero viene recuperato il nome della destinazione sulla quale eseguire il
routing (24).
Se il valore recuperato e’ valido viene eseguito il routing vero e proprio verso la nuova destinazione (26)
 40 valore di ritorno della mediazione: in caso di successo (true)  e di destinazione italia il messaggio viene mandato
alla coda ItaliaQueue e successivamente consumato da ItaliaMDB.
Nel caso di ordine estero, il messaggio viaggia verso la destinazione (EsteroDestination) e poi verso la coda EsteroQueue e successivamente consumato da EsteroMDB.
In caso si errore (false)  il messaggio viene eliminato dalla destinazione.
 46-59 Esegue il routing verso la nuova destinazione.Recupera la sessione e da essa il nome del bus (48).
Modfica il ‘forward routing path’ , ovvero la lista delle destinazioni da attraversare (50-58)
 63-69 Determina il nome della destinazione andando a leggere la ‘Context Property’ associata alla mediazione con nome
“DestinazionePerEstero” (24).
Questo evita di inserire nomi di destinazioni direttamente nel codice.


Una mediazione viene 'impacchettata' in una applicazione Enterprise mediante di un modulo EJB  sotto forma di Stateless Bean;vediamo come procedere per ottenere questo risultato: apriamo il descrittore di distribuzione (dell'applicazione EJB) spostiamoci nel punto 'gestore di mediazioni'  (Fig. 4)  ed inseriamo il riferimento alla nostra mediazione .

 

Figura 4 – Selezione della handler class


Nel nostro caso specifico è stata inserita solamente una handler class (Sequence 1) ma e' possibile creare una 'catena' di mediazioni ognuna delle quali verrà invocata in sequenza. (Fig.5)

 

Figura 5 – Handler class

 

Modulo Client (inserimento ordini) top
L'applicazione Enterprise (AlimentaOrdiniEAR) contiene al suo interno il modulo web (AlimentaOrdiniWeb) che definisce una servlet utilizzata per simulare l'immissione di un ordine (Fig. 6) .



Figura 6 – Inserimento di un ordine

Codice della Servlet
package ordini;

import java.io.IOException;
import java.io.PrintWriter;
import javax.jms.Connection;
import javax.jms.DeliveryMode;
import javax.jms.Destination;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.naming.InitialContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


public class OrdiniServlet extends javax.servlet.http.HttpServlet implements
javax.servlet.Servlet {
   
    private final static String CFJNDI = "jms/OrdiniCF";
   
    private final static String QUEUE_IT = "jms/ItaliaQueue";
   
    public OrdiniServlet() {
        super();
    }
   
    protected void doGet(HttpServletRequest request,
            HttpServletResponse response) throws ServletException, IOException {
        immetiOrdineDaElaborare(request, response);
        renderOrdine(request, response);
    }

    protected void doPost(HttpServletRequest request,
            HttpServletResponse response) throws ServletException, IOException {
        immetiOrdineDaElaborare(request, response);
        renderOrdine(request, response);
    }
   
    protected void immetiOrdineDaElaborare(HttpServletRequest request,
            HttpServletResponse response) throws ServletException, IOException {
       
        Connection connection = null;
        Session session = null;
        MessageProducer queueSender = null;
        try {
            InitialContext initCtx = new InitialContext();
           
            javax.jms.ConnectionFactory qcf = (javax.jms.ConnectionFactory) initCtx
            .lookup(CFJNDI);
           
            Destination q = (Destination) initCtx.lookup(QUEUE_IT);
           
            connection = qcf.createConnection();
           
            session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
           
            queueSender = session.createProducer(q);
            TextMessage outMessage = session.createTextMessage();
           
            String ordineInArrivo = request.getParameter("ordine");
           
            outMessage.setText(ordineInArrivo);
           
            outMessage.setJMSDestination(q);
            queueSender.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
            queueSender.send(outMessage);
            System.out.println("Ordine consegnato!");
        } catch (Exception ex) {
            ex.printStackTrace();
        } finally {
            if (connection != null) {
                try {
                    session.close();
                    queueSender.close();
                    connection.close();
                } catch (Exception ex) {       
                }       
            }       
        }   
    }
    private void renderOrdine(HttpServletRequest request, HttpServletResponse response)   throws IOException{
       
        response.setContentType("text/html; charset=ISO-8859-1");
        response.setContentType("text/html");
        PrintWriter out = response.getWriter();
        out.println("<html>");
        out.println("<head>");
        out.println("Messaggio inviato : ");
        out.println("</head>");
        out.println("<body>");
        out.println(request.getParameter("ordine"));
        out.println("</body>");
        out.println("</html>");
       
    }
}

Output di SystemOut.log :

[30/07/07 10.10.23:375 CEST] 00000036 SystemOut     O Ordine consegnato!
[30/07/07 10.10.23:421 CEST] 0000003b SystemOut     O routing.OrdiniRoutingMediation Messaggio arrivato alla mediazione : RoutingMediation contenuto ESTERO_ORDN=1200_ARTICOLO=232_QTA=1_PRZ=213.89
[30/07/07 10.10.23:500 CEST] 0000003e SystemOut     O Ordine Estero ricevuto :
  JMSMessage class: jms_text
  JMSType:          null
  JMSDeliveryMode:  1
  JMSExpiration:    0
  JMSPriority:      4
  JMSMessageID:     ID:75864c2f572bae8b98e7341d110a134f0000000000000001
  JMSTimestamp:     1185783023359
  JMSCorrelationID: null
  JMSDestination:   queue://ordiniDestination?busName=TutorialsBus
  JMSReplyTo:       null
  JMSRedelivered:   false
  JMSXUserID:
  JMS_IBM_System_MessageID: 1B54B66B3953B8C9_36500002
  JMSXAppID: Service Integration Bus
  JMSXDeliveryCount: 1
ESTERO_ORDN=1200_ARTICOLO=232_QTA=1_PRZ=213.89
[30/07/07 10.10.23:500 CEST] 0000003e SystemOut     O ......
[30/07/07 10.10.23:515 CEST] 0000003e SystemOut     O Ordine Estero elaborato!
 


Conclusioni e Risorse top
In questo tutorial abbiamo visto la potenza e la flessibilità del System Integration Bus di WebSphere sia per quanto riguarda le funzionalità di messaging , sia per quanto riguarda la creazione e l’utilizzo delle mediazioni.Il bus oltre che a gestire i classici messaggi JMS offre un supporto completo ed integrato ai WebServices.

Risorse

WebSphere Information Center

Service Data Object (SDO)

Developer Works

SibExplorer applicazione che permette di  ‘esplorare’  le varie componenti del bus mediante una interfaccia grafica.



 Attachments List
Generic DocumentApplicazioneSIB.zip



JavaPortal è ideato da:    
K-Tech Logo










LICENZA



Eccetto dove diversamente specificato, i contenuti di questo sito sono rilasciati sotto licenza Creative Commons

Sitemap  © 2002-2004 Copyright Information. Privacy . Today is sabato 19 giugno 2010