bloggers bloggers

Marco Napolitano
Messaggi: 79
Stelle: 0
Data: 17/02/22
Jader Jed Francia
Messaggi: 63
Stelle: 0
Data: 18/02/21
Paolo Gambetti
Messaggi: 2
Stelle: 0
Data: 11/11/19
Katia Pazzi
Messaggi: 1
Stelle: 0
Data: 27/06/19
Ezio Lombardi
Messaggi: 11
Stelle: 0
Data: 10/04/18
Chiara Mambretti
Messaggi: 25
Stelle: 0
Data: 27/02/17
Serena Traversi
Messaggi: 3
Stelle: 0
Data: 21/07/16
Francesco Falanga
Messaggi: 8
Stelle: 0
Data: 14/06/16
Antonio Musarra
Messaggi: 2
Stelle: 0
Data: 18/11/13
Simone Celli Marchi
Messaggi: 6
Stelle: 0
Data: 09/07/13
Indietro

Introduzione agli Hooks: primo episodio

L’insediamento dell’Open Source nel mondo del cosiddetto Enterprise prosegue in modo inesorabile ma alcune organizzazioni sono ancora restie all’adozione di software Open Source e hanno delle giustificate ragioni. La manutenzione delle personalizzazioni (da riesaminare per ogni nuova release) è uno dei motivi che giustifica questa diffidenza nei confronti dei software Open Source.

Ipotizziamo per un attimo di poter “agganciare tramite un arpione” le personalizzazioni implementate senza toccare il core del software, direi che sarebbe un’operazione fantastica, bene, Liferay ha introdotto di recente un nuovo tipo di plugin che prende per l’appunto il nome di Liferay Hooks (Liferay Inc, 2012) . Questa nuova via di estensione fornisce un livello di separazione tra le vostre personalizzazioni e il core di Liferay, diminuendo drasticamente la complessità di personalizzazione, introducendo inoltre una notevole libertà di movimento senza la preoccupazione di dover tener tracciata del codice sorgente a ogni release del core di Liferay.

Restando nell’orto delle personalizzazioni, un'altra strada “più larga” da percorrere in scenari complessi, dove gli altri tipi di plugin non arrivano, si chiama Liferay Ext (Liferay Inc, 2012) . La trattazione di questa “bestia” non è però oggetto di quest’articolo, magari di un futuro.

A questo punto direi che sia venuto il momento di scrutare più da vicino gli hooks e per quali scopi possano essere utilizzati, per poi immediatamente saltare alla realizzazione pratica di un hook per personalizzare Liferay. La versione di riferimento di Liferay è la 6.1 edizione Community Edition.

1. Obiettivo

L’articolo intende comunicare le informazioni base che riguardano gli hooks favorendo l’aspetto reale, in altre parole, far capire a cosa servono tramite l’esposizione e realizzazione di un caso di studio quanto più possibile vicino al reale. Sarà quindi presentato un caso d’integrazione che farà uso degli hooks, toccando i vari aspetti di personalizzazione. L’articolo sarà suddiviso in più episodi per evitare una “sbrodolata” d’informazione e rendere più efficace l’assimilazione di quanto esposto.

2. Gli Hook in breve

Che cosa sono gli hooks? Il nome è più che azzeccato, in effetti, sono parti di codice “agganciate” a Liferay che in genere sovrascrivono alcune delle funzioni del portale.

Tramite questo tipo di plugin è possibile per gli sviluppatori sovrascrivere parti del core di Liferay con le proprie implementazioni, mantenendo una netta separazione tra il codice personalizzato e il core di Liferay.

Qualcuno potrebbe giustamente obiettare con una domanda del tipo: perché non utilizzare l’Ext plugin? Poiché l’Ext plugin fornisce l’accesso completo alle parti interne del core di Liferay, il codice personalizzato diventerebbe strettamente accoppiato a particolari implementazioni di funzioni interne che spesso potrebbero cambiare da una release a un’altra, basterebbe quindi un semplice cambio di firma di un metodo per causare un gran mal di testa a colui il quale deve riesaminare il codice personalizzato.

Così come portlet, theme, layout e così via, anche gli hooks sono hot-deployable [1] , quindi aggiungere e rimuovere è un’operazione semplice. La possibilità di suddividere funzionalità complesse in più hook, sviluppati da persone diverse, rende dinamico l’ambiente di sviluppo e inoltre l’uso del set di API pubbliche di Liferay per la scrittura dell’hook rende semplice la revisione del codice personalizzato grazie alla corretta segnalazione dei deprecati. Gli hooks sono stati progettati per superare molte delle limitazioni dell’Ext e i punti di estensione disponibili crescono a ogni release di Liferay anche grazie ai feedback ricevuti da parte degli utenti.

Come fare a scegliere lo strumento di estensione più adeguato? Utilizzare gli hook dove possibile. Sono più semplici da implementare, installare, rimuovere e manutenere. Ricorre all’uso dell’Ext (Liferay Inc, 2012) solo nel caso in cui ciò che è richiesto non può essere soddisfatto tramite hook.

Nel prossimo paragrafo vedremo ciò che è possibile personalizzare tramite hook.

3. Cos’è possibile personalizzare tramite Hook

La strada consigliata per la personalizzazione delle funzioni base di Liferay, sono gli hooks (Liferay Inc, 2012) . Tramite gli hooks è possibile coprire un ampio spettro di necessità e dovrebbero essere utilizzati al posto dell’Ext, quando possibile. Gli hooks sono stati progettati per personalizzare fondamentalmente cinque caratteristiche principali del portale:

· Portal properties

· Language properties

· Web Resources

· Performing custom actions

· Services

Come per le portlet, layout e temi, anche gli hooks sono creati e gestiti utilizzando il Plugin SDK [2] .

Nella trattazione degli hooks e in particolare del caso di studio illustrato in seguito, vedremo i seguenti aspetti che saranno suddivisi in episodi diversi:

· Portal properties

· Performing custom action

· Web Resources

· Servlet filter hook

4. Creazione di un hook

Gli hooks risiedono all’interno della directory hooks del Plugin SDK. Esistono vari metodi che potete utilizzare per creare i vostri hooks alcuni dei quali sono:

· Developer Studio

· Comando create del Plugin SDK

· Apache Maven

Per maggiori approfondimenti sulla creazione degli hooks fare riferimento a (Liferay Inc, 2012) per i primi due punti mentre per l’ultimo consiglio la consultazione di (Koivisto, Getting started with Liferay Maven SDK, 2012) , (Koivisto, Developing Liferay Plugins with Maven, 2012) (Musarra, 2012)

5. Caso d’integrazione tramite Hook

Gli hooks possono essere molto efficaci nelle soluzioni d’integrazione tra Liferay e altri sistemi esterni. In questo paragrafo vedremo come poter sfruttare gli hooks come punto “d’intermediazione” tra Liferay e un sistema di CRM.

Macro architettura d’integrazione tra Liferay e CRM

Figura 1 Macro architettura d’integrazione tra Liferay e CRM.

La macro architettura d’integrazione mostrata in Figura 1 illustra chiaramente quali sono gli elementi interessati dal caso d’integrazione proposto. Volutamente sono stati evidenziati in nero gli elementi che riguardano il CRM per porre l’accento sul fatto che devono essere considerati vere e proprie scatole nere e concentrare l’attenzione verso gli hooks.

5.1 Ipotesi d’integrazione

Alcuni degli utenti memorizzati su Liferay (che accedono al portale) sono clienti dell’ipotetica azienda Dontesta Corporation Ltd (che vende prodotti per l’equitazione) e le schede commerciali dei clienti sono registrate sul sistema interno di CRM. Non necessariamente gli utenti definiti su Liferay sono clienti dell’azienda e di conseguenza gestiti sul CRM. L’esigenza dell’azienda è di dare la possibilità d’accesso diretto alle schede dei contatti e aziende direttamente dal portale Liferay.

Esempio di UI per accesso alle schede CRM del contatto e azienda

Figura 2 Esempio di UI per accesso alle schede CRM del contatto e azienda.

Il mockup [3] illustrato in Figura 1 è un buon esempio di come l’interfaccia utente su Liferay si dovrebbe presentare agli utenti per consentire loro l’accesso alle schede del CRM. Con un po’ d’occhio è possibile notare come il mockup di Figura 1 è spudoratamente vicinissimo alla lista Utenti e Organizzazioni accessibile da pannello di controllo di Liferay.

Garantire l’accesso alle schede (contatto e azienda) si traduce nella necessità di poter memorizzare alcuni dati presenti sul CRM come attributi aggiuntivi dell’utente Liferay. I dati da prelevare dal sistema di CRM sono:

· L’identificativo del contatto;

· L’identificativo dell'azienda cui il contatto appartiene.

I dati sopra menzionati sono indispensabili per comunicare al CRM quale contatto o azienda s’intende visualizzare. L’accesso ai dati del CRM da parte di Liferay avviene tramite la scatola nera CRM Integration API indicata nel diagramma di Figura 1 .

5.2 Dove memorizzare i dati del CRM

E’ plausibile pensare ai dati provenienti dal CRM come estensione del modello utente di Liferay, d’altronde questi dati arricchiscono l’utente di altre informazioni. Liferay mette a nostra disposizione uno strumento davvero potente che consente facilmente di realizzare quanto pensato e illustrato in Figura 3 .

Modello Utente Liferay esteso

Figura 3 Modello Utente Liferay esteso.

Sicuramente il nome di campi personalizzati (o custom fields) non suona del tutto nuovo, bene, questo è lo strumento con il quale definire sul modello utente due nuovi attributi (topic Extended CRM Attribute di Figura 3 ) specificandone anche il tipo:

· ContactId: attributo di tipo stringa il cui valore è l’identificativo (UUID [4] ) del contatto sul sistema di CRM;

· AccountId: attributo di tipo stringa il cui valore è l’identificativo (UUID) dell’azienda cui il contatto appartiene;

I due nuovi attributi creati per il modello utente di Liferay conterranno quindi i valori necessari per recuperare in seguito le informazioni di dettaglio del contatto e azienda. In Figura 4 è mostrato il dettaglio di un utente e in particolare sono evidenziati i valori dei due attributi ContactId e AccountId.

Dettaglio dell’utente con particole vista degli attributi CRM

Figura 4 Dettaglio dell’utente con particole vista degli attributi CRM.

5.3 Quando e come memorizzare i dati del CRM

Direi che siamo arrivati al punto interessante del caso d’integrazione. E’ stato definito l’obiettivo, i dati del CRM cui accedere e quale strumento utilizzare per memorizzare questi ultimi, non resta che altro che scoprire quando accedere al CRM per recuperare i dati di nostro interesse e come memorizzarli su i due nuovi attributi definiti in precedenza.

Il portale Liferay supporta un gran numero di eventi che accadono in certe situazioni e tramite hook è possibile quindi eseguire una o più azioni personalizzate (performing custom actions) al verificarsi di un determinato evento. Le azioni che sono eseguite per ognuno degli eventi supportati dal portale, sono definite nel file di configurazione portal.properties. Attraverso l’hook dovremmo quindi:

· Estendere il file di configurazione portal.properties;

· Creare la nuova azione da eseguire per un determinato evento.

Il tipo di evento che calza a pennello con il nostro caso d’integrazione è di user login e in particolare l’evento login post action. Quest’evento è idoneo per eseguire l’azione di recupero e memorizzazione dei dati ContactId e AccountId.

Processo di login sul portale Liferay

Figura 5 Processo di login sul portale Liferay.

Il processo mostrato in Figura 5 rende più chiaro il processo di login. Il diagramma mostra solamente la parte di processo di nostro interesse. L’evento di login post action è scatenato nel momento in cui è stato accertato che l’utente abbia inserito le corrette credenziali, a quel punto tramite l’Event Processor sono eseguite tutte le azioni definite dalla proprietà login.events.post. Il file portal.properties del nostro hook, dovrebbe contenere la configurazione mostrata al Listato 1 .

##

## Portal Events

##

#

# Login event

#

login.events.post=it.dontesta.liferay.portal.events.LoginPostAction

Listato 1 Definizione dell’azione da eseguire all’evento di login post action.

L’azione da eseguire nel momento in cui avviene l’evento, è una classe che estende la classe astratta com.liferay.portal.kernel.events.Action di cui occorre implementare il metodo com.liferay.portal.kernel.events.Action#run(). Ricordo che non siamo limitati a specificare una sola classe.

All’interno del metodo run() andrà inserito il codice necessario per eseguire i seguenti task:

· Recupero dell’utente che ha eseguito con successo il login;

· Prendere contatto con il CRM presentandosi con le credenziali dell’utente che ha appena eseguito il login;

· Recupero i dati d’interesse dal CRM, che ricordo essere, il ContactId e l’AccountId;

· Recupero l’Expando Bridge [5] sul modello dell’utente;

· Tramite l’ausilio dell’Expando Bridge memorizzo i dati ricevuti dal CRM nei rispettivi attributi estesi definiti in precedenza (vedi Figura 3 ).

package it.dontesta.liferay.portal.events;

/**

*

*/

public class LoginPostAction extends Action {

/*

* (non-Javadoc)

*

* @see com.liferay.portal.kernel.events.Action#run(javax.servlet.http.

* HttpServletRequest, javax.servlet.http.HttpServletResponse)

*/

@Override

public void run(HttpServletRequest request, HttpServletResponse response)

throws ActionException {

}

Listato 2 Classe che implementa l’azione da eseguire sull’evento login post action.

I dati così ottenuti e memorizzati sui campi personalizzati saranno utilizzati in seguito per accedere alle schede di dettaglio del CRM (Contatto e Azienda). In Figura 6 un piccolo assaggio.

Scheda di dettaglio Azienda aperta da Liferay

Figura 6 Scheda di dettaglio Azienda aperta da Liferay.

6. Conclusioni

Questo primo episodio è stato molto stringato sulla parte introduttiva degli hooks cercando comunque di sintetizzare al meglio gli aspetti più importanti per poi focalizzare l’attenzione su un caso di studio abbastanza vicino al reale. In questa prima parte, con l’aiuto del caso di studio, è stata affrontata la personalizzazione di Liferay tramite hooks, concentrandosi su, Portal properties e Performing custom action.

Nei prossimi episodi vedremo i rimanenti aspetti (Web Resources e Servlet filter hook) ultimando il caso di studio. A conclusione di tutti gli episodi ci sarà anche il regalo finale, il repository contenente i sorgenti del progetto oggetto di studio.

Bibliografia

Koivisto, M. (2012, Mar 3). Developing Liferay Plugins with Maven. Tratto da SlideShare: http://www.slideshare.net/koivimik/developing-liferay-plugins-with-maven

Koivisto, M. (2012, Feb 1). Getting started with Liferay Maven SDK. Tratto da Liferay Blog: http://www.liferay.com/it/web/mika.koivisto/blog/-/blogs/getting-started-with-liferay-maven-sdk

Liferay Inc. (2012). Creating a Hook. Tratto da Liferay Portal 6.1 - Development Guide: http://www.liferay.com/it/documentation/liferay-portal/6.1/development/-/ai/creating-a-ho-4

Liferay Inc. (2012). Ext plugins. Tratto da Liferay Portal 6.1 - Development Guide: http://www.liferay.com/it/documentation/liferay-portal/6.1/development/-/ai/ext-plugi-4

Liferay Inc. (2012). Hooks. Tratto da Liferay Portal 6.1 - Development Guide: http://www.liferay.com/it/documentation/liferay-portal/6.1/development/-/ai/hoo-4

Musarra, A. (2012, Oct 18). Creare progetti Liferay tramite il plugin m2eclipse (Maven for Eclipse). Tratto da Antonio Musarra's Blog: http://musarra.wordpress.com/2012/10/18/creare-progetti-liferay-tramite-il-plugin-m2eclipse-maven-for-eclipse/



[1] Il processo d’installazione o aggiornamento di componenti a un server in esecuzione senza arrestare e riavviare il server stesso.

[2] E’ un ambiente di sviluppo che aiuta nello sviluppo di tutti i tipi di plugin di Liferay basato sul Apache Ant, di recente è stata introdotta anche la possibilità di realizzare plugin tramite Apache Maven.

[3] Permockupsi intende comunemente la riproduzione di un oggetto originale ad uso didattico, dimostrativo, scenografico o di comunicazione visiva

[4] L'identificativo univoco universale(universally unique identifieroUUID) è un identificativo standard usato nelle infrastrutture software, standardizzato dallaOpen Software Foundation(OSF) come parte di un ambiente distribuito di computazione.

[5] E’ l’interfaccia d’accesso ai custom fields di un determinato model.

Precedente
Commenti
Aggiungi Commento
Andrea Fornelli
Ciao a tutti!
Mi sono da poco avvicinato a Liferay. Ho creato un hook per modificare la pagina "Users and Organizations" (all'interno del "Pannello di controllo") e aggiungergli un link nella select "Aggiungi" che permette di fare una importazione massiva di utenti a partire da un file csv. Il click mi porta in una jsp da me creata in cui, ho un form con un pulsante che dovrebbe fare l'upload sul server del file csv e poi importare massivamente gli utenti nel db. Per provare un semplice submit ho seguito le indicazioni al link http://www.liferay.com/it/community/wiki/-/wiki/Main/Struts+Action+Hook+Tips?_36_pageResourcePrimKey=21386817. Al submit riesco ad entrare nella classe java creata, ma poi ho il seguente errore
ERROR [http-bio-8080-exec-39][PortletRequestProcessor:453] Forward does not exist
nell'eseguire l'istruzione del metodo render.
Come e dove specifico la jsp a cui tornare(se rimango nella stessa da cui ho eseguito il submit)/andare(se passo ad un'altra jsp)?
Sarà una banalità, ma non mi funziona...Grazie
Inviato il 09/07/15 14.02.
Antonio Musarra
Ciao Andrea,
sul post che hai indicato è specificata la soluzione anche per il tipo d'errore da te specificato.

Dovresti specificare anche i forward per le action. Se non hai già letto ti consiglio di leggere il documento https://www.liferay.com/it/documentation/liferay-portal/6.1/development/-/ai/lp-6-1-dgen06-overriding-and-adding-struts-actions-0 che dovrebbe rispondere al caso tuo.

Bye,
Antonio.
Inviato il 09/07/15 14.02 in risposta a Andrea Fornelli.
Andrea Fornelli
Grazie Antonio,
con un pò di calma sono riuscito a risolvere e a leggere l'intero documento.
Mi sono scontrato con un altro problema: nell'aggiungere in maniera massiva gli utenti, attraverso il web service "addUser", mi sono accorto che gli utenti aggiunti sono tutti di default con stato uguale a 2 e quando faccio la ricerca da Liferay, mi vengono fuori solo se metto "qualsiasi stato".
Per renderli attivi, prima della chiamata al web service, ho settato, all'interno del ServiceContext, la property workflowAction con la costante WorkflowConstants.STATUS_APPROVED:
serviceContext.setWorkflowAction(WorkflowConstants.STATUS_APPROVED);
Sembra che nel DB memorizzi sempre il valore 2 allo stato dell'utente che inserisco, nonostante questa istruzione. La situazione strana è che Il valore della costante WorkflowConstants.STATUS_APPROVED è paria a 0 quando la verifico in debug (ci sono anche le costanti per settare inattivo, negato...). Come mai? E' estremamente importante, spero tu mi possa aiutare.
Grazie.
Inviato il 09/07/15 14.02 in risposta a Antonio Musarra.
Antonio Musarra
Ciao Andrea,
strano che lo inserisca in stato draft. Magari dopo l'operazione di add prova a fare l'operazione di update user o update status. Non appena ho qualche attivo vedrò di dare uno sguardo più in fondo.

Bye,
Antonio.
Inviato il 09/07/15 14.02 in risposta a Andrea Fornelli.
Salvatore Costanza
Ciao a tutti,
ho la necessità di permettere il login sia con email che con screenname.
Ho creato un hook nel quale sovrascrivo la struts action /login/login.
Nella mia recupero le preferences della portlet di login (dovrebbe essere la 58):

PortletPreferences portletPreferences = PortletPreferencesFactoryUtil.getPortletSetup(actionRequest, "58");

e poi se l'input inserito dall'utente non è una mail cambio ne cambio il valore:

portletPreferences.setValue("authType", CompanyConstants.AUTH_TYPE_SN);

Nell'invocazione della action originale:
originalStrutsPortletAction.processAction(originalStrutsPortletAction, portletConfig, actionRequest, actionResponse);

il valore arriva però a null.

Qualcuno sa darmi una mano?
Grazie
Inviato il 09/07/15 14.02.
Antonio Musarra
Buongiorno Salvatore e scusa del ritardo nella risposta.
Vado a memoria, e se non ricordo male, dovresti eseguire il commit delle modifiche eseguite alle preferenze della portlet tramite il metodo store.

Bye,
Antonio.
Inviato il 09/07/15 14.02 in risposta a Salvatore Costanza.