• Non ci sono risultati.

4.2 Piattaforma di Sviluppo e Componenti

4.2.1 Service Engine

I Service Engine (SE) sono componenti JBI che forniscono logica di in- tegrazione e di trasformazione verso altri componenti così come a loro volta possono utilizzare i servizi di altri SE. I SE sono in grado principalmente di integrare applicazioni/risorse Java-Based.

La struttura del pacchetto .jar che verrà installato sul Service Bus è molto semplice e consiste nei package Java contenenti i file .class e una directory META-INF che contiene il file di configurazione jbi.xml.

La funzione del file di configurazione è quella di indicare le classi che implementano le interfacce obbligatorie del container JBI.

Le interfacce sono tre e si occupano di gestire le fasi del ciclo di vita del componente: installazione, rimozione, avvio e spegnimento. Nel file jbi.xml vengono anche specificate le librerie condivise che il componente utilizza.

Più nel dettaglio la parte dei file .class va impacchettata in un .jar il cui nome deve essere specificato nel file jbi.xml.

4.2 Piattaforma di Sviluppo e Componenti 59

Figura 4.2: Struttura del componente

La figura 4.2 riguarda la struttura del primo Service Engine, che svolge la funzione di logging dei messaggi.

Gli altri due Service Engine rispettivamente RingTwoEngine e RingTh- reeEngine svolgono le funzioni di storing ed inoltro dei messaggi; ma la struttura è la medesima. Vediamo ora i due package fondamentali:

it.ditech.jbi.component : questo package contiene altri tre package nel-

l’ordine: common, service e utils.

Il primo contiene le quattro classi fondamentali che implementano le interfacce del container JBI che sono Bootstrap (implemetata nella classe BootstrapRingOne.java), per la gestione del boot del componen- te, ComponentLifeCycle (implemetata nella classe ComponentLifeCy- cleRingOne.java) che serve a gestire l’intero ciclo di vita del compo- nente, Component (implemetata nella classe ComponentRingOne.java) che serve a stabilire la struttura fondamentale ed infine l’interfaccia

RingOne.java) che svolge la funzione di definizione del servizio che il componente espone.

Il secondo packege contenuto in component è service, in questo pac- kage si trova una classe che implementa il descrittore del servizio del- l’engine.

Il package utils fornisce delle utiliy per la gestione dell’XML e del- la fase di scambio di messaggi tra l’engine in questione e gli altri componenti.

ringoneengine : questo è il package che estende le classi del package

it.ditech.jbi.component.common e che devono essere riportate nel

file jbi.xml. Le classi RingOneBootstrap.java, RingOneComponent.java e RingOneComponentLifeCycle.java estendono rispettivamente le clas- si BootstrapRingOne.java, ComponentRingOne.java e ComponentLife- CycleRingOne.java.

La classe ServiceRingOne.java è la classe in cui viene implementato il servizio vero e proprio ed attraverso i metodi della classe vengono richiamati i servizi. Per separare infrastruttura e logica abbiamo deciso di spostare quest’ultima all’interno di una libreria condivisa che verrà richiamata dall’interno di ogni engine.

Di seguito riportiamo un esempio del file jbi.xml, inerente al primo Service Engine.

1 <jbi v e r s i o n=" 1.0 " x m l n s=" h t t p :// j a v a . sun . com / xml / ns / jbi ">

2 <c o m p o n e n t t y p e=" service - e n g i n e ">

3 <i d e n t i f i c a t i o n>

4 <name> R i n g O n e E n g i n e </name>

5 <d e s c r i p t i o n> P r i m o E n g i n e d e l l a catena </d e s c r i p t i o n>

6 </i d e n t i f i c a t i o n>

7 <c o m p o n e n t-class-name> r i n g o n e e n g i n e . R i n g O n e C o m p o n e n t </c o m p o n e n t-class-name>

8 <c o m p o n e n t-class-path>

9 <path-element> c o m p o n e n t e . jar </path-element>

4.2 Piattaforma di Sviluppo e Componenti 61

11 <b o o t s t r a p-class-name> r i n g o n e e n g i n e . R i n g O n e B o o t s t r a p </b o o t s t r a p-class-name>

12 <b o o t s t r a p-class-path>

13 <path-element> c o m p o n e n t e . jar </path-element>

14 </b o o t s t r a p-class-path>

15 <shared-library> ditech - ejb - l i b r a r i e s </shared-library>

16 </c o m p o n e n t>

17 </jbi>

Listing 4.1: jbi.xml

Come si può notare il file riporta le informazioni necessarie per il deploy e l’installazione del componente, in particolare indica dove si trova la clas- se che implementa l’interfaccia javax.jbi.component.Bootstrap e l’interfaccia javax.jbi.component.ComponentLifeCycle.

Le altre informazioni riguardano il nome del componente e le librerie utilizzate da quest’ultimo.

L’ultimo aspetto che andremo a trattare per i Service Engine riguarda lo scambio di messaggi con altri componenti. Lo scambio dei messaggi viene de- finito nello standard JBI e vengono implementati diversi pattern di scambio; nel nostro caso è stato usato il pattern InOut, che implementa una comuni- cazione bloccante sincrona. Di seguito il codice Java del metodo utilizzato

nella classe RingOneMessageHandlerper l’inoltro dei messaggi:

1 p u b l i c s t a t i c S t r i n g d o I n O u t M e s s a g e E x c h a n g e ( L o n g id , R i n g O n e C o m p o n e n t L i f e C y c l e c o m p R i n g ) t h r o w s E x c e p t i o n { 2 3 S t r i n g r e s u l t = " "; 4 c h a n n e l = c o m p R i n g . g e t D e l i v e r y C h a n n e l () ; 5 S e r v i c e E n d p o i n t s e r v i c e E n d p o i n t = f i n d S e r v i c e E n d p o i n t ( c o m p R i n g ) ; 6 if ( s e r v i c e E n d p o i n t == n u l l) { 7 c o m p R i n g . g e t L o g g e r () . i n f o (" [ d o I n O u t M e s s a g e E x c h a n g e ]: Il p r i m o S e r v i c e E n g i n e non ha t r o v a t o n e s s u n S e r v i c e E n d p o i n t a t t i v o per ") ; 8 } 9 Q N a m e o p e r a t i o n = new Q N a m e (" h t t p :// www . d i t e c h . it / jbi / t e s i / s a n t i / r o b e r t o ", " s t e p T w o O p e r a t i o n " ) ; 10 I n O u t i n O u t M e = c r e a t e I n O u t M e s s a g e E x c h a n g e ( o p e r a t i o n , s e r v i c e E n d p o i n t , c o m p R i n g , c h a n n e l ) ; 11 // S e t t a un NM sul c a n a l e 12 N o r m a l i z e d M e s s a g e i n M s g = i n O u t M e . c r e a t e M e s s a g e () ; 13 // S e t t a il c o n t e n u t o del m e s s a g g i o 14 i n M s g . s e t C o n t e n t (n u l l) ; 15 S t r i n g i d e n t i f i c a t o r e = S t r i n g . v a l u e O f ( id ) ; 16 i n M s g . a d d A t t a c h m e n t (" a l l e g a t o ", new D a t a H a n d l e r ( i d e n t i f i c a t o r e , " t e x t / p l a i n ") ) ; 17 // i n v i a il m e s s a g g i o al S e r v i c e E n g i n e S u c c e s s i v o 18 i n O u t M e . s e t I n M e s s a g e ( i n M s g ) ; 19 if ( c h a n n e l . s e n d S y n c ( inOutMe , R i n g O n e C o m p o n e n t L i f e C y c l e . S E N D _ S Y N C _ T I M E O U T ) ) { 20 L o g g e r . g e t L o g g e r (" R i n g O n e M e s s a g e H a n d l e r ") . log ( L e v e l . INFO , " I N O L T R O E S E G U I T O C O R R E T T A M E N T E ") ; 21 }

22 E x c h a n g e S t a t u s s t a t u s = i n O u t M e . g e t S t a t u s () ; 23 if ( E x c h a n g e S t a t u s . E R R O R . e q u a l s ( s t a t u s ) ) { 24 t h r o w new E x c e p t i o n (" [ d o I n O u t M e s s a g e E x c h a n g e ]: E r r o r e di c o m u n i c a z i o n e tra il p r i m o e il s e c o n d o S e r v i c e E n g i n e ") ; 25 } 26 // R e c u p e r a la r i s p o s t a 27 N o r m a l i z e d M e s s a g e o u t M s g = i n O u t M e . g e t O u t M e s s a g e () ; 28 D a t a H a n d l e r dh = o u t M s g . g e t A t t a c h m e n t (" r e s u l t ") ; 29 r e s u l t = ( S t r i n g ) dh . g e t C o n t e n t () ; 30 dh = n u l l; 31 32 if ( i n O u t M e . g e t S t a t u s () . e q u a l s ( E x c h a n g e S t a t u s . E R R O R ) ) { 33 i n O u t M e = n u l l; 34 i n M s g = n u l l; 35 o u t M s g = n u l l; 36 r e s u l t = " E R R O R "; 37 38 } e l s e { 39 i n O u t M e . s e t S t a t u s ( E x c h a n g e S t a t u s . D O N E ) ; 40 i n O u t M e = n u l l; 41 i n M s g = n u l l; 42 o u t M s g = n u l l; 43 } 44 r e t u r n r e s u l t ; 45 } Listing 4.2: message.java

Le righe di codice più significative sono la riga 10, la riga 19, la riga 27 e la riga 39. Alla riga si 10 utilizza il metodo createInOutMessageExchange per ottenere un oggetto MessageExchange il responsabile dello scambio dei messaggi. Tale oggetto viene creato a partire dal nome dell’operazione da invocare sull’altro componente, dal canale aperto verso il componente destinazione del messaggio e dal ServiceEndpoint ovvero l’endpoint del Service Engine ricevente.

Alla riga 19 sull’oggetto MessageExchange viene richiamato il metodo sendSync che inoltra il messaggio1 e restituisce un boolean in base all’esito dell’inoltro.

Se l’esito è false il metodo termina con errore, altrimenti continua dalla riga 27. Con il metodo getOutMessage() viene recuperata la risposta del componente remoto. In ultimo alla riga 39 viene settato lo stato del MessageExchange a DONE ovvero lo scambio è terminato correttamente. A questo punto il metodo termina con esito positivo.

Per fare una maggiore chiarezza possiamo vedere di seguito una rappresenta- zione dello scambio di messaggi basato sul pattern InOut.

1Il metodo inoltra il messaggio in modalità sincrona e utilizza un intervallo in ms per

la sincronizzazione. Se entro quell’intervallo non è giunta nessuna risposta viene sollevata un’eccezione di time out e viene retituito un false

4.2 Piattaforma di Sviluppo e Componenti 63

Figura 4.3: Message Exchange Pattern InOut

Ogni frammento XML ricevuto da un qualsiasi Binding Component viene adat- tato al formato Normalized Message ed inoltrato ad altri componenti, non diretta- mente bensì attraverso un componente infrastrutturale del container JBI il Message Normalized Router (Figura 4.4).

Documenti correlati