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 returned Object 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 or javax.jms.ConnectionFactory . That is the type of connection factory that is used by the pax-transx-jdbc and pax-transx-jms bundles. 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 -specific ManagedConnectionFactory ConnectionManager implemented by application server creates supporting objects , manages transactions, pooling, etc. and eventually obtains physical (managed) connection from passed ManagedConnectionFactory . 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 for javax.sql.(XA)ConnectionFactory services and ships some JDBC pooling implementations pax-jms does the same for javax.jms.(XA)ConnectionFactory services and ships some JMS pooling implementations pax-transx adds configuration options and discovery for javax.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 uses org.ops4j.pax.transx.jdbc.ManagedDataSourceBuilder from pax-transx-jdbc pax-jms-pool-transx uses org.ops4j.pax.transx.jms.ManagedConnectionFactoryBuilder from pax-transx-jms While the pooled data sources/connection factories are created in builder style (no JavaTM 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)

Commands:
<!-- 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>
<!-- 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>