2
votes

WSO2 Identity Server 5.0.0 (and some patches ;))

It does not appear that custom JDBC user store managers (child of JDBCUserStoreManager) use a JDBC pool. I'm noticing that I can end up session closed errors and sql exceptions whereas the Identity Server itself is still operating OK with its separate database connection (a configured pool).

So I guess I have two questions about this:

  1. Somewhere up the chain, is there a JDBC pool for the JDBCUserStoreManager? If so, are there means to configure that guy more robustly?
  2. Can I create another JDBC datasource in master-datasources.xml which my custom JDBC user store manage could reference?
2

2 Answers

1
votes

Instead of using your own datasources/connections, you can import Carbon Datasources and use those (they come with inbuilt pooling and no need to worry about any configurations etc). You can either access these programmatically by directly calling ndatasource component or access them via JNDI.

To access them directly from ndatasource component:
The dependency:

<dependency>
  <groupId>org.wso2.carbon</groupId>
  <artifactId>org.wso2.carbon.ndatasource.core</artifactId>
  <version>add_correct_version_here</version>
</dependency>

(You can check repository/components/plugins to find out the correct version for above dependency)
You can inject DataSourceService as in this code (the @scr.reference tag refers to the service you need to inject, this uses maven scr plugin to parse these dependencies when building the bundle).

Note that when you follow this approach you'll have to build the jar as an OSGi bundle as it uses declarative services (and have to place it in repository/components/dropins). Otherwise the dependencies won't be injected at runtime.

Next, you can access all the data sources as:

List<CarbonDataSource> dataSources = dataSourceService.getAllDataSources();
1
votes

Rajeev's answer was really insightful and helped with investigating and evaluating what I should do. But, I didn't end up using that route. :)

I ended up looking through the Identity Server and Carbon source code and found out that the JDBCUserStoreManager does end up creating a JDBC pool configured by the properties you set for that manager. I had a class called CustomUserStoreConstants for my custom user store manager which had setMandatoryProperty called by default to set:

  • JDBCRealmConstants.DRIVER_NAME
  • JDBCRealmConstants.URL
  • JDBCRealmConstants.USER_NAME
  • JDBCRealmConstants.PASSWORD

So the pool was configured with these values, BUT that was it...nothing else. So no wonder it wasn't surviving the night!

It turned out that the code setting this up, if it found a value for the JDBCRealmConstants.DATASOURCE in the config params, it would just load up that datasource and ignore any other params set. Seeing that, I got rid of those 4 params listed above and forced my custom user store to only allow having a DATASOURCE and I set it in code with the default JNDI name that I would name that datasource always. With that, I was able to configure my JDBC pool for this datasource with all params such as testOnBorrow, validationQuery, validationInterval, etc in master-datasources.xml. Now the only thing that would ever need to change is the datasource's configuration in that file.

The other reason I went with the datasource in the master-datasources.xml is that I didn't have to decided in my custom user store's code which parameters I would want to have or not have and just manage it all in the xml file easily. This really has advantages with portability of configs and IT involvement for deployments and debugging. I already have other datasources in this file for the IS deployment.

All said, my user store is now living through the night and weekends. :)