Chapter 8. About Java connector architecture
The JCA specification was created to (among other things) generalize the scenarios that have these three participants:
- An external system such as a database or generally an EIS system
- A JavaEE application server
- A deployed application
8.1. Simple JDBC analogy
In the simplest scenario, where there is only an application and database, you have:
Adding an application server that exposes javax.sql.DataSource
, you have the following (without recalling different aspects of data sources like XA):
8.2. Overview of using JCA
JCA generalizes the concept of a database driver by adding two-way communication between the driver and the application server. The driver becomes a resource adapter that is represented by javax.resource.spi.ResourceAdapter
.
There are two important interfaces:
-
javax.resource.spi.ManagedConnectionFactory
implemented by a resource adapter. -
javax.resource.spi.ConnectionManager
implemented by an application server.
The ManagedConnectionFactory
interface serves two purposes:
The
Object createConnectionFactory(ConnectionManager cxManager)
method may be used to produce a connection factory for a given EIS (or database or message broker) that can be used by application code. The returnedObject
may be:-
A generic
javax.resource.cci.ConnectionFactory
(not described here further, see JCA 1.6, chapter 17: Common Client Interface) -
EIS specific connection factory like the well-known
javax.sql.DataSource
orjavax.jms.ConnectionFactory
. That is the type of connection factory that is used by thepax-transx-jdbc
andpax-transx-jms
bundles.
-
A generic
-
The
javax.resource.spi.ManagedConnection ManagedConnectionFactory.createManagedConnection()
method used by an application server, creates actual physical connections to the EIS/database/broker.
ConnectionManager
is implemented by an application server and used by a resource adapter. It is the application server that first performs QoS operations (pooling, security, transaction management) and finally delegates to the ManagedConnectionFactory
of the resource adapter to create ManagedConnection
instances. The flow looks like this:
-
Application code uses connection factory created and exposed by application server using object returned from
ManagedConnectionFactory.createConnectionFactory()
. It may be generic CCI interface or e.g.,javax.sql.DataSource
. -
this connection factory doesn’t create connections on its own, instead it delegates to
ConnectionManager.allocateConnection()
passing resource adapter-specificManagedConnectionFactory
-
ConnectionManager
implemented by application server creates supporting objects, manages transactions, pooling, etc. and eventually obtains physical (managed) connection from passedManagedConnectionFactory
. - Application code gets connection which is usually a wrapper/proxy created by application server which eventually delegates to resource adapter's specific physical connection.
Following is the diagram, where application server created non-CCI connection factory which is EIS-specific. Simply - access to EIS (here: database) is done using javax.sql.DataSource
interface, the driver’s task is to provide physical connection, while application server will wrapp it inside (typically) a proxy that does pooling/enlisting/security.
8.3. About the pax-transx project
The pax-transx
project provides support for JTA/JTS transaction management in OSGi, as well as resource pooling for JDBC and JMS. It closes the gap between pax-jdbc
and pax-jms
.
-
pax-jdbc
adds configuration options and discovery forjavax.sql.(XA)ConnectionFactory
services and ships some JDBC pooling implementations -
pax-jms
does the same forjavax.jms.(XA)ConnectionFactory
services and ships some JMS pooling implementations -
pax-transx
adds configuration options and discovery forjavax.transaction.TransactionManager
implementations and (finally) provides JCA-based JDBC/JMS connection management with pooling and tranasction support.
The sections about JDBC connection pools and about JMS connection pools are still valid. The only change needed to use JCA-based pools is to use pool=transx
properties when registering JDBC data sources and JMS connection factories.
-
pax-jdbc-pool-transx
usesorg.ops4j.pax.transx.jdbc.ManagedDataSourceBuilder
frompax-transx-jdbc
-
pax-jms-pool-transx
usesorg.ops4j.pax.transx.jms.ManagedConnectionFactoryBuilder
frompax-transx-jms
While the pooled data sources/connection factories are created in builder style (no Java™ bean properties), these properties are supported for JDBC:
-
name
-
userName
-
password
-
commitBeforeAutocommit
-
preparedStatementCacheSize
-
transactionIsolationLevel
-
minIdle
-
maxPoolSize
-
aliveBypassWindow
-
houseKeepingPeriod
-
connectionTimeout
-
idleTimeout
-
maxLifetime
These properties are supported for JMS:
-
name
-
userName
-
password
-
clientID
-
minIdle
-
maxPoolSize
-
aliveBypassWindow
-
houseKeepingPeriod
-
connectionTimeout
-
idleTimeout
-
maxLifetime
userName
and password
properties are needed for XA recovery to work (just like it was with aries.xa.username
and aries.xa.password
properties in Fuse 6.x).
With this JDBC configuration in Blueprint (mind pool=transx
):
<!-- Database-specific, non-pooling, non-enlisting javax.sql.XADataSource --> <bean id="postgresql" class="org.postgresql.xa.PGXADataSource"> <property name="url" value="jdbc:postgresql://localhost:5432/reportdb" /> <property name="user" value="fuse" /> <property name="password" value="fuse" /> <property name="currentSchema" value="report" /> <property name="connectTimeout" value="5" /> </bean> <!-- Expose database-specific data source with service properties No need to expose pooling, enlisting, non database-specific javax.sql.DataSource - it'll be registered automatically by pax-jdbc-config with the same properties as this <service>, but with higher service.ranking --> <service id="pool" ref="postgresql" interface="javax.sql.XADataSource"> <service-properties> <!-- "pool" key is needed for pax-jdbc-config to wrap database-specific data source inside connection pool --> <entry key="pool" value="transx" /> <!-- <service>/@id attribute doesn't propagate, but name of the datasource is required using one of: --> <entry key="osgi.jndi.service.name" value="jdbc/postgresql" /> <!-- or: --> <!--<entry key="dataSourceName" value="jdbc/postgresql" />--> <!-- Other properties, that normally are needed by e.g., pax-jdbc-pool-transx --> <entry key="pool.maxPoolSize" value="13" /> <entry key="pool.userName" value="fuse" /> <entry key="pool.password" value="fuse" /> </service-properties> </service>
And with this JMS configuration in Blueprint (mind pool=transx
):
<!-- Broker-specific, non-pooling, non-enlisting javax.jms.XAConnectionFactory --> <bean id="artemis" class="org.apache.activemq.artemis.jms.client.ActiveMQXAConnectionFactory"> <argument index="0" value="tcp://localhost:61616" /> <!-- credentials needed for JCA-based XA-recovery --> <argument index="1" value="admin" /> <argument index="2" value="admin" /> <property name="callTimeout" value="2000" /> <property name="initialConnectAttempts" value="3" /> </bean> <!-- Expose broker-specific connection factory with service properties No need to expose pooling, enlisting, non broker-specific javax.jms.XAConnectionFactory - it'll be registered automatically by pax-jms-config with the same properties as this <service>, but with higher service.ranking --> <service id="pool" ref="artemis" interface="javax.jms.XAConnectionFactory"> <service-properties> <!-- "pool" key is needed for pax-jms-config to wrap broker-specific connection factory inside connection pool --> <entry key="pool" value="transx" /> <!-- <service>/@id attribute doesn't propagate, but name of the connection factory is required using one of: --> <entry key="osgi.jndi.service.name" value="jms/artemis" /> <!-- or: --> <!--<entry key="name" value="jms/artemis" />--> <!-- Other properties, that normally are needed e.g., pax-jms-pool-transx --> <entry key="pool.maxPoolSize" value="13" /> <entry key="pool.userName" value="admin" /> <entry key="pool.password" value="admin" /> </service-properties> </service>
You have a JDBC data source and a JMS connection factory registered that leverage JCA-based resource management. transx-based pools will properly integrate with pax-transx-tm-narayana
with respect to XA recovery.
The features that are needed are:
-
pax-jdbc-pool-tranx
-
pax-jms-pool-tranx
-
pax-transx-jdbc
-
pax-transx-jms
-
pax-jms-artemis
(when using A-MQ 7)