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 .
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!