Wednesday, December 17, 2008

How to share a single JDBC Pool across SMX4 bundles

In the last week I have been working on a solution involving a number of Camel routes deployed into FUSE ESB 4 (ServiceMix4). The new OSGi archetypes for ServiceMix4 (servicemix-osgi-camel-archetype, servicemix-osgi-cxf-code-first-archetype and servicemix-osgi-cxf-wsdl-first-archetype) are really handy in that regard - nice work Ashwin Karpe! Those new archetypes have been checked in to SVN, but may not be in the release build yet so if you want them you may need to check them out and build them locally.

Because SMX4 is built on OSGi, you can deploy any Java artifact, not just JBI components. I put this to the test: my customer wanted to have a single, shared JDBC pool across all of his bundles. You can do this by creating the pool in a simple Spring file, and registering it as a service for all the other bundles to use. To do this, I installed the driver for PostgreSQL into my SMX container, using the nifty "wrap:" feature that will take a jar and osgi-ify it. Then, I created a Spring context file to intantiate the bean, like this:


<bean id="postgresPoolingDS" class="org.postgresql.ds.PGPoolingDataSource">
<property name="serverName" value="localhost"/>
<property name="databaseName" value="play"/>
<property name="portNumber" value="0"/>
<property name="user" value="play"/>
<property name="password" value="pa55w0rd"/>
<property name="dataSourceName" value="postgres"/>
<property name="initialConnections" value="1"/>
<property name="maxConnections" value="100"/>
</bean>

<osgi:service id="postgresPoolingDSService" ref="postgresPoolingDS"
auto-export="all-classes"/>


Here's the really neat bit: when you drop this spring file into the deploy directory of ServiceMix 4, the ServiceMix kernel will osgi-ify the file and deploy it as a bundle. Hey-presto: the pool is created and registered as a service in the OSGi service registry.

To access this service from one of my camel routes, I used the <osgi:reference> to get a reference to the dataSource in my bundle's spring file. You can then inject the reference into your route and away you go.


<osgi:reference id="dataSource" interface="javax.sql.DataSource" />


The "look-up" is done by interface type: in this case I'm OK as there's only one javax.sql.DataSource registered. I should really do a more explicit query, but I guess I'll leave that as an exercise for the interested reader.

For me, this kind of thing is OSGi at its best: allowing sharing and reuse of Java classes and Java objects in a really nice, modular way.

5 comments:

Anderson Nielson said...

How did you install the Postgress driver? Did you put the Postgress jars in the deploy folder too?

Matteo said...

please, can anyone explain (or better post a full example about) how to share MORE than one connection pool? Thank

Matteo
http://www.redaelli.org/matteo/

cmoulliard said...

Hi Adrian,

Can you explain How you have used the wrap: feature to osgified the jar ?

Charles

malgravajhoj said...

To use more than one connection pool, just use the service-proeprties and filter as explained at http://static.springframework.org/osgi/docs/1.1.3/reference/html-single/#service-registry:export:props

get said...

I am using iBatis DAO & able to use share connection but I require transaction manager where my DAO Manager class will call 2 DAO & if 1 fail. I tried many ways in Spring DM but fail, any idea?