Project Agroal defines itself as “The natural database connection pool”. And that’s what is it.
It was developed by Luis Barreiro. He works for WildFly as a performance engineer. This prefigures what you can expect – a well performing database connection pool. As Agroal comes from the porfolio of the WildFly projects it offers smooth integration with WildFly and with Narayana too.
In the previous posts we checked other connection pools that you can use with Narayana - either the transactional driver provided by Narayana or DBCP2 which is nicely integrated to be used with Narayana in Apache Tomcat. Another option is the use of the IronJacamar which lives in the long-termed brotherhood with Narayana. All those options are nicely documented in our quickstarts.
Agroal is a party member and you should consider to check it. Either when running standalone application with Narayana or when you run on WildFly. Let’s take a look how you can use it in the standalone application first.
Agroal with Narayana standalone
In case you want to use the Agroal JDBC pooling capabilities with Narayana in your application you need to configure the Agroal datasource to know
- how to grab the instance of the Narayana transaction manager
- where to find the synchronization registry
- how to register resources to Narayana recovery manager
Narayana setup
First we need to gain all the mentioned Narayana objects which are then passed to Agroal which ensures the integration by calling the Narayana API at appropriate moments.
// gaining the transction manager and synchronization registry
TransactionManager transactionManager
= com.arjuna.ats.jta.TransactionManager.transactionManager();
TransactionSynchronizationRegistry transactionSynchronizationRegistry
= new com.arjuna.ats.internal.jta.transaction.arjunacore.TransactionSynchronizationRegistryImple();
// intitialization of recovery manager
RecoveryManager recoveryManager
= com.arjuna.ats.arjuna.recovery.RecoveryManager.manager();
recoveryManager.initialize();
// recovery service provides binding for hooking the XAResource to recovery process
RecoveryManagerService recoveryManagerService
= new com.arjuna.ats.jbossatx.jta.RecoveryManagerService();
recoveryManagerService.create();
Agroal integration
Now we need to pass the Narayana's object instances to Agroal.
With that being done we can obtain a JDBC Connection
which is backed by the transaction manager.
AgroalDataSourceConfigurationSupplier configurationSupplier
= new AgroalDataSourceConfigurationSupplier()
.connectionPoolConfiguration(cp -> cp
.transactionIntegration(new NarayanaTransactionIntegration(
transactionManager, transactionSynchronizationRegistry,
"java:/agroalds1", false, recoveryManagerService))
cf.connectionFactoryConfiguration(cf ->
.jdbcUrl("jdbc:h2:mem:test")
.principal(new NamePrincipal("testuser"))
.credential(new SimplePassword("testpass"))
.recoveryPrincipal(new NamePrincipal("testuser"))
.recoveryCredential(new SimplePassword("testpass"))
.connectionProviderClassName("org.h2.jdbcx.JdbcDataSource"))
.maxSize(10)
);
AgroalDataSource ds1 = AgroalDataSource.from(configurationSupplier);
transactionManager.begin();
conn1 = ds1.getConnection();
...
Those are steps needed for the standalone application to use Narayana and Agroal. The working code example could be seen in the Narayana quickstart at github.com/jbosstm/quickstart#agroal - AgroalDatasource.java
Agroal XA datasource in WildFly
If you want to use the power of Narayana in the WildFly application you need XA participants that Narayana can drive. From Agroal perspective you need to define a xa datasource which you use (linked via JNDI name) in your application.
DISCLAIMER: for you can use the Agroal capabilities integrated with Narayana you will need to run WildFly 15 or later. Currently only WildFly 14 is available so for testing this you need to build the WildFly from sources by yourself. The good message is that’s an easy task – see at https://github.com/wildfly/wildfly/#building.
Agroal datasource subsystem is not available by default in the standalone.xml
file so you need to enable that extension. When you run the jboss cli
commands then you do it like this
cd $JBOSS_HOME
./bin/jboss-cli.sh -c
# jboss-cli is started, run following command there
/extension=org.wildfly.extension.datasources-agroal:add
/subsystem=datasources-agroal:add()
:reload
From now you can work with the datasources-agroal
subsystem. For you can create the xa-datasource
definition you need to have a driver which the datasource will use. The driver has to define it’s XA connection provider.
NOTE: if you want to check what are options for the Agroal configuration in the jboss cli then read the resource description with command
/subsystem=datasources-agroal:read-resource-description(recursive=true)
Agroal driver definition works only with drivers deployed as modules.
You can’t just copy the driver jar to $JBOSS_HOME/standalone/deployments
directory but you need to create a module under $JBOSS_HOME/modules
directory.
See details either by creating module.xml
by yourself or the recommended way
is using the jboss cli
with command
module add --name=org.postgresql
--resources=/path/to/jdbc/driver.jar --dependencies=javax.api,javax.transaction.api
NOTE: The command uses the name of the module org.postgresql
as I will demonstrate adding the xa datasource for the PostgreSQL database.
When the module is added we can declare the Agroal’s driver.
/subsystem=datasources-agroal/driver=postgres:add(
module=org.postgresql, class=org.postgresql.xa.PGXADataSource)
We’ve used the class org.postgresql.xa.PGXADataSource
as we want to use it as XA datasource. When class is not defined then standard jdbc driver for PostgresSQL is used (org.postgresql.Driver
) as declared in the META-INF/services/java.sql.Driver
file.
NOTE: If you would declare the driver without the XA datasource being defined and then you try to add it to XA datasource definition you will get an error
/subsystem=datasources-agroal/driver=non-xa-postgres:add(module=org.postgresql)
/subsystem=datasources-agroal/xa-datasource=AgroalPostgresql:add(
connection-factory={driver=non-xa-postgres},...)
{
"outcome" => "failed",
"failure-description" => {"WFLYCTL0080: Failed services" => {"org.wildfly.data-source.AgroalPostgresql"
=> "WFLYAG0108: An xa-datasource requires a javax.sql.XADataSource as connection provider. Fix the connection-provider for the driver"}
},
"rolled-back" => true
}
When the JDBC driver module is defined we can create the Agroal XA datasource. The bare minimum of attributes you have to define is shown in the following command
/subsystem=datasources-agroal/xa-datasource=AgroalPostgresql:add(
jndi-name=java:/AgroalPostgresql, connection-pool={max-size=10}, connection-factory={
driver=postgres, username=test, password=test,url=jdbc:postgresql://localhost:5432/test})
NOTE: this is the most simple way of define the credentials for the connection to database. If you consider more sophisticated method, than just username/password as clear strings saved in the standalone.xml, take a look at the Elytron capabilities.
To check if the WildFly Agroal datasource is able to connect to the database you can use test-connection command
/subsystem=datasources-agroal/xa-datasource=AgroalPostgresql:test-connection()
If you are insterested how the configuration looks as a xml element in standalone.xml
configuration file then the Agroal subsystem with PostgreSQL XA datasource definition would look like
<subsystem xmlns="urn:jboss:domain:datasources-agroal:1.0">
<xa-datasource name="AgroalPostgresql" jndi-name="java:/AgroalPostgresql">
<connection-factory driver="postgres" url="jdbc:postgresql://localhost:5432/test"
username="test" password="test"/>
<connection-pool max-size="10"/>
</xa-datasource>
<drivers>
<driver name="postgres" module="org.postgresql" class="org.postgresql.xa.PGXADataSource"/>
</drivers>
</subsystem>
If you want use the Agroal non-xa datasource as commit markable resource (CMR) it’s possible too. You need to create a standard datasource and define it as connectable. For more information what the commit markable resource means and how it works check our previous blogpost about CMR.
<subsystem xmlns="urn:jboss:domain:datasources-agroal:1.0">
<datasource name="AgroalPostgresql" connectable="true" jndi-name="java:/AgroalPostgresql"
statistics-enabled="true">
<connection-factory driver="postgres" url="jdbc:postgresql://localhost:5432/test"
username="test" password="test"/>
<connection-pool max-size="10"/>
</datasource>
<drivers>
<driver name="postgres" module="org.postgresql" class="org.postgresql.Driver"/>
</drivers>
</subsystem>
NOTE: In addition to this configuration of Agroal datasource you need to enable the CMR in the transaction subsystem too – check the blogpost for detailed info.
Summary
This blogpost showed way how to configure Agroal JDBC pooling library and how to integrate it with Narayana.
The code example is part of the Narayana quickstart and you can check it at
https://github.com/jbosstm/quickstart/tree/master/agroal
No comments:
Post a Comment