(Italiano) Liferay 7: Come realizzare un client SOAP con Apache CXF in OSGi Style

Sorry, this entry is only available in Italiano.

L'argomento integrazione è il mio forte e per questo primo mio vero articolo su Liferay 7 ho deciso di trattare l'argomento Web Services dal punto di vista del consumer. Senza dubbio scrivere su questa tematica significa aprire tanti altri punti da approfondire e magari  con i prossimi articoli.

Qualcuno di voi chiederà a se stesso: ma esistono ancora e sono utilizzati i Web Services SOAP? La risposta è affermativa, continuate quindi la lettura.

1. Qual'è lo scenario e l'obiettivo

Immaginate il caso che dal vostro portale Liferay abbiate la necessità di dover integrare i dati dei vostri utenti con informazioni provenienti dal vostro sistema di CRM (Customer Relationship Management). Il sistema di CRM espone l'accesso ai propri dati attraverso un interfaccia SOAP, occorre quindi realizzare un client che risiederà sul Liferay 7 e che consenta l'interazione con il CRM.

Figura 1 - Scenario d'integrazione Liferay 7 e CRM via SOAP

Figura 1 - Scenario d'integrazione Liferay 7 e CRM via SOAP

Immaginato lo scenario (mostrato in Figura 1), l'obiettivo di questo articolo è quello di mostrare step-by-step quali sono i componenti che andranno installati sul Liferay 7 e come ad alto livello è composta l'applicazione che realizza il colloquio via SOAP con il sistema di CRM all'interno del contesto OSGi di Liferay.

Figura 2 - Dettaglio dello scenario d'integrazione tra Liferay 7 e il sistema di CRM

Figura 2 - Dettaglio dello scenario d'integrazione tra Liferay 7 e il sistema di CRM

Il diagramma di Figura 2 mostra il dettaglio dello scenario e in particolare la composizione dell'applicazione CRM Application che consta di tre moduli e il noto framework Apache CXF che sarà il nostro punto di riferimento per quel che riguarda il supporto ai Web Service SOAP.

L'applicazione CRM Application è stata già realizzata e disponibile sul Repository OSGi e Liferay 7  creato in occasione del primo Liferay User Group Italiano a Bologna #LRBO16. Sul repository git l'applicazione CRM Application corrisponde al modulo webservices-client.

2. Requisiti

Per seguire in modo efficace il contenuto di questo articolo è necessario avere: una conoscenza base di Liferay 7 e OSGi e la disponibilità dentro la vostra "borsa degli attrezzi" questi pezzi:

  1. Liferay 7.0.1 Community Edition GA2 (installata e in esecuzione) consigliato il bundle basato su tomcat
  2. Git Tools
  3. Gradle (versione >= 2.12)
  4. Telnet (come installare su Windows, sui sistemi *nix o Unix-like non serve installazione)
  5. Liferay IDE 3.0.1 GA2 (opzionale)
  6. Text Editor (opzionale)
  7. Apache CXF 3.1.6 (opzionale)

Il primo elemento e l'ultimo sono gli unici requisiti necessari per l'esecuzione dell'applicazione CRM Application.

Per i novizi di Liferay 7 consiglio la lettura della presentazione OSGi e Liferay 7 che io (@antonio_musarra) e Jader Francia (@JedJds) abbiamo discusso al primo Liferay User Group Italiano a Bologna #LRBO16.

3. Installazione del framework Apache CXF

Apache CXF è in genere il punto di riferimento come framework per quel che riguarda i Web Services. L'applicazione CRM Application adotta Apache CXF come framework a supporto dello sviluppo del client SOAP, è quindi indispensabile installare sull'istanza Liferay 7 alcuni dei componenti del framework affinché l'applicazione sia in grado di funzionare.

Liferay 7 supporta gli standard JAX-WS e JAX-RS tramite l'adozione del framework Apache CXF (versione 3.0.3) che esporta in parte tramite il bundle che si chiama Liferay Portal Remote CXF Common, e per vostra curiosità potreste vedere il file bnd dove sono evidenti gli Export-Package di Apache CXF. Nulla vieta quindi l'utilizzo del bundle di Liferay che esporta Apache CXF, preferisco però essere indipendente da Liferay per due motivi:

  • utilizzare una versione diversa del framework e possibilmente l'ultima, in questo caso la versione 3.1.6, Liferay uilizza la vecchia versione 3.0.3. OSGi consente tutto ciò in modo semplice e agevole.
  • Liferay 7 non esporta e non utilizza tutto lo stack offerto da Apache CXF, come per esempio la parte di WS-Security, WS-Policy, etc..

Per maggiorni approfondimenti consiglio la lettura del documento Liferay SOAP e REST Extender pubblicato sulla LDN.

Ricordate che siamo in ambiente OSGi? Bene, installare Apache CXF significa eseguire l'installazione dei bundle all'interno di Apache Felix che ricordo essere il container OSGi scelto dal Liferay.

Per il tipo di client SOAP da realizzare, i bundle di Apache CXF (versione 3.1.6) da installare sono:

L'installazione dei nove elementi del framework di Apache CXF può essere eseguita connettendosi via telnet alla Apache Felix GoGo Shell. Accertato che il portale Liferay 7 sia in esecuzione, l'installazione del framework Apache CXF può avvenire eseguendo i comandi mostrati a seguire.

$ telnet localhost 11311
g! install https://repository.apache.org/content/repositories/releases/org/apache/ws/xmlschema/xmlschema-core/2.2.1/xmlschema-core-2.2.1.jar
g! install https://repository.apache.org/content/repositories/releases/org/apache/cxf/cxf-core/3.1.6/cxf-core-3.1.6.jar
g! install https://repository.apache.org/content/repositories/releases/org/apache/cxf/cxf-rt-databinding-jaxb/3.1.6/cxf-rt-databinding-jaxb-3.1.6.jar
g! install https://repository.apache.org/content/repositories/releases/org/apache/cxf/cxf-rt-bindings-xml/3.1.6/cxf-rt-bindings-xml-3.1.6.jar
g! install https://repository.apache.org/content/repositories/releases/org/apache/cxf/cxf-rt-bindings-soap/3.1.6/cxf-rt-bindings-soap-3.1.6.jar
g! install https://repository.apache.org/content/repositories/releases/org/apache/cxf/cxf-rt-wsdl/3.1.6/cxf-rt-wsdl-3.1.6.jar
g! install https://repository.apache.org/content/repositories/releases/org/apache/cxf/cxf-rt-frontend-simple/3.1.6/cxf-rt-frontend-simple-3.1.6.jar
g! install https://repository.apache.org/content/repositories/releases/org/apache/cxf/cxf-rt-frontend-jaxws/3.1.6/cxf-rt-frontend-jaxws-3.1.6.jar
g! install https://repository.apache.org/content/repositories/releases/org/apache/cxf/cxf-rt-transports-http/3.1.6/cxf-rt-transports-http-3.1.6.jar

Il comando install esegue l'installazione dei bundle su Apache Felix. Il comando install accetta come parametro una URI e personalmente preferisco installare i bundle prelevando gli stessi dal repository maven di Apache, ecco perché ho specificato la URL per ogni bundle da installare. E' possibile scaricare prima i bundle e poi eseguire l'installazione specificando come URI file:///$ABSOLUTE_PATH_BUNDLE_FILE

I bundle che sono stati installati sono tutti nello stato Installed e il comando sulla gogo shell mostrato a seguire fa vedere lo stato dei bundle appena installati.

g! lb|grep -e "Xml|Apache CXF"
  479|Installed   |    1|XmlSchema Core (2.2.1)
  480|Installed   |    1|Apache CXF Core (3.1.6)
  481|Installed   |    1|Apache CXF Runtime JAXB DataBinding (3.1.6)
  482|Installed   |    1|Apache CXF Runtime XML Binding (3.1.6)
  483|Installed   |    1|Apache CXF Runtime SOAP Binding (3.1.6)
  484|Installed   |    1|Apache CXF Runtime Core for WSDL (3.1.6)
  485|Installed   |    1|Apache CXF Runtime Simple Frontend (3.1.6)
  486|Installed   |    1|Apache CXF Runtime JAX-WS Frontend (3.1.6)
  487|Installed   |    1|Apache CXF Runtime HTTP Transport (3.1.6)

Con ben in mente il ciclo di vita delle applicazioni in ambiente OSGi mostrato nella presentazione OSGi e Liferay 7 (e che riporto in Figura 3), l'obiettivo è quello di avere tutti i bundle nello stato Active.

Figura 3 - Life cycle dei bundle in OSGi

Figura 3 - Life cycle dei bundle in OSGi

Il bundle XmlSchema Core è quello da cui dipende il bundle Apache CXF Core, il primo step è quindi quello di avviare lo starting del bundle XmlSchema Core utilizzando il comando start $idBundle$, così come mostrato a seguire.

g! start 479
g! lb|grep -e "XmlSchema|Apache CXF"

  479|Active     |    1|XmlSchema Core (2.2.1)
  480|Starting   |    1|Apache CXF Core (3.1.6)
  481|Starting   |    1|Apache CXF Runtime JAXB DataBinding (3.1.6)
  482|Starting   |    1|Apache CXF Runtime XML Binding (3.1.6)
  483|Starting   |    1|Apache CXF Runtime SOAP Binding (3.1.6)
  484|Starting   |    1|Apache CXF Runtime Core for WSDL (3.1.6)
  485|Starting   |    1|Apache CXF Runtime Simple Frontend (3.1.6)
  486|Starting   |    1|Apache CXF Runtime JAX-WS Frontend (3.1.6)
  487|Starting   |    1|Apache CXF Runtime HTTP Transport (3.1.6)<em>&nbsp;</em>

Dopo l'esecuzione del comando start per il bundle XmlSchema Core, tutti i bundle Apache CXF sono passati nello stato Starting. Questo stato è dovuto al fatto che i bundle di Apache CXF hanno dichiarato nel proprio Manifest File (MANIFEST.MF) una policy di attivazione del bundle impostata a lazy, questo vuol dire che il passaggio allo stato Active avverrà nel momento in cui qualche altro bundle richiederà i "servigi" del framework Apache CXF.

4. Struttura dell'applicazione CRM Application

Il modulo client SOAP di esempio è stato realizzato rispettando l'OSGi Service Pattern mostrato nella presentazione OSGi e Liferay 7 e con la struttura seguente:

  • crmservices-api - Definizione delle API dell'interfaccia per l'accesso al servizio SOAP target
  • crmservices-service - Implementazione delle API definite in crmservices-api. Il servizio SOAP del CRM utilizzato è disponibile pubblicamente all'indirizzo http://www.predic8.com:8080/crm/CustomerService. L'implementazione fa uso del framework Apache CXF
  • crmservices-commands - Client che mostra come consumare le API

In Figura 4 è mostrato il class diagram dell'intera applicazione e in particolare:

  • L'interfaccia CRMService definisce la nostra API pubblica d'interazione con i servizi del CRM e si trova nel modulo crmservices-api
  • La classe CRMSOAPService definita come component OSGi implementa l'interfaccia CRMService. Questo è il componete che implementata il colloquio via SOAP con il sistema di CRM e si trova nel modulo crmservices-service
  • La classe CRMCustomerServiceCommand definita come component OSGi implementa una serie di comandi OSGi che consentono di eseguire le operazioni definite dall'interfaccia CRMServiceinsomma, agisce da consumer dei servizi CRM
Figura 4 - Class Diagram dell'applicazione CRM Application

Figura 4 - Class Diagram dell'applicazione CRM Application

Ognuno dei moduli rappresenta fisicamente un bundle OSGi, esattamente i bundle sono:

  • crmservices-api.jar
  • crmservices-service.jar
  • crmservices-commands.jar 

5. Deploy dei bundle dell'applicazione

Il processo di deploy dei bundle del modulo webservices-client sulla vostra istanza Liferay 7 può avvenire in questo modo:

  • Clone del repository liferay-italia-bo-usergroup
  • Modifica del file gradle.properties specificando la propria directory d'installazione di Liferay 7, che nel mio caso è /opt/liferay-ce-portal-7.0-ga2-blog. La property da modificare è liferay.workspace.home.dir

A seguire i comandi per il deploy dei bundle del modulo webservices-client.

$ git clone https://github.com/amusarra/liferay-italia-bo-usergroup
$ cd liferay-italia-bo-usergroup
$ cd modules/webservices-client
$ gradle deploy

L'effetto del comando del comando gradle deploy è visibile dai log di Liferay di cui riporto un esempio.

20:34:39,563 INFO  [fileinstall-/opt/liferay-ce-portal-7.0-ga2-blog/osgi/modules][BundleStartStopLogger:35] STARTED crmservices-api_1.0.0 [489]
20:34:39,568 INFO  [fileinstall-/opt/liferay-ce-portal-7.0-ga2-blog/osgi/modules][BundleStartStopLogger:35] STARTED crmservices.commands_1.0.0 [488]
20:34:49,736 INFO  [fileinstall-/opt/liferay-ce-portal-7.0-ga2-blog/osgi/modules][BundleStartStopLogger:35] STARTED crmservices-service_1.0.0 [490]
20:34:49,746 INFO  [fileinstall-/opt/liferay-ce-portal-7.0-ga2-blog/osgi/modules][CRMSOAPService:149] Configured SOAP EndPoint : { http://www.predic8.com:8080/crm/CustomerService }
20:34:50,125 INFO  [fileinstall-/opt/liferay-ce-portal-7.0-ga2-blog/osgi/modules][BundleStartStopLogger:35] STARTED org.apache.cxf.cxf-core_3.1.6 [480]
20:34:50,778 INFO  [fileinstall-/opt/liferay-ce-portal-7.0-ga2-blog/osgi/modules][BundleStartStopLogger:35] STARTED org.apache.cxf.cxf-rt-frontend-simple_3.1.6 [485]
20:34:50,788 INFO  [fileinstall-/opt/liferay-ce-portal-7.0-ga2-blog/osgi/modules][BundleStartStopLogger:35] STARTED org.apache.cxf.cxf-rt-frontend-jaxws_3.1.6 [486]
20:34:50,863 INFO  [fileinstall-/opt/liferay-ce-portal-7.0-ga2-blog/osgi/modules][BundleStartStopLogger:35] STARTED org.apache.cxf.cxf-rt-bindings-soap_3.1.6 [483]
20:34:50,885 INFO  [fileinstall-/opt/liferay-ce-portal-7.0-ga2-blog/osgi/modules][BundleStartStopLogger:35] STARTED org.apache.cxf.cxf-rt-wsdl_3.1.6 [484]
20:34:51,225 INFO  [fileinstall-/opt/liferay-ce-portal-7.0-ga2-blog/osgi/modules][BundleStartStopLogger:35] STARTED org.apache.cxf.cxf-rt-transports-http_3.1.6 [487]
20:34:51,237 INFO  [fileinstall-/opt/liferay-ce-portal-7.0-ga2-blog/osgi/modules][BundleStartStopLogger:35] STARTED org.apache.cxf.cxf-rt-bindings-xml_3.1.6 [482]
20:34:51,667 INFO  [fileinstall-/opt/liferay-ce-portal-7.0-ga2-blog/osgi/modules][BundleStartStopLogger:35] STARTED org.apache.cxf.cxf-rt-databinding-jaxb_3.1.6 [481]

Cosa notate dall'estratto del file di log di Liferay 7? Tutto normale, nulla di strano. Al momento del deploy dei nostri bundle anche i bundle di Apache CXF sono stati avviati e passati nello stato Active. Per evidenziare ancora meglio la nuova situazione eseguire il comando lb dalla gogo shell così come indicato a seguire.

g! lb | grep -e "XmlSchema|Apache CXF|crmservices"

  479|Active     |    1|XmlSchema Core (2.2.1)
  480|Active     |    1|Apache CXF Core (3.1.6)
  481|Active     |    1|Apache CXF Runtime JAXB DataBinding (3.1.6)
  482|Active     |    1|Apache CXF Runtime XML Binding (3.1.6)
  483|Active     |    1|Apache CXF Runtime SOAP Binding (3.1.6)
  484|Active     |    1|Apache CXF Runtime Core for WSDL (3.1.6)
  485|Active     |    1|Apache CXF Runtime Simple Frontend (3.1.6)
  486|Active     |    1|Apache CXF Runtime JAX-WS Frontend (3.1.6)
  487|Active     |    1|Apache CXF Runtime HTTP Transport (3.1.6)
  488|Active     |   10|crmservices.commands (1.0.0)
  489|Active     |   10|crmservices-api (1.0.0)
  490|Active     |   10|crmservices-service (1.0.0)

6. Test del client SOAP

Per il test del client possiamo utilizzare i comandi OSGi definiti in crmservices-commands:

  • createDefaultCustomer - Comando per la creazione di un customer
  • getCustomer - Comando per il retrieve di un customer specificando l'id del customer
  • getCustomers - Comando per il retrieve di tutti i customer

A seguire l'esecuzione in ordine dei comandi OSGi sopra descritti e il relativo output.

g! createDefaultCustomer

Customer with id: 4ab5a868-e41e-4c26-867e-2a88af56866e created

g! getCustomer 4ab5a868-e41e-4c26-867e-2a88af56866e

Customer [person=PersonType [id=4ab5a868-e41e-4c26-867e-2a88af56866e, firstName=Antonio, lastName=Musarra, age=35, address=AddressType [street=Via Guseppe Verdi 90, city=Bronte, zipCode=95034, country=IT]], companyAddressType=CompanyAddressType [companyName=Antonio Musarra's Blog], id=4ab5a868-e41e-4c26-867e-2a88af56866e]

g! getCustomers

it.dontesta.labs.liferay.lrbo16.webservice.crm.exception.CRMServiceException: The be implement!

7. Risorse

Per approfondimenti su Liferay 7 e OSGi vi lascio queste serie di risorse:

8. Conclusioni

In questo articolo abbiamo visto come impostare il vostro ambiente Liferay 7 al fine di realizzare applicazioni che hanno necessità di colloquiare con altri sistemi attraverso il protocollo SOAP. Sicuramente è più interessante vedere com'è strutturata un'applicazione seguendo l'OSGi Service Pattern. Esistono altri modi per utilizzare il framework Apache CXF all'interno delle vostre applicazioni, per esempio, includendo i jar direttamente all'interno dell'applicazione, metodo che personalmente sconsiglio. In genere preferisco l'approccio a bundle quando non ci sono restrizioni particolari, in questo caso ogni applicazione potrà sfruttare il framework Apache CXF dichiarandone solamente l'utilizzo e i bundle delle applicazioni risulteranno più contenuti in termini di dimensioni.  

Antonio Musarra

I began my journey into the world of computing from an Olivetti M24 PC (http://it.wikipedia.org/wiki/Olivetti_M24) bought by my father for his work. Day after day, quickly taking control until … Now doing business consulting for projects in the enterprise application development using web-oriented technologies such as J2EE, Web Services, ESB, TIBCO, PHP.

You may also like...