Managing connections to the database server using JNDI Datasource
The Java Naming and Directory Service (JNDI) can be used to manage connections to the database server.
Advantages of using JNDI
You can derive most power from JNDI if your deployment is complex. Abstracting the lookup of resources means not having to, for example, change and deploy properties or configuration files separately for each environment. The more deployment stages, such as test, production, etc., the more benefit you would accrue from using JNDI.
Migrating an application between environments (such as Integration > Test > Production) becomes much simpler. You can have multiple databases in each new environment without changing the Unblu deployment package.
As long as each app server uses the same JNDI name, you can drop the WAR file into any environment. Using a JNDI datasource doesn’t require the Unblu WAR file to be modified. |
-
Standardizes the configuration of database connections.
-
Enables the use of password encryption (passwords are currently stored as clear text strings). See Encrypting Passwords in Tomcat for more on encrypting your database passwords.
-
Allows more fine grained control over database connection pooling settings
Disadvantages of using JNDI
-
Configuration split into two pieces. The Unblu configuration only points to separate configuration of the app server. Forgetting to set up the app server’s configuration properly can cause Unblu to fail at times.
Implementing a JNDI datasource
To implement JNDI datasource you must enable four configuration items, two for the main connection and two for the admin connection. The admin connection is used with administration credentials to set up the table structures.
com.unblu.storage.database.datasourceFactory=
com.unblu.storage.database.datasourceName=jdbc/unblu
com.unblu.storage.database.adminDatasourceFactory=
com.unblu.storage.database.adminDatasourceName=
Main configuration items
Values = INTERNAL | USE_PROVIDED (default: INTERNAL)
The com.unblu.storage.database.datasourceFactory item defines whether to look for db credentials in Unblu properties or to expect a datasource to be provided via JNDI.
Values = [name of JNDI data source] (default: jdbc/unblu)
The com.unblu.storage.database.datasourceName item provides the JNDI name of the DataSource to use, and is only effective when com.unblu.storage.database.datasourceFactory=USE_PROVIDED is configured.
JNDI names are usually defined like so: java:comp/env/jdbc/unblu - in the datasource name here we only need the jdbc/unblu part). |
Configuring a JNDI datasource
For a comprehensive look at how to configure a JNDI DataSource see The JNDI Resources HOW-TO and JNDI-Datasource Examples. |
Using JNDI datasource doesn’t require the WAR file to be modified. You should define JNDI environment variables or datasources in the context file of your applications server. In Tomcat, for example, this file is called context.xml
.
-
Adapt the
context.xml
file. -
Copy the required JDBC driver to the
lib
directory of Tomcat. This is so that the driver can be accessed automatically at runtime.
<Context>
<!-- ... -->
<Resource name="jdbc/unblu"
auth="Container"
type="javax.sql.DataSource"
maxActive="100"
maxIdle="100"
minIdle="20"
maxWait="30000"
validationQuery="select 1 from dual"
timeBetweenEvictionRunsMillis="34000"
minEvictableIdleTimeMillis="60000"
validationQueryTimeout="3"
testWhileIdle="true"
testOnBorrow="false"
removeAbandoned="true"
removeAbandonedTimeout="120"
factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
username="username"
password="password"
driverClassName="oracle.jdbc.driver.OracleDriver"
url="jdbc:oracle:thin:@//fqdn-of-ths-host:port/db"
<!-- ... -->
</Context>
In the example context.xml
file above, a DataSource connection is defined using a username, password, JDBC driver, a JDBC URL (where the driver should connect to), and database connection pool settings.
Password encryption in Tomcat
The example context.xml
file shown here uses a clear text password. To encrypt the password, you must use the features of the underlying application server. See Encrypting Passwords In Tomcat.
Storage overrides
For each of the Unblu storage parts, specific overrides are possible:
# Main
com.unblu.storage.database.main.datasourceFactory=
com.unblu.storage.database.main.datasourceName=
com.unblu.storage.database.main.adminDatasourceFactory=
com.unblu.storage.database.main.adminDatasourceName=
# Webhooks
com.unblu.storage.database.weho.datasourceFactory=
com.unblu.storage.database.weho.datasourceName=
com.unblu.storage.database.weho.adminDatasourceFactory=
com.unblu.storage.database.weho.adminDatasourceName=
# etc.
Fallback chain
The fallback chain lets you specify what is required, such as having specific INTERNAL
or PROVIDED
connections depending on the purpose, or a connection is an admin connection or not. However, the fallback chain also makes it possible to define one (simple) DB connection and derive all the specific parts from it.
For a specific Unblu storage type:
-
Is the storage-type-specific datasourceXXX defined? If yes: use it.
-
If not: Is the storage-type-unspecific datasourceXXX defined? If yes: use it.
-
If not: use the default, that is,
INTERNAL
, for datasourceFactory.
For admin connections:
-
Is the storage-type-specific-adminDatasourceXXX defined? If yes: use it.
-
If not: Is the storage-type-unspecific adminDatasourceXXX defined? If yes: use it.
-
If not: Is the storage-type-specific datasourceXXX defined? If yes: use it.
-
If not: Is the storage-type-unspecific datasourceXXX defined? If yes: use it.
-
If not: use the default, that is,
INTERNAL
, for adminDatasourceFactory
Extended environment variable definitions
It is now possible to:
-
Define different variable types other than just
String
(although eventually these variables are converted back to a string within Unblu). -
Hierarchically structure Unblu environment properties as outlined below:
Listing 2. Example of hierarchically structured Unblu environment properties<Environment name="com.unblu.core.server.livetracking.agent.unavailablesessionlimit" value="3" type="java.lang.Integer" /> # an Integer type property <Environment name="com.unblu.visual.resourcehistory.enabled" value="true" type="java.lang.Boolean"/> # a Boolean type property <Environment name="com.unblu.chat.videochat.proxyAuthScheme" value="BASIC" type="java.lang.String"/> # a String type property <Environment name="unblu/com.unblu.storage.database.poolMax" value="32" type="java.lang.Integer"/> # a hierarchically nested property under the tree entry "unblu"
Type information helps during configuration validation, since type-incompatible values result in an error at startup.
Hierarchically structuring your environment properties can be helpful, especially when you use JNDI to store configuration parameters for multiple applications. Be aware that whatever structure you use, Unblu only picks up the last part of it. In the example above, unblu/com.unblu.storage.database.poolMax is interpreted as com.unblu.storage.database.poolMax within Unblu. |
Other changes
The meaning of setting com.unblu.storage.database.platform
has changed slightly. While it previously defaulted to org.eclipse.persistence.platform.database.H2Platform
, which is the qualified name of an internal implementation class, it’s now possible to use the following properties to define the type of database to connect to:
-
Auto: new default. (Advises Unblu to detect the used database automatically.)
-
Oracle
-
MySQL
-
PostgreSQL
-
SQLServer
Unblu still lets you define the (internal) class name of the Platform (like the previous default, above, with the H2Platform). |
See also
-
For information on the architecture of JNDI, refer to Oracle’s JNDI overview.