Prerequisite reading

Before you get started, please make sure you have read the documentation below. If you have not, you may not get a full understanding of the matters described in this document.

  1. Upgrader overview
  2. Getting started

You will also need the Upgrader tool Javadocs for your reference.

Introduction

As explained, in the Upgrader overview section, the Upgrader tool can handle SQL and Ant upgrade scripts and some of its behaviors can be influenced by properties passed to it from outside. In addition, the tool can be extended by plugging in Java classes to perform additional functions that the tool does not handle by default. The Upgrader tool supports the concept of plugin using which you can:

  1. Introduce your own script runners that can handle scripts not supported by the tool. For example, you can plugin your own runner for executing Python and/or Ruby scripts. You can also override the script runners provided by the Upgrader tool.
  2. Introduce your own listener class that the Upgrader tool uses to notify when upgrade even occurs. This is achieved by the use of callback methods in the class. For example, the tool invokes a callback method just before a script is executed or if there is an exception. One of the uses of this capability is to perform a manual rollback when an Ant script fails to execute. Although the SQL scripts run within a transaction and, on exception, the transaction is rolled back but that is not supported for Ant scripts. TO overcome this problem, you can create your own rollback scripts that performs the necessary cleanup and plugin to the Upgrader tool.
  3. Introduce your own patch engine that handles the persistence of the patch information. This is not necessary in most cases because the JDBC persistence engine provided by the tool handles the persistence. However, in case your application does not use a database, you can create your own patch engine class that handles persisting information to a file system. For example, you may want the patch information to be stored in an XML file in the root directory of your application.
The plugin capability ensures that you don't need to modify the tool in order to extend the capabilities.

Creating your own script runners

Let's say that you have standardized on using Python scripts for upgrading the application from one version to another. You want a patch with the extension - .py to be executed by your own custom runner. To add this capability to the Upgrader tool, you need to do the following:

  1. Create a class that implements the interface - org.cafesip.upgrade.ScriptRunner.
  2. Add this class and any associated jars to the CLASSPATH of the Upgrader tool. In the case of Python script runners, you will need the jython.jar and other jar files that provide the Python scripting capability.
  3. Use the property - org.cafesip.upgrade.custom.runners to plugin the class to the Upgrader tool.
Please refer to the javadocs for the ScriptRunner interface for details of the method that you need to implement and for the syntax of the value part of the property. Note that it is possible to add more than one script runner using the property describe above.

You can also override the script runners that the tool provides by adding your own runners in the same way as described above. For example, if the SQL script runner that we have provided does not work with DB2, you can create your own SQL script runner and overriding the default SQL script runner.

Setting up an upgrade listener

Let's say you want to create rollback scripts for the Ant patch scripts that you have in the patch directory. You can achieve this as described below:

  1. Create a class that implements the interface - org.cafesip.upgrade.Listener. Alternatively, you can extend the class - org.cafesip.upgrade.UpgraderListenerAdapter and override the methods that you are interested in.
  2. Add this class and any associated jars to the CLASSPATH of the Upgrader tool.
  3. Use the property - org.cafesip.upgrade.listener to plugin the class to the Upgrader tool.
For details on the callback methods and the property, refer to the Javadocs for the UpgradeListener interface.

You can override the method - onException() to listen for exceptions. To implement, your own rollback Ant script that are invoked to perform cleanups after an Ant patch script has failed, you ask the developers to create rollback Ant scripts for every Ant patch scripts that are added by the developers. You can name the rollback scripts using the naming convention - rollback_XXX.ant and place them in the patch directory where the patch scripts are placed. The onException() method may look like the following:

import org.cafesip.upgrade.runners.AntScriptRunner;
import org.cafesip.upgrade.runners.UpgradeParams;

public void onException(Upgrader upgrader, Exception e, int dbPatchLevel, File file) {
// Get the patch directory
String patchDir = patchDir = (String) UpgraderParams.getInstance().get( UpgraderParams.PARAM_PATCHDIR);
File f = new File(patchDir, "rollback" + dbPatchLevel + ".ant");

if (!f.exists) return; // rollback script does not exist, oops!

AntScriptRunner runner = new AntScriptRunner();
runner.execute(f); // this will excute the rollback script
}
Note that the above code is just a suggestion. It is meant to demonstrate that you can perform your own actions. Also note that the listener is not just meant for adding rollback capability. It can be used for logging script progress, to communicate with the installer that you may be using among other things.

Using your own patch engine

The patch engine provides persistence capability to the Upgrader tool. Using the patch engine, the tool stores and retrieves patch information among other things. The JDBC patch engine provided by the Upgrader tool is sufficient for this purpose. The only time you will need to provide your own patch engine is when your application does not use a database. You can plugin your own patch engine as described below:

  1. Create a class that implements the interface - org.cafesip.upgrade.PatchEngine.
  2. Add this class and any associated jars to the CLASSPATH of the Upgrader tool.
  3. Use the property - org.cafesip.upgrade.custom.patcher to plugin the class to the Upgrader tool.
For details on the callback methods and the property, refer to the Javadocs for the PatchEngine interface.

Variables

The Upgrader tool provides a mechanism using which objects can communicate with each other. It is provided in the form of variables that are stored in the singleton object - org.cafesip.upgrade.UpgraderParams. If you have extended the capabilities of the Upgrader tool as described in the above sections, the plugin objects you created can access certain system variables or you can store your own variables for use by other classes. As demonstrated in the code segment we provided in the listener section above, we are taking advantage of this feature:

// Get the patch directory
String patchDir = patchDir = (String) UpgraderParams.getInstance().get( UpgraderParams.PARAM_PATCHDIR);
If you are using the JDBC patch engine (default), your script runners can also obtain the JDBC connection as follows:
Connection connection = (Connection) UpgraderParams.getInstance().get( UpgraderParams.PARAM_CONNECTION);
See the javadocs for the UpgraderParams class for details.

Contributing your extensions

If you would like to contribute your extension to the Upgrade tool so that we can include them with the core distribution, please contact us with your contribution. We will be happy to include them if we feel that it will enhance the capabilities. Please note that when you contribute, you have to contribute under the terms and conditions of the Apache License and the source code will be available to the public. Also, we may not take your contributions if you have not provided sufficient Junit tests.