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

Collegarsi a datasource esterni con Liferay DXP

Parecchio tempo fa avevamo già affrontato la problematica di accedere a database esterni a Liferay per leggere (e scrivere) informazioni; se vi siete persi il post potete rileggerlo qui prima di procedere.

Con l'uscita di Liferay DXP alcune cose sono cambiate ma è sempre possibile collegarsi ad un database esterno; vediamo cosa è cambiato e come fare.

Iniziamo con la definizione dei parametri di connessione al database esterno e qui si aprono subito 2 possibili alternative. Infatti se abbiamo definito i parametri di connessione del database di Liferay all'interno del file portal-ext.properties allora dobbiamo definire i parametri di connessione del database esterno sempre nello stesso file:

jdbc.ext.driverClassName=<DRIVER_CLASS_NAME>
jdbc.ext.url=<CONNECTION_URL>
jdbc.ext.username=<USERNAME>
jdbc.ext.password=<PASSWORD>
jdbc.ext.connectionTestQuery=<CONNECTION_TEST_QUERY> (se serve)

Il nome finale delle property (driverClassName, url, ...) è standard di portale e non può essere cambiato ma il prefisso (jdbc.ext.) è a discrezione dell'utente che può quindi definire tutte le connessioni esterne che servono.

Se invece abbiamo definito i parametri di connessione del database di Liferay nel file context.xml di Tomcat, allora dobbiamo creare la connessione in questo file.

Dopodichè dobbiamo creare un nuovo bundle di tipo servicebuilder; la particolarità di Liferay DXP è che bisognerà creare un bundle differente per ogni connessione ad un database esterno e questo a causa di una limitazione (bug?) del prodotto. In fondo non è un grosso problema, ma basta saperlo e risparmierete un sacco di tempo indecision.

Prima di procedere assicuriamoci che il bundle *-service abbia le seguenti dipendenze:

dependencies {
    compileOnly group: "biz.aQute.bnd", name: "biz.aQute.bndlib", version: "3.1.0"
    compileOnly group: "com.liferay", name: "com.liferay.osgi.util", version: "3.0.0"
    compileOnly group: "com.liferay", name: "com.liferay.portal.spring.extender", version: "2.0.0"
    compileOnly group: "com.liferay.portal", name: "com.liferay.portal.kernel", version: "2.6.0"
    compileOnly project(":modules:my-external-db:my-external-db-api")
}

A questo punto possiamo creare nel file service.xml le entità del database esterno (e solo loro!):

<entity name="Foo" local-service="true" table="Foo" data-source="extDataSource">
    ...
</entity>

Fate attenzione ai nomi dell'entità e dei campi perchè sembra che il Service Builder non crei correttamente il mapping tra i nomi; quindi consiglio di mantenere gli stessi nomi usati nel database esterno specificando esplicitamente anche l'attributo table, nonostante sia uguale al nome.

A differenza di quello che si faceva nella versione 6.2, ora è sufficiente specificare solamente l'attributo data-source; questo perchè quello che si fa su Liferay DXP è ridefinire il data source di default di Liferay (ovviamente solo per il bundle in oggetto) e quindi session factory e transaction manager rimangono associati al loro data source di partenza (che viene sovrascritto).

A questo punto è possibile lanciare il task Gradle build-service per generare tutto lo strato di persistenza.

Una volta terminato il task, andiamo a creare il file ext-spring.xml nella cartella /src/main/resources/META-INF/spring; il suo contenuto sarà leggermente diverso a seconda di come è stata definita la connessione al database esterno.

Nel caso in cui abbiate configurato la connessione all'interno del file portal-ext.properties, dovete definire il file nel modo seguente:

<?xml version="1.0"?>

<beans default-destroy-method="destroy" default-init-method="afterPropertiesSet"
    xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

    <bean class="com.liferay.portal.dao.jdbc.spring.DataSourceFactoryBean" id="liferayDataSourceImpl">
        <property name="propertyPrefix" value="jdbc.ext." />
    </bean>

    <bean class="org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy" id="liferayDataSource">
        <property name="targetDataSource" ref="liferayDataSourceImpl" />
    </bean>

    <alias alias="extDataSource" name="liferayDataSource" />
</beans>

I punti importanti da segnalare sono quelli evidenziati in grassetto:

  • La proprietà propertyPrefix va definita con il prefisso utilizzato per definire i vari parametri di connessione, nel nostro caso vale jdbc.ext. (con il . finale mi raccomando);
  • Il data source viene definito usando come identificativo liferayDataSource, che è quello predefinito di Liferay e quindi stiamo sovrascrivendo la connessione di default (ma solo per il bundle in oggetto);
  • Alla fine creiamo un alias per il data source, che sarà da utilizzare nel file service.xml; fate attenzione ad utilizzare lo stesso valore in entrambi i file.

Se invece avete definito la connessione al database esterno nel file context.xml di Tomcat, dovete definire il file nel modo seguente:

<?xml version="1.0"?>

<beans default-destroy-method="destroy" default-init-method="afterPropertiesSet"
    xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

    <bean class="com.liferay.portal.dao.jdbc.spring.DataSourceFactoryBean" id="liferayDataSourceImpl">
        <property name="propertyPrefix" value="jdbc.ext." />
        <property name="properties">
            <props>
                <prop key="jdbc.ext.jndi.name">jdbc/SQLServerPool</prop>
            </props>
        </property>
    </bean>

    <bean class="org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy" id="liferayDataSource">
        <property name="targetDataSource" ref="liferayDataSourceImpl" />
    </bean>

    <alias alias="extDataSource" name="liferayDataSource" />
</beans>

In questo caso, oltre alla proprietà propertyPrefix, va definita anche la proprietà properties che conterrà il nome della referenza JNDI al database esterno; fate attenzione a definire la chiave della proprietà con lo stesso prefisso impostato su propertyPrefix ed il valore della proprietà con lo stesso valore impostato nel file context.xml.

Ora potete deployare il plugin e, se tutto funziona correttamente, vedrete nei log un messaggio di avvenuta connessione al database esterno.

Enjoy!

Commenti
Aggiungi Commento
Paolo Gambetti
Con Liferay versione 7.1 sono necessarie alcune modifiche:

1) Il file ext-spring.xml non deve essere creato nella cartella /src/main/resources/META-INF/spring ma nella cartella /src/main/resources/META-INF/spring/parent

2) Nel file bnd.bnd dei service che utilizzano datasource esterni aggiungere le sequenti righe:

Import-Package: \
com.liferay.portal.dao.jdbc.spring,\
org.springframework.jdbc.datasource,\
*
Inviato il 21/10/19 17.56.