SlideShare ist ein Scribd-Unternehmen logo
1 von 48
Downloaden Sie, um offline zu lesen
MessageBus, Cluster communication and caching on B2B 
Mariuzzo Mauro 
Liferay Architect, SMC Treviso srl
Liferay Symposium Italy, Rome 2014 
- 2 - 
Requisito 
Creare una soluzione B2B per consentire a Partner e Rivenditori di: 
●vedere il catalogo dei prodotti 
●effettuare ordini e vederne lo stato di avanzamento 
●vedere i propri documenti fiscali (ordini, fatture)
Liferay Symposium Italy, Rome 2014 
- 4 - 
Prodotti coinvolti - ERP 
Fonte aziendale autoritativa per: 
●Anagrafiche Cliente, Anagrafiche Prodotto, ... 
●Lavorazioni 
●Ordini 
●Fatture 
●Listini Particolari Cliente e metodi di calcolo del prezzo 
●Contratti e Promozioni 
●.... 
ERP
Liferay Symposium Italy, Rome 2014 
- 5 - 
Soluzione CRM open source realizzata in Java secondo un paradigma model-driven. 
Gestisce le problematiche CRM, SFA, MA. 
Implementa diversi meccanismi di integrazione: CalDAV, CardDAV, IMAP, LDAP, ... 
Prodotti coinvolti - CRM 
OpenCRX
Liferay Symposium Italy, Rome 2014 
- 6 - 
Replica i dati ERP e li arricchisce per i contesti “non fiscali”: 
●Customer Satisfaction (Help-Desk, TTS, ....) 
●Sales Force Automation 
●Marketing Automation 
●.... 
Prodotti coinvolti - CRM 
OpenCRX
Liferay Symposium Italy, Rome 2014 
- 7 - 
●Fornisce all'utente una User Interface semplificata che migliora la sua User eXperience 
–Rispetto a ERP e CRM 
●Unico punto di accesso applicativo per gli utenti esterni 
●Moltiplicatore di accessi 
–I CRM non sono pensati per centinaia di utenti contemporanei 
●Arricchisce i contenuti per una fruizione “responsiva” e cross- browser 
●.... 
Prodotti coinvolti - Portale 
Liferay-Portal
Liferay Symposium Italy, Rome 2014 
- 8 - 
DMZ LAN 
Soluzione - Architettura 
Internet
Liferay Symposium Italy, Rome 2014 
- 9 - 
Soluzione – Screenshots
Liferay Symposium Italy, Rome 2014 
- 10 - 
Soluzione – Screenshots
Liferay Symposium Italy, Rome 2014 
- 11 - 
Soluzione – Screenshots
Liferay Symposium Italy, Rome 2014 
- 12 - 
Soluzione – Screenshots
Liferay Symposium Italy, Rome 2014 
- 13 - 
Soluzione – Screenshots
Liferay Symposium Italy, Rome 2014 
- 14 - 
Soluzione – Screenshots
Liferay Symposium Italy, Rome 2014 
- 15 - 
Soluzione – Screenshots
Liferay Symposium Italy, Rome 2014 
- 16 - 
DMZ LAN 
Soluzione - Architettura 
Internet
Liferay Symposium Italy, Rome 2014 
- 17 - 
Problematiche – Integrazione Liferay-CRM 
OpenCRX dispone di un ricco set di API REST per accedere alle informazioni ed alle funzionalità 
La “soluzione B2B” è composta da diversi plugins (file .war separati) 
Come evitare di duplicare il codice di integrazione?
Liferay Symposium Italy, Rome 2014 
- 18 - 
Problematiche – Integrazione Liferay-CRM – plugin shared 
Per i servizi SOAP posso generare una “client library” partendo dal wsdl. 
Per i servizi REST me la devo costruire. 
Con il Liferay Plugins SDK posso realizzare la “client library” come plugin “shared”: 
●un particolare tipo di plugin che produce “.jar” invece di “.war” 
●pensato per codice senza stato (stateless)
Liferay Symposium Italy, Rome 2014 
- 19 - 
Problematiche – Integrazione Liferay–CRM – plugin shared 
Esempio: knowledge-base-portlet, knowledge-base-shared 
Il file build.xml 
<?xml version="1.0"?> 
<!DOCTYPE project> 
<project name="knowledge-base-shared" basedir="." default="deploy"> 
<property name="plugin.version" value="1" /> 
<import file="../build-common-shared.xml" /> 
</project>
Liferay Symposium Italy, Rome 2014 
- 20 - 
Problematiche – Integrazione Liferay–CRM – plugin shared 
Il file “build.xml” nel portlet che vuole usare lo shared 
<?xml version="1.0"?> 
<!DOCTYPE project> 
<project name="knowledge-base-portlet" basedir="." default="deploy"> 
<import file="../build-common-portlet.xml" /> 
<property name="import.shared" value="knowledge-base-shared" /> 
</project>
Liferay Symposium Italy, Rome 2014 
- 21 - 
Problematiche risolte 
✔Gestire il codice di integrazione con OpenCRX in una libreria riusabile da più plugins
Liferay Symposium Italy, Rome 2014 
- 22 - 
Problematiche – Evitare sovraccarico CRM 
Come evitare che tutti i plugin parlino direttamente con il CRM sovraccaricandolo? 
Il plugin “shared” non mi aiuta. 
Posso usare i service con il required-context!
Liferay Symposium Italy, Rome 2014 
- 23 - 
Liferay Plugins SDK - Required context 
●Anche un plugin può dichiarare dei servizi (file service.xml) 
●Il servizio si basa su 3 elementi: 
–L'interfaccia (es: KBArticleService) 
–La classe di implementazione (es: KBArticleServiceImpl) 
–La classe singleton (es: KBArticleServiceUtil) 
●Interfaccie e singleton finiscono in un file “xxxx- service.jar” 
●L'implementazione è caricata in modalità “lazy” tramite Spring
Liferay Symposium Italy, Rome 2014 
- 24 - 
Liferay Plugins SDK - Required context 
●Un plugin può dichiarare che vuole usare i servizi usati da un altro plugin 
–Nel file “liferay-plugin-package.properties” 
–Proprietà “required-depoyment-contexts” 
●A compile-time il file “xxxx-service.jar” viene copiato in “docroot/WEB-INF/lib” e finisce nel .war 
●Nella fase di deploy il plugin non viene reso operativo in assenza del contesto richiesto 
●Spring crea un tunnel tra i due plugin (i due contesti) 
●L'infrastruttura Liferay permette di trasferire oggetti complessi senza ClassCastExcpetion
Liferay Symposium Italy, Rome 2014 
- 25 - 
Liferay Plugins SDK - Required context 
●I servizi sono dichiarati nel file “service.xml” 
●Possono gestire entità reali (tabelle a database) 
<entity name="FavoriteSite" local-service="true" remote-service="false"> 
<column name="favoriteSiteId" type="long" primary="true" /> 
<column name="groupId" type="long" /> 
<column name="companyId" type="long" /> 
●Oppure entità “di servizio” 
<entity name="SocialOffice" local-service="false" remote-service="true"> 
<!-- References --> 
<reference package-path="com.liferay.portal" entity="Group" /> 
</entity>
Liferay Symposium Italy, Rome 2014 
- 26 - 
Liferay Plugins SDK - Required context 
●Dichiaro delle entità di servizio per gli elementi CRM (es: CRMProductService*) 
●Sfrutto il required-deployment-contexts per fornire i servizi agli altri plugins
Liferay Symposium Italy, Rome 2014 
- 27 - 
Problematiche risolte 
✔Gestire il codice di integrazione con OpenCRX in una libreria riusabile da più plugins 
✔Concentrare l'accesso al CRM in un unico plugin
Liferay Symposium Italy, Rome 2014 
- 28 - 
Liferay Plugins SDK - Required context 
I metodi dei services devono ritornare i dati del CRM 
Come evitare che Bean complessi mi sollevino una ClassCastException?
Liferay Symposium Italy, Rome 2014 
- 29 - 
Liferay Plugins SDK - Required context 
●I servizi devono ritornare oggetti semplici (int, long, String) 
–gli oggetti complessi sono JSON 
●Ho bisogno di un ulteriore strato che: 
–Dichiari i POJO delle entità CRM (es: CRMProduct) 
–Si preoccupi di convertire gli oggetti JSON in POJO (es: CRMProductUtil)
Liferay Symposium Italy, Rome 2014 
- 30 - 
Problematiche risolte 
✔Gestire il codice di integrazione con OpenCRX in una libreria riusabile da più plugins 
✔Concentrare l'accesso al CRM in un unico plugin 
✔Gestire gli elementi CRM come oggetti complessi
Liferay Symposium Italy, Rome 2014 
- 31 - 
Problematica – Sovraccarico CRM 
Come evitare di sovraccaricare il CRM con troppe richieste contemporanee?
Liferay Symposium Italy, Rome 2014 
- 32 - 
Problematica – Sovraccarico CRM 
Come evitare di sovraccaricare il CRM con troppe richieste contemporanee? 
Creando qualcosa di simile ad un connection- pool. 
Uso il MessageBus per creare delle code di elaborazione.
Liferay Symposium Italy, Rome 2014 
- 33 - 
MessageBus 
●E' un framework sviluppato da Liferay per gestire code di messaggi. 
●E' stato realizzato per essere leggero e flessibile. 
●Non si appoggia ad alcun framework esterno 
●Composto da tre elementi principali 
–Il Messaggio 
–La Destinazione (dove viene recapitato il messaggio) 
–Il Listener (l'attore che elabora il Messaggio)
Liferay Symposium Italy, Rome 2014 
- 34 - 
MessageBus 
Le Destinazioni sono 
●Asincrone: utilizzano più worker per elaborare i messaggi 
–Seriale: dispacciano il Messaggio ad un Listener alla volta 
–Parallela: dispacciano il Messaggio su più Listener contemporaneamente 
●Sincrone: utilizzano un singolo worker 
com....kernel.messaging.SerialDestination 
com....kernel.messaging.ParallelDestination 
com....kernel.messaging.SynchronousDestination
Liferay Symposium Italy, Rome 2014 
- 35 - 
MessageBus 
L'invio dei messaggi può essere: 
●Sincrono 
–il processo sender rimane appeso in attesa di una risposta 
–finché non arriva o per un periodo di tempo certo (timeout) 
●Asincrono 
–il processo sender continua 
–posso indicare un callback su cui ricevere la risposta 
–Posso “inviare e dimenticare” 
MessageBusUtil.sendMessage(destination, payload) 
MessageBusUtil.SendSyncronousMessage(destination, payload)
Liferay Symposium Italy, Rome 2014 
- 36 - 
Problematica – Sovraccarico CRM 
Il plugin “crm-integration-web” 
●Implementa il dialogo con il CRM 
●Tramite il ServiceBuilder gestisce le entità CRM come entità “di servizio” 
–Sotto forma di oggetti JSON 
●Dichiara delle MessageBus Destination per creare delle code di accesso ai servizi generati dal ServiceBuilder 
Il plugin “crm-integration-shared” 
●Dichiara / Implementa i Bean delle entità CRM 
●Implementa le classi per interagire con il MessageBus 
–Inviare i messaggi 
–Trasformare le risposte JSON (Payload) in POJO
Liferay Symposium Italy, Rome 2014 
- 37 - 
Problematica – Sovraccarico CRM 
Plugin ONE 
crm-integration-shared 
Plugin TWO 
crm-integration-shared 
crm-integration-web 
Destination 
Destination 
Service 
Destination 
Listener 
Listener 
Listener 
CRM
Liferay Symposium Italy, Rome 2014 
- 38 - 
Caching strato servizi 
Posso fare di più? 
Cache! 
Per le entità reali il ServiceBuilder genera la classe xxxPersistenceImpl che sfrutta la MultiVMPoolUtil per gestire la cache dei Model e dei Finder
Liferay Symposium Italy, Rome 2014 
- 39 - 
Caching strato servizi 
Per le entità “di servizio” questa classe non c'è. 
Ma la posso creare. 
Devo creare sia l'interfaccia nella parte service 
public interface CrmProductPersistence { 
public int countByC_P_D_C_B_TT( 
long userId, String customerId, String productNumber, 
String description, String categoryId, String brandId, 
CrmProductSearchTerms terms) 
throws CrmComunicationException, CrmResponseException;
Liferay Symposium Italy, Rome 2014 
- 40 - 
Caching strato servizi 
Ed ovviamente la sua implementazione 
public class CrmProductPersistenceImpl extends CrmBasePersistenceImpl 
implements CrmProductPersistence { 
.... 
public List<String> findByDescription( 
long userId, String customerId, String productNumber, String description, String categoryId, 
String brandId, CrmProductSearchTerms terms, Locale locale, int start, int count) 
throws CrmComunicationException, CrmResponseException { 
Object[] finderArgs = new Object[] { 
productNumber, description, categoryId, brandId, terms, start, count, locale}; 
@SuppressWarnings("unchecked") 
List<String> list = (List<String>)FinderCacheUtil.getResult( 
FINDER_PATH_FIND_BY_DESCRIPTION, finderArgs, null); 
if (list == null) { 
... 
list = crmItemsValuesFromResponse(productsResponse); 
if ((list != null) && !list.isEmpty()) { 
FinderCacheUtil.putResult(FINDER_PATH_FIND_BY_DESCRIPTION, finderArgs, list); 
} 
} 
return list; 
}
Liferay Symposium Italy, Rome 2014 
- 41 - 
Caching strato servizi 
La configurazione della cache si trova in “portal- impl/src/ehcache”
Liferay Symposium Italy, Rome 2014 
- 42 - 
Problematiche risolte 
✔Gestire il codice di integrazione con OpenCRX in una libreria riusabile da più plugins 
✔Concentrare l'accesso al CRM in un unico plugin 
✔Gestire gli elementi CRM come oggetti complessi 
✔Ridurre sovraccarico CRM (code + cache)
Liferay Symposium Italy, Rome 2014 
- 43 - 
Problematica - cluster 
●E se ho una installazione Liferay in Cluster? 
●La cache di Liferay è di tipo “Invalidante” 
–Se un dato non è presente in cache, oppure è scaduto o invalidato 
●lo leggo e lo metto nella mia cache 
–Se modifico un dato 
●Lo salvo sul DB 
●Lo aggiorno nella mia cache 
●Informo gli altri nodi di invalidarlo nella loro cache 
–Se cancello un dato 
●Lo cancello dal DB 
●Lo invalido nalla mia cache 
●Informo gli altri nodi di invalidarlo nella loro cache
Liferay Symposium Italy, Rome 2014 
- 44 - 
Problematica - cluster 
Possibilità UNO: dichiaro una specifica cache di replica nel MultiVMPoolUtil 
<cache 
eternal="false" 
maxElementsInMemory="100000" 
name="it.smc.....CRMProduct" 
overflowToDisk="false" 
timeToIdleSeconds="600" 
> 
<cacheEventListenerFactory 
class="com....ehcache.LiferayCacheEventListenerFactory" 
properties="replicatePuts=false,replicateUpdatesViaCopy=false" 
propertySeparator="," 
/> 
<bootstrapCacheLoaderFactory 
class="com....ehcache.LiferayBootstrapCacheLoaderFactory" /> 
</cache> 
"replicatePuts=true,replicatePutsViaCopy=true,replicateUpdatesViaCopy=true"
Liferay Symposium Italy, Rome 2014 
- 45 - 
Problematica - cluster 
Possibilità DUE: Uso la SingleVMPoolUtil e decido io come propagare la cache tra i nodi. 
Per propagarla utilizzo il framework “ClusterExecutor”
Liferay Symposium Italy, Rome 2014 
- 46 - 
Problematica - cluster 
com.liferay.portal.kernel.cluster.ClusterExecutorUtil 
public List<ClusterNode> getClusterNodes(); 
public ClusterNode getLocalClusterNode() throws SystemException; 
public Address getLocalClusterNodeAddress(); 
public void initialize(); 
public boolean isClusterNodeAlive(Address address); 
public boolean isClusterNodeAlive(String clusterNodeId); 
public boolean isEnabled(); 
public FutureClusterResponses execute( 
ClusterRequest clusterRequest) 
throws SystemException;
Liferay Symposium Italy, Rome 2014 
- 47 - 
Problematica - cluster 
Il metodo Execute mi permette di eseguire un metodo di una classe negli altri nodi 
●Identifico il metodo da chiamare 
MethodKey myMethodKey = new MethodKey( 
MethodClass.class, "methodName", FirstSerializableArguement.class ...); 
●Creo l'handler del metodo 
MethodHandler myMethodHandler = new MethodHandler( 
myMethodKey, myFirstArguement....); 
●Lo invoco 
–Metto true su skipLocal per saltare me stesso 
ClusterRequest clusterRequest = ClusterRequest.createMulticastRequest( 
methodHandler, true); 
ClusterExecutorUtil.execute(clusterRequest);
Liferay Symposium Italy, Rome 2014 
- 48 - 
Problematiche risolte 
✔Gestire il codice di integrazione con OpenCRX in una libreria riusabile da più plugins 
✔Concentrare l'accesso al CRM in un unico plugin 
✔Gestire gli elementi CRM come oggetti complessi 
✔Ridurre sovraccarico CRM (code + cache) 
✔Gestire installazione in Cluster
Liferay Symposium Italy, Rome 2014 
- 49 - 
MessageBus, Cluster communication and caching on B2B 
Mariuzzo Mauro 
Liferay Architect, SMC Treviso srl

Weitere ähnliche Inhalte

Ähnlich wie #LRIS2014 - MessageBus, Cluster communication and Caching on B2B

Sviluppo di servizi REST per Android - Luca Masini
Sviluppo di servizi REST per Android - Luca Masini Sviluppo di servizi REST per Android - Luca Masini
Sviluppo di servizi REST per Android - Luca Masini
Whymca
 

Ähnlich wie #LRIS2014 - MessageBus, Cluster communication and Caching on B2B (20)

UI Composition
UI CompositionUI Composition
UI Composition
 
Software Testing Forum 2012 - Polarion e TRS SpA
Software Testing Forum 2012 - Polarion e TRS SpASoftware Testing Forum 2012 - Polarion e TRS SpA
Software Testing Forum 2012 - Polarion e TRS SpA
 
Spring e Flex
Spring e FlexSpring e Flex
Spring e Flex
 
Set up and management of an integrated information system on Linux.
Set up and management of an integrated information system on Linux.Set up and management of an integrated information system on Linux.
Set up and management of an integrated information system on Linux.
 
Set up and management of an integrated information system on Linux.
Set up and management of an integrated information system on Linux.Set up and management of an integrated information system on Linux.
Set up and management of an integrated information system on Linux.
 
Le Novita’ dello sviluppo applicazioni per IBM i
Le Novita’ dello sviluppo applicazioni per IBM iLe Novita’ dello sviluppo applicazioni per IBM i
Le Novita’ dello sviluppo applicazioni per IBM i
 
Evento 18 giugno - Sviluppo applicativo
Evento 18 giugno - Sviluppo applicativoEvento 18 giugno - Sviluppo applicativo
Evento 18 giugno - Sviluppo applicativo
 
La piattaforma web di CNA: Istanze Drupal replicabili integrate con Alfresco ...
La piattaforma web di CNA: Istanze Drupal replicabili integrate con Alfresco ...La piattaforma web di CNA: Istanze Drupal replicabili integrate con Alfresco ...
La piattaforma web di CNA: Istanze Drupal replicabili integrate con Alfresco ...
 
La piattaforma web di CNA: Istanze Drupal replicabili integrate con Alfresco ...
La piattaforma web di CNA: Istanze Drupal replicabili integrate con Alfresco ...La piattaforma web di CNA: Istanze Drupal replicabili integrate con Alfresco ...
La piattaforma web di CNA: Istanze Drupal replicabili integrate con Alfresco ...
 
Designing with microservices - Daniele Mondello
Designing with microservices - Daniele MondelloDesigning with microservices - Daniele Mondello
Designing with microservices - Daniele Mondello
 
e-SUAP - General software architecture (Italiano)
e-SUAP - General software architecture (Italiano)e-SUAP - General software architecture (Italiano)
e-SUAP - General software architecture (Italiano)
 
Ibm bluemix r pozzi
Ibm bluemix r pozziIbm bluemix r pozzi
Ibm bluemix r pozzi
 
Erlug
ErlugErlug
Erlug
 
B Human Progetti di Stage 2009
B Human Progetti di Stage 2009B Human Progetti di Stage 2009
B Human Progetti di Stage 2009
 
cv Armando Maglio
cv Armando Magliocv Armando Maglio
cv Armando Maglio
 
API Transformation in Crédit Agricole Italia
API Transformation in Crédit Agricole ItaliaAPI Transformation in Crédit Agricole Italia
API Transformation in Crédit Agricole Italia
 
Emerasoft Day 2012 - TRS "Uso del metodo Cosmic e di Polarion per la gestione...
Emerasoft Day 2012 - TRS "Uso del metodo Cosmic e di Polarion per la gestione...Emerasoft Day 2012 - TRS "Uso del metodo Cosmic e di Polarion per la gestione...
Emerasoft Day 2012 - TRS "Uso del metodo Cosmic e di Polarion per la gestione...
 
Machine learning models continuous deployment on azure using devops
Machine learning models continuous deployment on azure using devopsMachine learning models continuous deployment on azure using devops
Machine learning models continuous deployment on azure using devops
 
Liferay: Esporre Web Services Custom
Liferay: Esporre Web Services CustomLiferay: Esporre Web Services Custom
Liferay: Esporre Web Services Custom
 
Sviluppo di servizi REST per Android - Luca Masini
Sviluppo di servizi REST per Android - Luca Masini Sviluppo di servizi REST per Android - Luca Masini
Sviluppo di servizi REST per Android - Luca Masini
 

#LRIS2014 - MessageBus, Cluster communication and Caching on B2B

  • 1. MessageBus, Cluster communication and caching on B2B Mariuzzo Mauro Liferay Architect, SMC Treviso srl
  • 2. Liferay Symposium Italy, Rome 2014 - 2 - Requisito Creare una soluzione B2B per consentire a Partner e Rivenditori di: ●vedere il catalogo dei prodotti ●effettuare ordini e vederne lo stato di avanzamento ●vedere i propri documenti fiscali (ordini, fatture)
  • 3. Liferay Symposium Italy, Rome 2014 - 4 - Prodotti coinvolti - ERP Fonte aziendale autoritativa per: ●Anagrafiche Cliente, Anagrafiche Prodotto, ... ●Lavorazioni ●Ordini ●Fatture ●Listini Particolari Cliente e metodi di calcolo del prezzo ●Contratti e Promozioni ●.... ERP
  • 4. Liferay Symposium Italy, Rome 2014 - 5 - Soluzione CRM open source realizzata in Java secondo un paradigma model-driven. Gestisce le problematiche CRM, SFA, MA. Implementa diversi meccanismi di integrazione: CalDAV, CardDAV, IMAP, LDAP, ... Prodotti coinvolti - CRM OpenCRX
  • 5. Liferay Symposium Italy, Rome 2014 - 6 - Replica i dati ERP e li arricchisce per i contesti “non fiscali”: ●Customer Satisfaction (Help-Desk, TTS, ....) ●Sales Force Automation ●Marketing Automation ●.... Prodotti coinvolti - CRM OpenCRX
  • 6. Liferay Symposium Italy, Rome 2014 - 7 - ●Fornisce all'utente una User Interface semplificata che migliora la sua User eXperience –Rispetto a ERP e CRM ●Unico punto di accesso applicativo per gli utenti esterni ●Moltiplicatore di accessi –I CRM non sono pensati per centinaia di utenti contemporanei ●Arricchisce i contenuti per una fruizione “responsiva” e cross- browser ●.... Prodotti coinvolti - Portale Liferay-Portal
  • 7. Liferay Symposium Italy, Rome 2014 - 8 - DMZ LAN Soluzione - Architettura Internet
  • 8. Liferay Symposium Italy, Rome 2014 - 9 - Soluzione – Screenshots
  • 9. Liferay Symposium Italy, Rome 2014 - 10 - Soluzione – Screenshots
  • 10. Liferay Symposium Italy, Rome 2014 - 11 - Soluzione – Screenshots
  • 11. Liferay Symposium Italy, Rome 2014 - 12 - Soluzione – Screenshots
  • 12. Liferay Symposium Italy, Rome 2014 - 13 - Soluzione – Screenshots
  • 13. Liferay Symposium Italy, Rome 2014 - 14 - Soluzione – Screenshots
  • 14. Liferay Symposium Italy, Rome 2014 - 15 - Soluzione – Screenshots
  • 15. Liferay Symposium Italy, Rome 2014 - 16 - DMZ LAN Soluzione - Architettura Internet
  • 16. Liferay Symposium Italy, Rome 2014 - 17 - Problematiche – Integrazione Liferay-CRM OpenCRX dispone di un ricco set di API REST per accedere alle informazioni ed alle funzionalità La “soluzione B2B” è composta da diversi plugins (file .war separati) Come evitare di duplicare il codice di integrazione?
  • 17. Liferay Symposium Italy, Rome 2014 - 18 - Problematiche – Integrazione Liferay-CRM – plugin shared Per i servizi SOAP posso generare una “client library” partendo dal wsdl. Per i servizi REST me la devo costruire. Con il Liferay Plugins SDK posso realizzare la “client library” come plugin “shared”: ●un particolare tipo di plugin che produce “.jar” invece di “.war” ●pensato per codice senza stato (stateless)
  • 18. Liferay Symposium Italy, Rome 2014 - 19 - Problematiche – Integrazione Liferay–CRM – plugin shared Esempio: knowledge-base-portlet, knowledge-base-shared Il file build.xml <?xml version="1.0"?> <!DOCTYPE project> <project name="knowledge-base-shared" basedir="." default="deploy"> <property name="plugin.version" value="1" /> <import file="../build-common-shared.xml" /> </project>
  • 19. Liferay Symposium Italy, Rome 2014 - 20 - Problematiche – Integrazione Liferay–CRM – plugin shared Il file “build.xml” nel portlet che vuole usare lo shared <?xml version="1.0"?> <!DOCTYPE project> <project name="knowledge-base-portlet" basedir="." default="deploy"> <import file="../build-common-portlet.xml" /> <property name="import.shared" value="knowledge-base-shared" /> </project>
  • 20. Liferay Symposium Italy, Rome 2014 - 21 - Problematiche risolte ✔Gestire il codice di integrazione con OpenCRX in una libreria riusabile da più plugins
  • 21. Liferay Symposium Italy, Rome 2014 - 22 - Problematiche – Evitare sovraccarico CRM Come evitare che tutti i plugin parlino direttamente con il CRM sovraccaricandolo? Il plugin “shared” non mi aiuta. Posso usare i service con il required-context!
  • 22. Liferay Symposium Italy, Rome 2014 - 23 - Liferay Plugins SDK - Required context ●Anche un plugin può dichiarare dei servizi (file service.xml) ●Il servizio si basa su 3 elementi: –L'interfaccia (es: KBArticleService) –La classe di implementazione (es: KBArticleServiceImpl) –La classe singleton (es: KBArticleServiceUtil) ●Interfaccie e singleton finiscono in un file “xxxx- service.jar” ●L'implementazione è caricata in modalità “lazy” tramite Spring
  • 23. Liferay Symposium Italy, Rome 2014 - 24 - Liferay Plugins SDK - Required context ●Un plugin può dichiarare che vuole usare i servizi usati da un altro plugin –Nel file “liferay-plugin-package.properties” –Proprietà “required-depoyment-contexts” ●A compile-time il file “xxxx-service.jar” viene copiato in “docroot/WEB-INF/lib” e finisce nel .war ●Nella fase di deploy il plugin non viene reso operativo in assenza del contesto richiesto ●Spring crea un tunnel tra i due plugin (i due contesti) ●L'infrastruttura Liferay permette di trasferire oggetti complessi senza ClassCastExcpetion
  • 24. Liferay Symposium Italy, Rome 2014 - 25 - Liferay Plugins SDK - Required context ●I servizi sono dichiarati nel file “service.xml” ●Possono gestire entità reali (tabelle a database) <entity name="FavoriteSite" local-service="true" remote-service="false"> <column name="favoriteSiteId" type="long" primary="true" /> <column name="groupId" type="long" /> <column name="companyId" type="long" /> ●Oppure entità “di servizio” <entity name="SocialOffice" local-service="false" remote-service="true"> <!-- References --> <reference package-path="com.liferay.portal" entity="Group" /> </entity>
  • 25. Liferay Symposium Italy, Rome 2014 - 26 - Liferay Plugins SDK - Required context ●Dichiaro delle entità di servizio per gli elementi CRM (es: CRMProductService*) ●Sfrutto il required-deployment-contexts per fornire i servizi agli altri plugins
  • 26. Liferay Symposium Italy, Rome 2014 - 27 - Problematiche risolte ✔Gestire il codice di integrazione con OpenCRX in una libreria riusabile da più plugins ✔Concentrare l'accesso al CRM in un unico plugin
  • 27. Liferay Symposium Italy, Rome 2014 - 28 - Liferay Plugins SDK - Required context I metodi dei services devono ritornare i dati del CRM Come evitare che Bean complessi mi sollevino una ClassCastException?
  • 28. Liferay Symposium Italy, Rome 2014 - 29 - Liferay Plugins SDK - Required context ●I servizi devono ritornare oggetti semplici (int, long, String) –gli oggetti complessi sono JSON ●Ho bisogno di un ulteriore strato che: –Dichiari i POJO delle entità CRM (es: CRMProduct) –Si preoccupi di convertire gli oggetti JSON in POJO (es: CRMProductUtil)
  • 29. Liferay Symposium Italy, Rome 2014 - 30 - Problematiche risolte ✔Gestire il codice di integrazione con OpenCRX in una libreria riusabile da più plugins ✔Concentrare l'accesso al CRM in un unico plugin ✔Gestire gli elementi CRM come oggetti complessi
  • 30. Liferay Symposium Italy, Rome 2014 - 31 - Problematica – Sovraccarico CRM Come evitare di sovraccaricare il CRM con troppe richieste contemporanee?
  • 31. Liferay Symposium Italy, Rome 2014 - 32 - Problematica – Sovraccarico CRM Come evitare di sovraccaricare il CRM con troppe richieste contemporanee? Creando qualcosa di simile ad un connection- pool. Uso il MessageBus per creare delle code di elaborazione.
  • 32. Liferay Symposium Italy, Rome 2014 - 33 - MessageBus ●E' un framework sviluppato da Liferay per gestire code di messaggi. ●E' stato realizzato per essere leggero e flessibile. ●Non si appoggia ad alcun framework esterno ●Composto da tre elementi principali –Il Messaggio –La Destinazione (dove viene recapitato il messaggio) –Il Listener (l'attore che elabora il Messaggio)
  • 33. Liferay Symposium Italy, Rome 2014 - 34 - MessageBus Le Destinazioni sono ●Asincrone: utilizzano più worker per elaborare i messaggi –Seriale: dispacciano il Messaggio ad un Listener alla volta –Parallela: dispacciano il Messaggio su più Listener contemporaneamente ●Sincrone: utilizzano un singolo worker com....kernel.messaging.SerialDestination com....kernel.messaging.ParallelDestination com....kernel.messaging.SynchronousDestination
  • 34. Liferay Symposium Italy, Rome 2014 - 35 - MessageBus L'invio dei messaggi può essere: ●Sincrono –il processo sender rimane appeso in attesa di una risposta –finché non arriva o per un periodo di tempo certo (timeout) ●Asincrono –il processo sender continua –posso indicare un callback su cui ricevere la risposta –Posso “inviare e dimenticare” MessageBusUtil.sendMessage(destination, payload) MessageBusUtil.SendSyncronousMessage(destination, payload)
  • 35. Liferay Symposium Italy, Rome 2014 - 36 - Problematica – Sovraccarico CRM Il plugin “crm-integration-web” ●Implementa il dialogo con il CRM ●Tramite il ServiceBuilder gestisce le entità CRM come entità “di servizio” –Sotto forma di oggetti JSON ●Dichiara delle MessageBus Destination per creare delle code di accesso ai servizi generati dal ServiceBuilder Il plugin “crm-integration-shared” ●Dichiara / Implementa i Bean delle entità CRM ●Implementa le classi per interagire con il MessageBus –Inviare i messaggi –Trasformare le risposte JSON (Payload) in POJO
  • 36. Liferay Symposium Italy, Rome 2014 - 37 - Problematica – Sovraccarico CRM Plugin ONE crm-integration-shared Plugin TWO crm-integration-shared crm-integration-web Destination Destination Service Destination Listener Listener Listener CRM
  • 37. Liferay Symposium Italy, Rome 2014 - 38 - Caching strato servizi Posso fare di più? Cache! Per le entità reali il ServiceBuilder genera la classe xxxPersistenceImpl che sfrutta la MultiVMPoolUtil per gestire la cache dei Model e dei Finder
  • 38. Liferay Symposium Italy, Rome 2014 - 39 - Caching strato servizi Per le entità “di servizio” questa classe non c'è. Ma la posso creare. Devo creare sia l'interfaccia nella parte service public interface CrmProductPersistence { public int countByC_P_D_C_B_TT( long userId, String customerId, String productNumber, String description, String categoryId, String brandId, CrmProductSearchTerms terms) throws CrmComunicationException, CrmResponseException;
  • 39. Liferay Symposium Italy, Rome 2014 - 40 - Caching strato servizi Ed ovviamente la sua implementazione public class CrmProductPersistenceImpl extends CrmBasePersistenceImpl implements CrmProductPersistence { .... public List<String> findByDescription( long userId, String customerId, String productNumber, String description, String categoryId, String brandId, CrmProductSearchTerms terms, Locale locale, int start, int count) throws CrmComunicationException, CrmResponseException { Object[] finderArgs = new Object[] { productNumber, description, categoryId, brandId, terms, start, count, locale}; @SuppressWarnings("unchecked") List<String> list = (List<String>)FinderCacheUtil.getResult( FINDER_PATH_FIND_BY_DESCRIPTION, finderArgs, null); if (list == null) { ... list = crmItemsValuesFromResponse(productsResponse); if ((list != null) && !list.isEmpty()) { FinderCacheUtil.putResult(FINDER_PATH_FIND_BY_DESCRIPTION, finderArgs, list); } } return list; }
  • 40. Liferay Symposium Italy, Rome 2014 - 41 - Caching strato servizi La configurazione della cache si trova in “portal- impl/src/ehcache”
  • 41. Liferay Symposium Italy, Rome 2014 - 42 - Problematiche risolte ✔Gestire il codice di integrazione con OpenCRX in una libreria riusabile da più plugins ✔Concentrare l'accesso al CRM in un unico plugin ✔Gestire gli elementi CRM come oggetti complessi ✔Ridurre sovraccarico CRM (code + cache)
  • 42. Liferay Symposium Italy, Rome 2014 - 43 - Problematica - cluster ●E se ho una installazione Liferay in Cluster? ●La cache di Liferay è di tipo “Invalidante” –Se un dato non è presente in cache, oppure è scaduto o invalidato ●lo leggo e lo metto nella mia cache –Se modifico un dato ●Lo salvo sul DB ●Lo aggiorno nella mia cache ●Informo gli altri nodi di invalidarlo nella loro cache –Se cancello un dato ●Lo cancello dal DB ●Lo invalido nalla mia cache ●Informo gli altri nodi di invalidarlo nella loro cache
  • 43. Liferay Symposium Italy, Rome 2014 - 44 - Problematica - cluster Possibilità UNO: dichiaro una specifica cache di replica nel MultiVMPoolUtil <cache eternal="false" maxElementsInMemory="100000" name="it.smc.....CRMProduct" overflowToDisk="false" timeToIdleSeconds="600" > <cacheEventListenerFactory class="com....ehcache.LiferayCacheEventListenerFactory" properties="replicatePuts=false,replicateUpdatesViaCopy=false" propertySeparator="," /> <bootstrapCacheLoaderFactory class="com....ehcache.LiferayBootstrapCacheLoaderFactory" /> </cache> "replicatePuts=true,replicatePutsViaCopy=true,replicateUpdatesViaCopy=true"
  • 44. Liferay Symposium Italy, Rome 2014 - 45 - Problematica - cluster Possibilità DUE: Uso la SingleVMPoolUtil e decido io come propagare la cache tra i nodi. Per propagarla utilizzo il framework “ClusterExecutor”
  • 45. Liferay Symposium Italy, Rome 2014 - 46 - Problematica - cluster com.liferay.portal.kernel.cluster.ClusterExecutorUtil public List<ClusterNode> getClusterNodes(); public ClusterNode getLocalClusterNode() throws SystemException; public Address getLocalClusterNodeAddress(); public void initialize(); public boolean isClusterNodeAlive(Address address); public boolean isClusterNodeAlive(String clusterNodeId); public boolean isEnabled(); public FutureClusterResponses execute( ClusterRequest clusterRequest) throws SystemException;
  • 46. Liferay Symposium Italy, Rome 2014 - 47 - Problematica - cluster Il metodo Execute mi permette di eseguire un metodo di una classe negli altri nodi ●Identifico il metodo da chiamare MethodKey myMethodKey = new MethodKey( MethodClass.class, "methodName", FirstSerializableArguement.class ...); ●Creo l'handler del metodo MethodHandler myMethodHandler = new MethodHandler( myMethodKey, myFirstArguement....); ●Lo invoco –Metto true su skipLocal per saltare me stesso ClusterRequest clusterRequest = ClusterRequest.createMulticastRequest( methodHandler, true); ClusterExecutorUtil.execute(clusterRequest);
  • 47. Liferay Symposium Italy, Rome 2014 - 48 - Problematiche risolte ✔Gestire il codice di integrazione con OpenCRX in una libreria riusabile da più plugins ✔Concentrare l'accesso al CRM in un unico plugin ✔Gestire gli elementi CRM come oggetti complessi ✔Ridurre sovraccarico CRM (code + cache) ✔Gestire installazione in Cluster
  • 48. Liferay Symposium Italy, Rome 2014 - 49 - MessageBus, Cluster communication and caching on B2B Mariuzzo Mauro Liferay Architect, SMC Treviso srl