Seleccionar página

Este artículo es una evolución del post anterior «Crear un datasource en Apache Karaf (1 de 2)» en el que el datasource en Apache Karaf no se declara utilizando la implementación del propio driver JDBC de MySQL sino que utilizamos el pool de conexiones implementado por Apache Commons DBCP 2.

En el ejemplo precedente, la librería mysql-connector-java-8.0.27.jar y el fichero mysql8-with-mysql-connector-java-ds.xml estan desplegados directamente en el directorio $KARAF_HOME/deploy; al instanciarse el datasource, éste es capaz de encontrar la clase com.mysql.cj.jdbc.MysqlXADataSource que está dentro del driver jdbc de MySQL.

En este caso, creamos el siguiente fichero mysql8-dbc2-ds.xml para configurar el datasource con este pool de conexiones a la base de datos MySQL :

<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">

    <bean id="dbcp2Datasource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close">

        <property name="driverClassName" value="com.mysql.cj.jdbc.Driver" />
        <property name="url" value="jdbc:mysql://localhost:3306/test" />

        <property name="username" value="neodoo" />
        <property name="password" value="neodoo" />

        <!--
        <property name="initialSize" value="5"/>
        <property name="validationQuery" value="select 1" />

        <property name="maxTotal" value="32" />
        <property name="maxIdle" value="10" />
        <property name="maxWaitMillis" value="30000" />
        <property name="removeAbandonedOnBorrow" value="true" />
        <property name="removeAbandonedTimeout" value="30" />
        <property name="testOnBorrow" value="true" />

        <property name="timeBetweenEvictionRunsMillis" value="1800"/>
        <property name="minEvictableIdleTimeMillis" value="1800"/>
        <property name="testWhileIdle" value="true"/>
        <property name="testOnReturn" value="true"/>
        -->

    </bean>

    <service interface="javax.sql.DataSource" ref="dbcp2Datasource">

        <service-properties>
            <entry key="osgi.jndi.service.name" value="jdbc/mysql8"/>
        </service-properties>

    </service>

</blueprint>

Este ejemplo nos invita a realizar el mismo procedimiento que en el post anterior (es decir copiar directamente la librería JDBC y este fichero en el directorio $KARAF_HOME/deploy) pero si lo hacemos así, este datasource no es capaz de acceder a las clases compiladas del driver JDBC de MySQL.

El procedimiento del post anterior no se puede realizar ya que el fichero mysql8-with-dbcp2-ds.xml se comporta como un bundle OSGI e importa la librería de Apache DBCP2 al aparecer declarado en el fichero XML pero no es capaz de importar el driver JDBC de MySQL.

Nota: Una forma de resolver este problema consistiría en recompilar y empaquetar la librería del proyecto Apache Commons DBCP 2 incluyendo en el fichero META-INF/MANIFEST.MF la librería JDBC de MySQL en la sección de Import-Package para que este bundle OSGI sepa que la necesita del exterior. A continuación, bastaría con desplegar la librería regenerada incluyendo también la dependencia a Apache Commons Pool 2 en el directorio $KARAF_HOME/deploy.

No obstante, no utilizaremos este procedimiento y haremos que la librería del driver jdbc MySQL se cargue directamente en el propio motor de OSGI.

Para ello, realizamos la siguiente modificación en la sección org.osgi.framework.system.packages.extra del fichero $KARAF_HOME/etc/config.properites para indicarle los paquetes de del driver MySQL :

...

#
# Extra packages appended after standard packages
#
org.osgi.framework.system.packages.extra = \
    org.apache.karaf.branding, \
    sun.misc, \
    com.sun.jmx.remote.protocol, \
    com.sun.jmx.remote.protocol.jmxmp, \
    com.mysql.cj.jdbc,\
    com.mysql.jdbc,\
    org.apache.karaf.jaas.boot.principal;uses:=javax.security.auth;version=4.3.3, \
   org.apache.karaf.jaas.boot;uses:=\"javax.security.auth,javax.security.auth.callback,javax.security.auth.login,javax.security.auth.spi,org.osgi.framework\";version=4.3.3, \
    org.apache.karaf.diagnostic.core;uses:=org.osgi.framework;version=4.3.3, \
    org.apache.karaf.diagnostic.core.common;uses:=org.apache.karaf.diagnostic.core;version=4.3.3

...

A continuación copiamos la librería mysql-connector-java-8.0.27.jar en el directorio $KARAF_HOME/lib/boot.

Ahora sólo necesitamos rearrancar el servidor de Apache Karaf y automáticamente ya dispondremos del bundle de MySQL cargado en memoria.

Una vez conectados en la consola de Karaf, instalamos los siguientes features :

karaf@root()> feature:install jdbc jndi deployer aries-blueprint 

Instalamos Apache Commons DBCP2 a través de la siguiente utilizando un feature :

karaf@root()> feature:install pax-jdbc-pool-dbcp2 

En este punto, podemos verificar que el datasource se ha creado correctamente :

karaf@root()> jdbc:ds-list 
Name        │ Service Id │ Product │ Version                 │ URL                              │ Status
────────────┼────────────┼─────────┼─────────────────────────┼──────────────────────────────────┼───────
jdbc/mysql8 │ 141        │ MySQL   │ 8.0.27-0ubuntu0.21.10.1 │ jdbc:mysql://localhost:3306/test │ OK
karaf@root()> jdbc:ds-info jdbc/mysql8
Property       │ Value
───────────────┼─────────────────────────────────────────────────────────────────────────────────
driver.version │ mysql-connector-java-8.0.27 (Revision: e920b979015ae7117d60d72bcc8f077a839cd791)
service.id     │ 141
db.version     │ 8.0.27-0ubuntu0.21.10.1
name           │ jdbc/mysql8
db.product     │ MySQL
url            │ jdbc:mysql://localhost:3306/test
driver.name    │ MySQL Connector/J
username       │ root@localhost
karaf@root()> jndi:names 
JNDI Name                │ Class Name
─────────────────────────┼────────────────────────────────────────────────
osgi:service/jndi        │ org.apache.karaf.jndi.internal.JndiServiceImpl
osgi:service/jdbc/mysql8 │ com.mysql.cj.jdbc.MysqlConnectionPoolDataSource
karaf@root()> 

Instalamos Apache Camel y los conectores utilizados en el proyecto de rutas :

karaf@root()> feature:repo-add camel
Adding feature url mvn:org.apache.camel.karaf/apache-camel/RELEASE/xml/features
karaf@root()> feature:install camel camel-sql

Desplegamos el fichero routes-with-datasource.xml en el directorio $KARAF_HOME/deploy :

<?xml version="1.0" encoding="UTF-8"?>
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" default-activation="lazy">

    <!-- Reference to external datasource using jndi -->
    <reference id="dataSource" interface="javax.sql.DataSource"
        filter="(osgi.jndi.service.name=jdbc/mysql8)">
    </reference>

    <bean id="sql" class="org.apache.camel.component.sql.SqlComponent">
        <property name="dataSource" ref="dataSource" />
    </bean>

    <camelContext id="routes-with-datasource" xmlns="http://camel.apache.org/schema/blueprint">

       <route id="route-with-sql-component">
           <from uri="timer://foo?repeatCount=1" />
           <to uri="sql:select * from Task" />
          <log message="[SQL] Received: ${body}"/>
       </route>

    </camelContext>

</blueprint>

A continuación el proyecto se desplegará y para confirmarlo, puedes consultar el fichero $KARAF_HOME/data/log/karaf.log para confirmar la ejecución de la ruta.

Con este segundo post, te mostramos las dos formas de declarar un datasource de forma global a todos tus proyectos, incluso en los que incorporan el soporte JPA.

Pin It on Pinterest