Performing a DB2 bind with Rational Team Concert 4.0

Summary

A final step in the preparation of an enterprise application with embedded SQL for IBM DB2 access is to perform a DB2 bind. IBM Rational Team Concert 4.0 Enterprise Extensions provide the capability to perform this step through the execution of custom REXX during or after a build process or as a post-promote or post-deploy command. This article illustrates the tasks involved in configuring several of these approaches.

License Statement

This article contains source code. License terms that govern use of this source code are here.

Additional setup

This article assumes that DB2 is already set up and configured, and that the TSO user ID used in the build and deployment is authorized to issue the BIND command. You should work with your system administrator to ensure these pre-requisites are fulfilled. This article also does not cover the PLAN bind, which would likely be performed manually outside the scope of a build or deploy. However, you can find a sample PLAN bind in the mortgage application that will be performed if you choose to take the BIND file approach briefly described above.

Option 1: DB2 bind as a step in the build process

You can perform the bind as a step in your dependency build. The translator that calls the bind REXX script is integrated into the language definitions that include SQL pre-processing. The sample mortgage application includes this option. The required setup is demonstrated in the following steps. If you are using the sample mortgage application, you can generate the translator and language definition used here by un-commenting <property name="use.bind_1" value="true"/> in setuprtcz.xml before running the system definitions generator.

Step 1: Create a REXX bind script.

First, you need a REXX script to perform the bind. A sample script, REXXBIND.rex, is included in the sample mortgage application and used here.
/* REXX */
/* REXX BIND processor sample */
trace o
Arg PACKAGE DBRM

rcode = 0

/* Set BIND options */
SYSTEM = 'DSN9'

i = Pos('(', DBRM)
len = Length(DBRM)
LIBRARY = Substr(DBRM, 1, i - 1)
MEMBER = Substr(DBRM, i + 1, len - i - 1)

OWNER = 'DEVDBA'
ACTION = 'REPLACE'
VALIDATE = 'RUN'
ISOLATION = 'CS'
EXPLAIN = 'NO'
QUALIFIER = 'DEVDBA'

Call Bind_it

Exit rcode

Bind_it:

/* Create a bind control statement as a single long line. Then */
/* queue that into a FIFO stack */
DB2_Line = "BIND PACKAGE("PACKAGE")" ||,
" LIBRARY('"LIBRARY"')" ||,
" MEMBER("MEMBER")" ||,
" OWNER("OWNER")" ||,
" ACTION("ACTION")" ||,
" VALIDATE("VALIDATE")" ||,
" ISOLATION("ISOLATION")" ||,
" EXPLAIN("EXPLAIN")" ||,
" QUALIFIER("QUALIFIER")"

/* Write the bind control statement to the data queue and execute */
/* DB2I to perform the bind. */

queue DB2_Line
queue "End"
Address TSO "DSN SYSTEM("SYSTEM")"
rcode = RC

Return

Update the BIND PACKAGE parameters in the script as necessary for your environment. If there are multiple environments running from the code that was built, you can add multiple DB2 bind environments to this REXX script.

You can save this REXX script in a PDS on your build machine, or you can store it in the SCM and load it out as part of the build process. If you choose to store the REXX script in the SCM, add the REXX script to a zComponent project, as shown in the following hierarchy:

zComponent project containing REXX bind scripts

The REXX zFolder must have an associated data set definition, and in the properties for the REXXBIND.rex file, select the Always load this file during dependency build option.

REXXBIND properties with Always load this file during dependency build

Step 2: Create a translator to invoke the REXX bind script.

Next, you need a translator that runs the REXX script using TSO, as shown in the following graphic:

DB2 bind translator using TSO exec

Configure your translator with the following command:

EXEC '${team.enterprise.scm.resourcePrefix}.REXX(REXXBIND)' '${db2.package} ${team.enterprise.scm.resourcePrefix}.DBRM@{source.member}'

If you choose to save the REXX script on the host rather than in the SCM, replace the first instance of the ${team.enterprise.scm.resourcePrefix} build property in the Command/member field with the high level qualifier for the data set containing the REXX script. The two arguments passed to the REXX script are the collection ID provided by the build property ${db2.package}, and the DBRM member generated by the DB2 pre-processor as part of the compile step in the build process.

Step 3: Add the DB2 bind translator to language definitions associated with DB2 applications.

You must add the translator you created to your DB2 language definitions, as shown in the following graphic:

DB2 language definition with bind step

Step 4: Configure the dependency build.

Your dependency build, which is configured to process programs associated with your DB2 language definitions, must be updated to include the ${db2.package} build property described above. It also requires the use of a custom ISPF bin path (assuming your ISPF gateway installation is not configured with your DB2 SDSNLOAD library in the STEPLIB), as described in the help here. Set the ${team.enterprise.build.ant.myISPFBinPath} property to point to a directory containing a custom ISPZXENV with an entry such as the following for STEPLIB:

STEPLIB ="ISP.SISPLPA:ISP.SISPLOAD:DB2.V9R1M0.SDSNLOAD"

Dependency build definition including the DB2 language definition

The mortgage application contains a second example, briefly described here. In this example, a BIND (.bnd) file is included in the zComponent project, and this file specifies parameters required for the bind. BIND files are associated with a language definition that contains a translator that executes a different REXX script, BNDPROC.rex. The DBRM data set is provided as the DBRMLIB DD, rather than as a parameter to the REXX script. With this configuration, all binds occur at the end of the build after all programs have been compiled and link-edited, rather than in-line as each file is processed as we see in the sample above. To try this approach, uncomment <property name="use.bind_2" value="true"/> in setuprtcz.xml before running the system definitions generator.

Option 2: DB2 BIND as a post-deploy command

If you are not building your programs directly into your runtime environment, you need to package and deploy the programs after you build them. As a result, you need to perform a bind on the programs in their target environment. Configure this bind as a post-deploy command.

Step 1: Create a REXX bind script

This bind script is different from the script described previously. This script is not under source control, since you will not be loading from the SCM as part of the package and deploy process. Also, you are passing the environment level in which the bind occurs as an argument. In doing so, you can reuse the script at the production, quality assurance, and any test levels. This argument is used to select the appropriate options for the BIND. The following sample script can be used as a starting point and configured for your environment:
/* REXX */
/* REXX BIND processor sample */
/* trace o */
/* Trace ?i */
Arg DBRM ENV

rcode = 0

Say "Performing REXX BIND on " DBRM

/* Set standard BIND options by environment */

i = Pos('(', DBRM)
len = Length(DBRM)
LIBRARY = Substr(DBRM, 1, i - 1)
MEMBER = Substr(DBRM, i + 1, len - i - 1)


Select
When (ENV = 'PROD') Then
Do
SUBSYS = 'DSN9'
OWNER = 'PRODDBA'
ACTION = 'REP'
VALIDATE = 'RUN'
ISOLATION = 'CS'
EXPLAIN = 'NO'
QUALIFIER = 'PRODDBA'

Call Bind_it
End
When (ENV = 'TEST') Then
Do
SUBSYS = 'DSN9'
OWNER = 'TESTDBA'
ACTION = 'REP'
VALIDATE = 'BIND'
ISOLATION = 'CS'
EXPLAIN = 'NO'
QUALIFIER = 'TESTDBA'

Call Bind_it
End
When (ENV = 'DEV2') Then
Do
SUBSYS = 'DSN9'
OWNER = 'DEVDBA'
ACTION = 'REP'
VALIDATE = 'BIND'
ISOLATION = 'CS'
EXPLAIN = 'NO'
QUALIFIER = 'DEVDBA'

Call Bind_it
End
Otherwise
Do
Say "No bind on ENV " ENV
NOP /* no bind needed */
End
End
Exit rcode

Bind_it:

/* Create a bind control statement as a single long line. Then */
/* queue that into a FIFO stack */
DB2_Line = "BIND PACKAGE("ENV")" ||,
" LIBRARY('"LIBRARY"')" ||,
" MEMBER("MEMBER")" ||,
" OWNER("OWNER")" ||,
" ACTION("ACTION")" ||,
" VALIDATE("VALIDATE")" ||,
" ISOLATION("ISOLATION")" ||,
" EXPLAIN("EXPLAIN")" ||,
" QUALIFIER("QUALIFIER")"

/* Write the bind control statement to the data queue and execute */
/* DB2I to perform the bind. */

queue DB2_Line
queue "End"
Address TSO "DSN SYSTEM("SUBSYS")"
rcode = RC

Say "BIND complete."
Return

Step 2: Gather the deployed DBRM modules.

When the bind is part of the build process, you know which DBRM to bind because it is generated in a previous translator. With this option, you need to find out which modules to bind.

You can find this information in one of the USS files generated by deployment, deltaDeployed.xml. The file lists all of the members that were created or updated as a result of the deployment. You must parse this file to find the DBRM modules you need to bind. A sample basic REXX script, BINDALL.rex, uses custom JavaScript to parse the deltaDeployed.xml file and binds each of the updated DBRM files using the script from the previous step. BINDALL uses the jrunscript command line script shell that ships with Java 6. The jrunscript shell tool is experimental. You can replace the use of the tool with additional REXX to parse the xml file.
/* REXX */
/******************************************************************************/
/* NAME := BINDALL */
/* */
/* DESCRIPTIVE NAME := Post-deploy DB2 bind module */
/* */
/* FUNCTION := Parse deltaDeployed.xml to gather deployed DBRMs and call */
/* REXXBIND for that member. */
/* */
/* Change the following to suit your installation requirements: */
/* */
/* @jrunscript@ - location of jrunscript shell provided with Java 6 */
/* @parsescript@ - location of your javascript for parsing deltaDeployed.xml */
/* @rexxpds@ - location of your REXXBIND script */
/******************************************************************************/
JRUNSCRIPT = "@jrunscript"
PARSE_SCRIPT = "@parsescript@"

trace o

parse arg '"'ROOT'"' '"'PACKDEF'"' '"'LABEL'"' '"'ENV'"'.
deltadep = ROOT"/"PACKDEF"/"LABEL"/deltaDeployed.xml"

Say "Gathering deployed DBRMs from" deltadep

manlist.0 = 0
shellcmd = JRUNSCRIPT PARSE_SCRIPT deltadep
sh_rc = bpxwunix(shellcmd,,manlist.,err.)
If err.0 > 0 Then
Do
Say "Problem parsing manifest file : "deltadep". "
Do i = 1 to err.0
Say strip(err.i)
End
Call Exitproc(8)
End


/* Process the DBRM elements */

i = 1
Do while i <= manlist.0
Parse var manlist.i DataSet'('Member')'
Say "Calling REXXBIND on member:" DataSet"("Member")"
Address TSO "exec '@rexxpds@(rexxbind)'",
"'"DataSet"("Member") "ENV"'"
i = i + 1
End
Exit 0

Update the values @jrunscript@, @parsescript@, and @rexxpds@ per the directions in the script above. 

We call the following sample javascript to parse deltaDeployed.xml:

var doc = new XMLDocument(arguments[0]);
var containers = doc.getElementsByTagName('container');
for ( var i = 0; i < containers.length; i++) {
var container = containers.item(i);
var dataset_name = container.getAttribute('name');
if (dataset_name.match(/DBRM$/)) {
var resources = container.getElementsByTagName('resource');
for ( var j = 0; j < resources.length; j++) {
var member_name = resources.item(j).getAttribute('name')
.replace(" ", "");
println(dataset_name + '(' + member_name + ')');
}
}
}

Step 3: Configure the post-deploy command.

You must configure your deployment definition to run your REXX script as a post-deploy command. Include the name of your REXX script followed by the required parameters. In the deployment definition, you pass several parameters needed to calculate the location of the deltaDeployed.xml file, as well as the environment to which you are deploying. The full value for Deploy post-command in our sample is BINDALL ${team.deploy.common.localPackageRoot.dir} ${team.deploy.common.packagedefinitionUUID} ${team.deploy.common.packageLabel} TEST. The properties being passed in are the deployed package root directory, the unique ID of the associated package definition, and the label of the package being deployed.

Deployment definition with deploy post-command

Just as you did for the build definition in step 4 of option 1, you must set the ${team.enterprise.build.ant.myISPFBinPath} property. In this case, you must update your ISPF.conf file to reference the PDS that contains the REXX script created in step 2 above. For example, the REXX created in RYEHLE.REXX.EXEC is specified as the following in ISPF.conf:

sysproc=RYEHLE.REXX.EXEC,ISP.SISPCLIB

You can find more information on updating ISPF.conf here.

Other approaches to DB2 bind

You might want to perform your bind as a post-build or post-promote command. To do this, as you did previously for post-deploy, you need to gather the DBRM members you need to bind. You can find this information in artifacts of the build and promotion, generatedOutputs.properties and promotionInfo.xml.

For more information

About the authors

Robin Yehle is a member of the Jazz Jumpstart team. The Jazz Jumpstart team is a worldwide group of development specialists who bring new and advanced Jazz-based technologies to customers. Please direct feedback and comments to ryehle@us.ibm.com.

Liam Doherty is a Rational Team Concert Enterprise Extensions Architect and RTC ISPF Client developer. He has 30 years of experience with the MVS operating system both with IBM and other customers. Initially an application programmer in PL/I, IMS, CICS, and DB2, he moved into more technical support roles such as IMS DBA, CICS System programmer, and SCLM Administrator before spending much of his career as a DB2 DBA. The last 11 years he has concentrated on Source and Configuration Mangagement products, initially as the SCLM architect and has taken that experience in SCM to the RTC team for the past 3 years. Please direct feedback and comments to dohertl@au1.ibm.com.

Tami Takamiya has been working on the Enterprise Extension of the Rational Team Concert product and primarily involved in the design and implementation of the mainframe application build component. Please direct feedback and comments to ttakamiy@us.ibm.com.


Dashboards and work items are no longer publicly available, so some links may be invalid. We now provide similar information through other means. Learn more here.
Feedback
Was this information helpful? Yes No 5 people rated this as helpful.