26 março 2014

Migrating JDBC Resources from GlassFish to WebLogic

Following up with my series of articles about Migrating from GlassFish to WebLogic, this time I want to cover the migration of a very common resource used by every Java EE developer: JDBC resources, or simply, DataSources. And in case you haven't read yet the first article, here it is: Migrating a Java EE App from GlassFish to WebLogic. That one will walk you through redeploying a simple yet almost complete Java EE 6 application on WebLogic, without any code change nor specific deployment descriptors, and still taking advantage of the enhanced Maven Plugin in WebLogic 12c.

It is easy to migrate resources by using the Web consoles of both WebLogic and GlassFish. Just open one browser window for each server, put them side-by-side, and follow the UI menus. Most of the properties are the same. But if you walkthrough the full article below, you will not only learn the concepts and what is required to migrate JDBC resources, but also how to migrate things using Command-line Interface (asadmin from GlassFish; wlst from WebLogic). So in order to understand what I'm doing here, I strongly recommend you to read, at least the introduction of, these two docs below in case you are not familiar with asadmin or wlst:


Oracle WebLogic Types of JDBC Data Sources

WebLogic offers three types of DataSources. For this migration, the type we will use will be "Generic". To know more about each type, click on the links below:

  • Generic Data Source
    • the type you are most familiar with; we will focus on this one
  • GridLink Data Source
    • in case you have an Oracle RAC Database, this is an optimal data source with HA and Failover features
  • Multi Data Source
    • abstracts two or more Generic Data Sources; works like a 'pool of data sources' so you can use it for either failover or load balancing


JDBC Resources: DataSources and Connection Pools

In the first article this was sort of covered from a Java EE Standard point of view. I simply took advantage of the @DataSourceDefinition annotation type, which allows developers to define JDBC DataSources directly from the Java source code, and requires no vendor-specific deployment descriptors nor manual previous configuration of the application server.

Now in case you have a legacy application or you are not using @DataSourceDefinition, you will be required to migrate these resources by hand. This will require three (plus one optional) simple steps:

  1. List JDBC resources from a GlassFish domain
  2. (optional; see below) Install 3rd-party JDBC drivers in WebLogic
  3. Extract and convert relevant and required information by WebLogic
  4. Create datasources inside WebLogic
Oracle WebLogic 12c already comes with JDBC drivers for Oracle DB 11g, MySQL 5.1.x, and Derby DB, so you won't need to do anything for these databases. For more information, read the docs JDBC Drivers Installed with WebLogic Server. In this doc you will also learn how to update the versions already provided by WebLogic, for example if you want to take advantage of the new features in Oracle DB 12c

If you are using Microsoft SQL Server, PostgreSQL, or any other database, check the Setting the Environment for a Thirdy-Party JDBC Driver for more information on how to install these drivers.

Concepts of JDBC Resources

We should also learn one difference between the concept of JDBC Resources in GlassFish 3 versus WebLogic 12c. In GlassFish, there are two types of JDBC Resources:
  • JDBC Connection Pools
  • JDBC Resources (aka DataSources)
On the other hand, WebLogic treats JDBC Resources as one single thing: Data Sources. The connection pool is part of the data source definition where in GlassFish, the Data Source is a separate artifact, which allows enabling/disabling the object, and also provides the JNDI name to a specific Connection Pool. In few words, when migrating a data source from GlassFish to WebLogic, you will only care about the JDBC Connection Pool and the JNDI name given at the JDBC Resource item.

Listing JDBC Resources from a GlassFish domain

First, let's list all JDBC Resources (datasources) in our GlassFish server. Connect with asadmin and execute the list-jdbc-resources command:

asadmin> list-jdbc-resources
jdbc/__TimerPool
jdbc/__default
jdbc/gf2wls
Command list-jdbc-resources executed successfully.

Let's focus on our example: the jdbc/gf2wls datasource. This will be the DataSource we will migrate from GlassFish to WebLogic. Now let's list all Connection Pools in this GlassFish domain by using asadmin list-jdbc-connection-pools:

asadmin> list-jdbc-connection-pools
__TimerPool
DerbyPool
mysql_gf2wls_gf2wlsPool
Command list-jdbc-connection-pools executed successfully.

Now of course in case you have dozens of connection pools created in your GlassFish domain, it would be easier to issue a command that shows you which connection pool is associated to the Data Source you want to migrate. To do this, let's use the asadmin get command:

asadmin> get resources.jdbc-resource.jdbc/gf2wls.*
resources.jdbc-resource.jdbc/gf2wls.enabled=true
resources.jdbc-resource.jdbc/gf2wls.jndi-name=jdbc/gf2wls
resources.jdbc-resource.jdbc/gf2wls.object-type=user
resources.jdbc-resource.jdbc/gf2wls.pool-name=mysql_gf2wls_gf2wlsPool

We not only got which connection pool is associated to this data source but also its JNDI name, because the name of the resource may not be exactly the same as the JNDI name. 

Extracting GlassFish's JDBC Connection Pool data

Next step is to get all properties of your Connection Pool. Let's issue the asadmin get command again:

asadmin> get resources.jdbc-connection-pool.mysql_gf2wls_gf2wlsPool.*
resources.jdbc-connection-pool.mysql_gf2wls_gf2wlsPool.property.portNumber=3306
resources.jdbc-connection-pool.mysql_gf2wls_gf2wlsPool.property.serverName=localhost
resources.jdbc-connection-pool.mysql_gf2wls_gf2wlsPool.property.databaseName=gf2wls
resources.jdbc-connection-pool.mysql_gf2wls_gf2wlsPool.property.User=gf2wls
resources.jdbc-connection-pool.mysql_gf2wls_gf2wlsPool.property.URL=jdbc:mysql://localhost:3306/gf2wls?zeroDateTimeBehavior=convertToNull
resources.jdbc-connection-pool.mysql_gf2wls_gf2wlsPool.property.driverClass=com.mysql.jdbc.Driver
resources.jdbc-connection-pool.mysql_gf2wls_gf2wlsPool.property.Password=gf2wls
Command get executed successfully.

Easy, isn't? Now, let's focus on the minimum required properties we need to create this DataSource in WebLogic 12c. They are under resources.jdbc-connection-pool.mysql_gf2wls_gf2wlsPool.property.* , so if you want to list only these, change the asadmin method above to the following: asadmin get resources.jdbc-connection-pool.mysql_gf2wls_gf2wlsPool.property.*

Create the Data Source in WebLogic using WLST

To help you witht he final step, I've created a sample WLST script to create a Data Source in WebLogic. In this script, there are a few variables you must define. To call this script, go to your WebLogic installation directory and, if you are on Linux, call $ source setDomainEnv.sh (or the proper script for your environment). Then execute the WLST script: $ java weblogic.WLST ds_gf2wls.py

You should see the following output:

$ java weblogic.WLST ds_gf2wls.py
Initializing WebLogic Scripting Tool (WLST) ...

Welcome to WebLogic Server Administration Scripting Shell

Type help() for help on available commands

Connecting to t3://localhost:7001 with userid weblogic ...
...
Starting an edit session ...
Started edit session, please be sure to save and activate your 
changes once you are done.
Saving all your changes ...
Saved all your changes successfully.
Activating all your changes, this may take a while ... 
The edit lock associated with this edit session is released 
once the activation is completed.
Activation completed

That's it. Check your WebLogic Console, by going to the Data Sources page.

Extending and improving the migration process

Now you may be wondering how to improve the process by automating everything, right? Yes you can do that! Since we have been using CLI commands, it all depends now on you by tweaking and coding some bash scripts. For example, you can use asadmin to get the information of all Data Sources, generate a bunch of files, use sed to, you know, hack the output files, then loop through them and call a more dynamic WLST script. If you want to read files from WLST, here's a fragment you can use:

from java.io import FileInputStream

propIS = FileInputStream("MyGFDS.properties")
configDS = Properties()
configDS.load(propIS)

dsName=configDS.get("dsName")
dsFileName=configDS.get("dsFileName")
dsDatabaseName=configDS.get("dsDataBaseName")
datasourceTarget=configDS.get("datasourceTarget")
dsJNDIName=configDS.get("dsJNDIName")
dsDriverName=configDS.get("dsDriverName")
dsURL=configDS.get("dsURL")
dsUserName=configDS.get("dsUserName")
dsPassword=configDS.get("dsPassword")
dsTestQuery=configDS.get("dsTestQuery")

Migrating Advanced Settings

If you want to migrate advanced settings of the Connection Pool, take a look at the full list of properties I extracted from GlassFish in my sample Data Source. To change for example the Max Pool Size, tweak the WLST script and add the following:

dsMaxPoolSize=25

cd('/JDBCSystemResources/' + dsName + '/JDBCResource/' + dsName + '/JDBCConnectionPoolParams/' + dsName)
cmo.setMaxCapacity(dsMaxPoolSize)

Again, you can do whatever you want in WLST.

There you go! If you come up with a super awesome script to automate the whole process, let me know!
Postar um comentário
Contato

Email:bruno.borges(at)gmail.com

LinkedIn: www.linkedin.com/in/brunocborges
Twitter: www.twitter.com/brunoborges
Comprei e Não Vou
Rio de Janeiro, RJ Brasil
Oracle
São Paulo, SP Brasil