Deploying Tibco Applications with Hudson
Facts - Tibco
Tuesday, 08 January 2008 22:02

A colleague and me have been setting up the Hudson web based make and deployment system for deploying Tibco BusinessWorks processes. 

Hudson is basically a web based frontend that interfaces with our version control system CVS and runs an Ant build file on the server. In our case Hudson was installed on a Windows 2003 server. Our main Hudson Ant build file contained XSLT tasks that generated other Ant build files for creating ear files and deploying. These generated Ant build files were subsequently called by tasks in the main Hudson ant build file. Later we got rid of the XSLT scripts and replaced them with Groovy code.

Use of CVS

We specified parts of CVS modules containing BusinessWorks projects that needed to be checked out from CVS first. Then we made our Hudson Ant execute a piece of java code that could replace global variables with values that matched our deployment environment. We checked the field "Legacy Mode" in the Hudson configuration such that we were able to check out only a part of a CVS module. Checking out only a part of a CVS module saved us a lot of time compared to checking out an entire CVS module.

Use of Perforce.

When we finally managed to deploy BusinessWorks code from a CVS repository our project manager decided to switch to Perforce. So we had to change the Hudson configuration to retrieve the code from Perforce. It took a while before we found out that we had to use a unique perforce workspace for each Hudson project. If multiple Hudson projects retrieve code from Perforce using the same workspace then the code will fail to synchronize with the Perforce repository. Apparently the Perforce server keeps track of which versions of each file are retrieved from the depot. This is different from how CVS works: the cvs client keeps track of which version of the code is retrieved from the server.

The following two Perforce problems are related to the Hudson Perforce plugin version 1.0.10.

The second problem with retrieving files from Perforce was the change list. For each build Hudson retrieves a list of changes from the server. The changes represent differences with the code from the previous build. For each change the description was displayed from the version control system. With CVS Hudson only displayed the changes in the files that were checked out for the project being built. When retrieving files from Perforce Hudson displayed all changes that occurred in the Perforce system, also the changes of files that were not retrieved.

The third problem with the Hudson Perforce plugin is related to retrieving labeled files. In Perforce (or CVS) each release is marked with a label. The idea is that the label makes it easier to retrieve that release from the version control system. Unfortunately the Perforce plugin for Hudson could not retrieve labeled snapshots of the code. The workaround is to retrieve the code from the Ant build file called by Hudson. Unfortunately this workaround breaks the synchronisation if the same Hudson project (Perforce workspace) is used to retrieve the labeled snapshot and the latest revision of the code. In later releases of the Perforce plugin the workaround is not necessary anymore. Instead labelled code can be checked out by supplying the label in the hudson configuration:

//depot/main/...@yourlabel

Hudson retrieves files from Perforce much faster than from CVS. Hudson cleans the directory with previously retrieved code each before each build when retrieving code from CVS. When retrieving code from Perforce the Hudson plugin just synchronises (updates) the code with the server. Not surprisingly it seems to take less time to compute a change list when retrieving code from Perforce compared to when retrieving code from CVS. But again the change list is better when using CVS.

Generating ear files

The generated Ant build files had to produce an ear file using the buildear utility, which is part of the Tibco Runtime Agent (TRA). Hudson was able to generate an ear file without problems, however some of the BusinessWorks processes in the ear file failed to start once deployed within Tibco Administrator.

After inspecting the ear files generated via Hudson it turned out that any references to the design time libraries were missing. These design time libraries were specified in the the file .designtimelibs of the BusinessWorks project and mapped to real library files using File Aliases defined in Tibco Designer. We knew already that these File Aliases were stored in the file Designer5.prefs.  Fortunately it turned out that the buildear utility reads the file Designer5.prefs in the user directory C:\Documents and Settings\%USER%\.TIBCO on the server running Hudson. So buildear creates ear files the same way Tibco Designer does.

We saw that we were able to create ear files with the correct library dependencies when we were creating ear files by running buildear from the command line. Still we could not create ear files when running buildear from Hudson. The we realized that the Hudson webserver was not running as the user Administrator. Instead it was running as a windows service under the Local System Account. Therefore it could not read the Designer5.prefs from the directory C:\Documents and Settings\Administrator\.TIBCO. So we copied Designer5.prefs to the directory C:\Documents and Settings\Default User\.TIBCO and we were able to generate correct ear files via the Hudson web-frontend.

Deploying ear files

The next problem was to deploy ear files via Hudson. Our Hudson-Ant build file called the tool AppManage for deploying to the machine Tibco Administrator was running on. This tool is part of the Tibco TRA package and has to run twice. First it has to create a deployment configuration file, containing for example the domain and the machine for the deployment and then it has to do the actual deployment, uploading the ear file to Tibco Administrator, etc.

Initially these deployments seemed to succeed: we saw that the ear file was uploaded to Tibco Administrator and that the Tibco BusinessWorks processes in it were restarted after deployment. However error messages such as "Container failed to deploy" persisted in Tibco Administrator. The problem was that our Hudson webserver and Tibco Administrator were on different subnets. We would have thought that it was enough to configure the Hawk Agent on the Hudson machine with a remote Rendezvous Daemon pointing to the Tibco Administrator machine. Unfortunately the deployment configuration file created by AppManage should also have the remote daemon in it but it did not. This remote deamon has to be used by AppManage for communicating with the Reposity Manager within Tibco Administrator. So we created an extra task in the Hudson Ant build file that replaced the value of the element application/repoInstances/:rvRepoInstance/daemon in the deployment configuration file with the correct remote daemon, pointing to machine the processes were deployed on. After we made sure that AppManage had a deployment configuration file with the correct value of the Rendezvous daemon we were able to deploy via the Hudson web frontend.

Complex BW deployments.

Initially each Tibco Administrator domain only had a single machine. So we only deployed our BusinessWorks processes on that machine with default parameters such as log file settings, java settings etc. However we knew that soon we also had to deploy on domains with more than one machine. And that it could happen that one ear file contained two process archives that needed to run on different machines. Or that some businessworks engines may need more memory than the standard 256Mb.

Before continuing I have to give some more details on our deployment Ant scripts: we supplied Hudson/Ant with an xml file telling Ant which ear files we wanted to deploy and the location of the code in the version control system. Let's call this file HudsonProjectName.TibcoComponents.xml. Then Ant calls AppManage for each ear file in HudsonProjectName.TibcoComponents.xml to create a deployment xml file EarFileName_deployment_config.xml. The next step is that Ant calls AppManage again to do the actual deployment using EarFileName_deployment_config.xml.

The file EarFileName_deployment_config.xml contains an xml structure of the form

<services><bw name="BWProcessArchiveName.par">...</bw></services>
for each ear file. This structure contains the deployment configuration of the BusinessWorks processes and is described in the Tibco Runtime Agent (TRA) manual in detail. By editing this file we managed to deploy with non-standard options using AppManage. So we decided to add this xml structure to the configuration of each ear file in HudsonProjectName.TibcoComponents.xml. Actually we only added the structure to ear file configurations that required deployment with non-default parameters. The next step was merging our custom deployment configuration in HudsonProjectName.TibcoComponents.xml into the generating deployment configuration in EarFileName_deployment_config.xml.

We needed two xml transforms to do this. The first XSL file transforms the custom deployment sections in HudsonProjectName.TibcoComponents.xml to the main structure in EarFileName_deployment_config.xml. The second XSL merges this temporary xml file into EarFileName_deployment_config.xml generated by AppManage. We could do the merge with Oliver Becker's stylesheet without any modifications. Thanks Oliver ! By setting replace=true in Oliver's stylesheet our custom deployment settings take precedence over the default deployment settings in EarFileName_deployment_config.xml. Instead of doing an XSLT merge we could have supplied complete custom deployment sections in HudsonProjectName.TibcoComponents.xml and overwrite the deployment sections in EarFileName_deployment_config.xml with our custom deployment sections. With the XSLT merge however we only need to supply the deployment parameters that are different from the defaults in HudsonProjectName.TibcoComponents.xml.

Later we refined this approach by doing the XSL merge after replacing the default deployment configuration in EarFileName_deployment_config.xml by own own default deployment configuration. This modification enabled multiple instances of the same BusinessWorks engine.

Starting and stopping BusinessWorks processes from Hudson

Once deployed BusinessWorks engines can be started and stopped from Tibco Administrator. Often the start and stop order matters. Therefore we also want to prevent mistakes caused by starting or stopping processes in the wrong order. Therefore we have set up an extra target in the Hudson Ant script such that processes can be started and stopped in the correct order with a single click.

The Ant task executes some custom java code talking to the Tibco Hawk libraries, in fact talking to the Hawk microagents of the BusinessWorks engines and to the microagents of the Tibco Runtime Agent. This code reads a start/stop sequence from the TibcoComponents.xml and then executes it. As with our other java code it was called from the Ant task using Groovy. The start/stop sequences permit starting and stopping BusinessWorks engines in arbitrary but predefined order. The processes can be started in blocking mode but also in parallel. After starting a number of processes in parallel it is possible to wait for some or all of these processes to be started. In addition this java code also permits switching BusinessWorks process starters from enabled to disabled and vice versa.

Note January 2012: the Hudson built system was bought by Oracle. As a result Hudson is now maintained by new team of developers. The existing Hudson developers and most plugin developers started developing a new branch of Hudson called Jenkins.