Migrate OpenMRS to DB2 and WebSphere Application Server

OpenMRS® is a collaborative, open source project to
develop software to support the delivery of healthcare in developing
countries. Learn how to migrate OpenMRS into IBM® DB2® and IBM
WebSphere® Application Server. This article shows you how to prepare the
database, import the source code, and modify the project for WebSphere
Application Server.

Introduction

The Open Medical Record System (OpenMRS), created in 2004, is a
collaborative, open source project to develop software to support delivery
of healthcare in developing countries. It is a web application that lets
you design a customized medical records system even if you have no
programming knowledge. Medical and systems analysis knowledge is required,
though. OpenMRS provides the ability to add or replace bundle modules. It
also has flexible customization functions. The platforms for the OpenMRS
project are Apache Tomcat and MySQL.

In this article, learn how to migrate OpenMRS into IBM DB2 and IBM
WebSphere Application Server. Step-by-step instructions show how to
migrate from MySQL to DB2 and how to import the project into your
development environment. Learn to make the necessary modifications for DB2
and WebSphere Application Server, and then deploy the EAR file.

Prerequisites

The following product versions apply to this article:

DB2 Version 9.7

WebSphere Application Server Version 7.0.0.17

OpenMRS Version 1.7.2.

Some of the information in this article may not apply to later versions of
the these products.

To follow along with this article, it is assumed you have deployed OpenMRS
on MySQL and Tomcat. For help with deployment, see Installing OpenMRS.

Create a DB2 database named Openmrs and ensure the current user has
database permissions to that database. To do so, you can right click
on the Openmrs database in the DB2 Control Center to view the user's
privileges, as shown in Figure 1.

Figure 1. User database
privileges

Prepare the MySQL and DB2 JDBC driver JAR files. The driver JAR files
are in the installation directory of your database.

For MySQL, the driver's name is likely
mysql-connector-java-5.1.7-bin.jar

For DB2 there will be two JAR files: db2jcc.jar and
db2jcc_license_cu.jar

Make sure your DB2 JDBC driver is later than version 3.0. You can
check the version by running the
java
com.ibm.db2.jcc.DB2Jcc -version command. Figure 2 shows a sample result.

Figure 2. JDBC driver
version

To use OpenMRS you must have the database on MySQL. To achieve the
migration target, you should have a data migration tool. The IBM Data
Movement Tool can help you with data migration tasks. (See Resources for more information about this
tool.)

Follow these steps to migrate the OpenMRS demonstration data from MySQL to
DB2:

Figure 3. Data movement property
configuration

Click Connect to DB2 to verify the connection works. If
you see the instance on your workstation, you can continue your data
movement. After clicking Extract DDL/Data, you'll see the
tool's information messages in the View File tab, as
shown in Figure 4.

Figure 4. Extract DDL and data

Find a file named db2gen.cmd in the output directory under your tool's
installation directory. At this point, you can extract the scripts to do
the database deploying. Click Deploy DDL/Data. The
console should look similar to Figure 5. Compare row
counts to check if any data did not execute correctly.

Figure 5. Deploy data objects

You can also change the migration properties by changing the values in the
IBMExtract.properties file, which is in the root directory of the IBM Data
Movement Tool.

Import the project
into the development environment

Some code modifications are required to migrate OpenMRS to DB2 and
WebSphere Application Server. The first step is to import the source code
into your development environment. The development environment must
provide the ability to develop Java EE projects. Eclipse is a good choice.
Download the OpenMRS source code. (Version
1.7.2 was used for this article.)

Make sure that your JRE is later than version 1.4. To verify your JRE
version, run the java -version command, as shown in Figure 6.

Figure 6. Check JRE version

Modify the project
for WebSphere Application Server

To ensure that the code can run in WebSphere Application Server, you should
build the project as an EAR file and deploy the EAR file to WebSphere
Application Server.

Add the deployment file

To allow the project to be built into an EAR file, add the J2EE
application.xml deployment file into this project.

In the metadata directory, add a folder named META-INF, which contains the
appliction.xml that will be the deployment descriptor when you deploy this
EAR file into WebSphere Application Server. It tells WebSphere Application
Server the web module of the application and the context root of it. The
content of the XML file is shown in Listing 1.

Listing 2. jsp servlet

The URL request with the suffix withjstl will be handled by
that jsp servlet, but what is that jsp servlet?
In Tomcat, you can find this jsp servlet configured in
web.xml under tomcat-root/conf/ directory, as shown in Listing 3.

Listing 3. jsp servlet in web.xml

Most importantly, the withjstl request will be handled by the
JspServlet class defined in Tomcat's jasper core. But, if you
don't have the same class in WebSphere Application Server, how can the
application manage that web request? To solve the problem, you can add a
configuration to the project's web.xml.

Open the web.xml file and find the <jsp-config> element in the
file.

As in Listing 4, add a
<jsp-property-group> element as a child inside the
<jsp-config> element.

Modify the
project for DB2

As you've seen in the src folder, the source code has two child folders:
api and web. During deployment, the classes in the api folder will be
compressed to a JAR file named openmrs-api-version.subversion-.jar. To
migrate this project to a DB2 database, you need a JDBC connector for
DB2.

Add DB2 JDBC driver

Use the following steps to put the DB2 JDBC driver into the project.

Create a new subfolder named db2 under the project lib folder.

Copy the DB2 JDBC drivers into the db2 folder and add them to
classpath.

Add the database driver path to the lib.properties by adding the lines
in Listing 5 to lib.properties (which is the file
that provides the Ant with a JAR lib variable configuration when
building).

In this system, hibernate will map the relational database tables with the
entity classes according to the *. hbm.xml file, so your operation on the
objects will carry out the corresponding tables in the database. The
hibernate primary key generation strategy includes the following.

Assigned

Specifies the new primary key value by the application.

Increment

The new primary key will be generated by hibernate through the
increment mode during operation.

Native

The primary key will generate using different strategies according to
different databases.

UUID

Universally unique identifier.

Foreign

Uses a foreign key from some other tables.

Sequence

Uses the sequence mechanism for generating primary key provided by a
specific database, such as Oracle. The primary key generation method
in OpenMRS is identity.

You can see the configuration in the hibernate mapping configuration file.
Listing 7 shows the example
PatientIdentifier.hbm.xml.

Listing 7. PatientIdentifier.hbm.xml

Identity will use the primary key generation mechanism
provided by the database; the primary key value is completely managed by
the database. Listing 8 shows the code you'll see if
you look at the IdentityGenerator class in the hibernate
package in org.hibernate.id.

The hibernate.jdbc.use_get_generated_keys property enables the
use of JDBC3 PreparedStatement.getGeneratedKeys() to retrieve
natively generated keys after insertion. The property requires a JDBC
driver later than version 3 and JRE later than version 4. If you don't add
this property, you will get the exception "The database returned no
natively generated identity value."

Modify the project runtime
configuration

To modify the project runtime environment there are two basic tasks.

Modify context.xml

The application will verify if it can connect
to the database and, if the database is empty, the first time the
application runs. The context.xml file is the configuration that
the application uses for the verification process.

At
runtime, the application will:

Execute the select statement to check whether the user data is
in the database.

Determine if initialization is necessary.

Modify the file to include the information in Listing 9 so that the system can connect to
the database. Make sure the DB2 user has the privileges to access
and operate the database.

The update filter configured in the
web.xml file will check the database update by running some MySQL
commands. To migrate the project to DB2, disable this update
filter. You could just delete the filter, but it's a better
practice to comment it out (<!-- -->), as shown in Listing 10.

Add the openmrs-runtime.properties, a runtime properties
configuration, to your application. As shown in Listing 11, the OpenMRS application will connect to the
database using this file's configuration at runtime.

Listing 14. Replace
updatesRequired

To avoid unwanted initialization during the application's first run,
replace the initializationRequired method of the
InitializationFilter class, which is in the
org.openmrs.web.filter.initialization package. Listing
15 shows an example.

Listing 15. Replace
initializationRequired

public static boolean initializationRequired() {
return false;
}

At this point, the project code will work with a DB2 database. However, to
migrate to WebSphere Application Server you should build the project to an
EAR file. You can build an EAR file with the help of Ant. Add a target
named "ear" to the ant build.xml file. In the EAR file, a WAR
file and a web application deployment descriptor are necessary. Add this
target as shown in Listing 16.

Deploy the EAR file in WebSphere Application Server

During the application's initialization, there's a bug involving the
filters running out of order. The wrong order creates a runtime bug where
the context is misused when it has not been set up. To solve the problem,
you need a fix patch for your WebSphere Application Server:

7.0.0-WS-WASSDK-FP0000017.pak

7.0.0-WS-WAS-FP0000017.pak

Download the appropriate fix for your operating system.

Modify custom properties

If you deploy your EAR file at this point, you'll see "403 Forbidden"
errors in your firebug Net panel, as shown in Figure
8.

Figure 8. 403 Forbidden errors

The error occurs when you don't have the privileges to access certain web
resources. The example application returns some resources from the WEB-INF
directory. In WebSphere Application Server, the resources under this
directory are protected, so you don't have privileges. To solve the
problem, add a property to your WebSphere Application Server custom
properties.

Troubleshooting

In the migration process you might encounter errors similar to those
outlined below. Analyzing the error log and the error phenomenon to find
the root cause of the error is the best way to solve it.

Error

Suggestion

Database connection error

Check if the user has the
required privileges, and verify whether the user can get
access to the database schema. Check whether your JDBC driver
matches the database version; the connection will not work
with different versions.

BUILD FAILED C:\Documents\openmrs-trunk\build.xml:150: Unable
to find a javac compiler;com.sun.tools.javac.Main is not on
the classpath

Perhaps JAVA_HOME does not point to the
JDK. It is currently set to C:\Program Files\Java\jre6. Copy
C:\Program Files\Java\jdk1.6.0_10\lib\tools.jar to C:\Program
Files\Java\jre6\lib\ext.

Can't load moduleXX

Download the corresponding modules
to the deployment directory of the WEB-INF \ bundledModules
folder. Find the modules in the OpenMRS Module Repository list.

No ContextLoaderListener registered

Most likely the
application can't load runtime property files in the
environment. You can try to copy this file to your webapps
root directory.

The first time you sign into developerWorks, a profile is created for you. Information in your profile (your name, country/region, and company name) is displayed to the public and will accompany any content you post, unless you opt to hide your company name. You may update your IBM account at any time.