When deploying a CICS bundle you may want to make sure the resources in it follow your company’s naming standards and best practices, or even prevent specific resources being installed. This article shows you how to perform these checks using the xmllint and sed tools, and provides a script to validate a CICS bundle against a set of validation rules that are based on XPath and regular expressions.

Anatomy of a CICS bundle

A CICS bundle defines a set of CICS resources that are installed and managed together. To understand how to validate these resources, first we need an example CICS bundle to work with.

Download the validatecicsbunde project ZIP and unzip it to a convenient location, or clone the Git repository cics-bundle-scripts.

Next, import the bundle project from this download into CICS Explorer using File → Import → Existing Projects into Workspace → Next → Select archive file → Browse… → catalog.example.service.zip → Finish.

Now lets look at the files that make up this bundle. In the Project Explorer view, expand catalog.example.service and the META-INF directory. Then double-click on cics.xml to start the CICS Bundle Manifest Editor. Here you can add and remove resources amongst other things. The resources are shown in the Defined Resources section.

screenshot
CICS Explorer with the catalog.example.service project open

The resource attributes are specified in separate XML files, in this case EXINQCS.urimap, EXINQCSW.urimap, and EXINQCSW.webservice. Note that DFH0XCMN.wsbind and DFH0XCMN.wsdl are referenced by EXINQCSW.webservice and used by CICS at runtime, but are not themselves CICS resources.

The variables.properties file contains name=value pairs, where the name can be referenced within resource attributes using the ${name} convention. The variables in resource attributes are resolved using the CICS build toolkit –resolve parameter. This allows resources to be tailored for different target environments, such as test and production. You can download the CICS Build Toolkit here.

/META-INF/cics.xml and resource files

cics.xml is the bundle meta-data file and contains a define element for each resource, including the resource name, its type in a URI format, and path to the location of the resource file relative to the bundle root. For more details of this file see Manifest contents for a CICS bundle. The XML schema for this and all bundle resources are in the CICS installation directory /usr/lpp/cicsts/cicsts53/schemas.

You can view the XML for cics.xml by using right-click → Open With → Text Editor.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<manifest xmlns="http://www.ibm.com/xmlns/prod/cics/bundle" id="catalog.example.service" bundleMajorVer="1" bundleMinorVer="0" bundleMicroVer="0" bundleVersion="1" bundleRelease="0" build="IntB-201511072132">
    <meta_directives>
        <timestamp>2016-01-18T14:58:31.832Z</timestamp>
    </meta_directives>

    <define name="EXINQCSW"
       type="http://www.ibm.com/xmlns/prod/cics/bundle/WEBSERVICE"
       path="EXINQCSW.webservice"/>

    <define name="EXINQCS"
       type="http://www.ibm.com/xmlns/prod/cics/bundle/URIMAP"
       path="EXINQCS.urimap"/>

    <define name="EXINQCSW"
       type="http://www.ibm.com/xmlns/prod/cics/bundle/URIMAP"
       path="EXINQCSW.urimap"/>
</manifest>

EXINQCS.urimap is a URIMAP resource to tell CICS when it receives a request with this URI how to process it.

<?xml version="1.0" encoding="UTF-8"?>
<cicsdefinitionurimap
   xmlns="http://www.ibm.com/xmlns/prod/CICS/smw2int"
   authenticate="NO"
   host="${host}"
   name="EXINQCS"
   path="${context.root}/DFH0XCMN"
   pipeline="${pipeline}"
   scheme="HTTP"
   transaction="CPIH"
   usage="PIPELINE"
   webservice="EXINQCSW"/>

Similarly EXINQCSW.urimap is a URIMAP resource to service requests for the web service WSDL document.

<?xml version="1.0" encoding="UTF-8"?>
<cicsdefinitionurimap
   xmlns="http://www.ibm.com/xmlns/prod/CICS/smw2int"
   authenticate="NO"
   characterset="UTF-8"
   hfsfile="DFH0XCMN.wsdl"
   host="*"
   hostcodepage="1208"
   mediatype="text/xml"
   name="EXINQCSW"
   path="${context.root}/DFH0XCMN?wsdl"
   scheme="HTTP"
   usage="SERVER"/>

And lastly EXINQCSW.webservice is the WEBSERVICE resource to define which PIPELINE is to be used when processing requests for this web service, the name of the wsbind file used to map the data between XML and language structure, the target program name etc.

<?xml version="1.0" encoding="UTF-8"?>
<cicsdefinitionwebservice
   xmlns="http://www.ibm.com/xmlns/prod/CICS/smw2int"
   description="CICS Catalog Example inquire single service"
   name="EXINQCSW"
   pipeline="PIPE01"
   validation="NO"
   wsbind="DFH0XCMN.wsbind"
   wsdlfile="DFH0XCMN.wsdl"/>

Using xmllint

The CICS Explorer and build toolkit do a good job at ensuring resources follow the CICS rules, similar to the checks performed by CEDA and DFHCSDUP. For example only valid characters are allowed, required combination of attributes are present, and referenced files are in the bundle.

So how can you perform your own validation? To start with as resources are XML files we need a reliable way to extract an attribute’s value using an XML command line tool, such as xmllint and XMLStarlet as they deal with XML code pages, escape sequences, white spaces, newlines, comments, etc. They are both available for a Linux and MS Windows.

As an example, to extract the name attribute from EXINQCS.urimap using xmllint specify the XPath string(//@name):

$ xmllint --xpath "string(//@name)" EXINQCS.urimap
EXINQCS

XPath is a very powerful expression language governed by the World Wide Web Consortium and has matured over V1.0, V2.0, and V3.0 specifications. Take care to choose the tools that implement the version that have the features you need.

Once we have the attribute value, it can be validated against a regular expression using tools such as sed, grep, or awk. For example, to validate the name attribute starts with the characters EX using sed, we can pipe the xmllint output to sed and use the expression /^EX/. To set the return code to 0 if the expression evaluates to true, otherwise to 1, add the sed command !{q1} as shown below:

$ xmllint --xpath "string(//@name)" EXINQCS.urimap | sed -n '/^EX/!{q1}' ; echo $?
0

$ xmllint --xpath "string(//@name)" EXINQCS.urimap | sed -n '/^BANK/!{q1}' ; echo $?
1

Scripting a set of rules

We can now combine xmllint and sed into a script and add some smarts to process all the resources in a bundle. The validatecicsbunde Linux bash script takes as input a rule – consisting of a file pattern, XPath, and regular expression – and the CICS bundle directory to validate. The script then searches the directory and its sub-directories for files matching the pattern. For each file found it runs xmllint with the XPath to get the required attribute value, and compares it to the regular expression. If regular expression returns false, the script return code is set to non-zero.

Change to the validatecicsbundle directory, and run the following command shown in bold:

cockerma@w530:~/git/cics-bundle-scripts/validatecicsbundle$ 
./validatecicsbundle -v -f *.urimap -x "string(//@name)" -e "^EX" examples/catalog.example.service

Rule 0: File pattern:*.urimap XPath:string(//@name) regex:^EX
Validating files in directory examples/catalog.example.service against rules:
File:./EXINQCSW.urimap Rule 0: XPath:string(//@name)=EXINQCSW matched regex ^EX
File:./EXINQCS.urimap Rule 0: XPath:string(//@name)=EXINQCS matched regex ^EX
Exiting with RC=0

You can see the name attribute in the two URIMAP resources are validated to ensure they start with the characters EX.

We can now take this a step further and define a set of rules in a file:

cockerma@w530:~/git/cics-bundle-scripts/validatecicsbundle$ cat examples/rules.txt
# Sample rules

# The resource name for all URIMAPs must start with EX 
*.urimap string(//@name) ^EX

# All URIMAP scheme attribute must be HTTP
*.urimap string(//@scheme) HTTP

# All URIMAP authenticate attribute must be NO
*.urimap string(//@authenticate) NO

# All WEBSERVICE pipeline attribute must be PIPE01
*.webservice string(//@pipeline) PIPE01

# All WEBSERVICE wsdlfile attribute must be present
*.webservice boolean(//*[@validation]) true

# JVMSERVER resource must not be present
cics.xml boolean(//*[local-name()='define'][@type="http://www.ibm.com/xmlns/prod/cics/bundle/JVMSERVER"]) false

And then validate the CICS bundle against that set of rules:

cockerma@w530:~/git/cics-bundle-scripts/validatecicsbundle$
./validatecicsbundle -v -r examples/rules.txt examples/catalog.example.service

Rule 0: File pattern:*.urimap XPath:string(//@name) regex:^EX
Rule 1: File pattern:*.urimap XPath:string(//@scheme) regex:HTTP
Rule 2: File pattern:*.urimap XPath:string(//@authenticate) regex:NO
Rule 3: File pattern:*.webservice XPath:string(//@pipeline) regex:PIPE01
Rule 4: File pattern:*.webservice XPath:boolean(//*[@validation]) regex:true
Rule 5: File pattern:cics.xml XPath:boolean(//*[local-name()='define'][@type="http://www.ibm.com/xmlns/prod/cics/bundle/JVMSERVER"]) regex:false
Validating files in directory examples/catalog.example.service against rules:
File:./EXINQCSW.webservice Rule 3: XPath:string(//@pipeline)=PIPE01 matched regex PIPE01
File:./EXINQCSW.webservice Rule 4: XPath:boolean(//*[@validation])=true matched regex true
File:./META-INF/cics.xml Rule 5: XPath:boolean(//*[local-name()='define'][@type="http://www.ibm.com/xmlns/prod/cics/bundle/JVMSERVER"])=false matched regex false
File:./EXINQCSW.urimap Rule 0: XPath:string(//@name)=EXINQCSW matched regex ^EX
File:./EXINQCSW.urimap Rule 1: XPath:string(//@scheme)=HTTP matched regex HTTP
File:./EXINQCSW.urimap Rule 2: XPath:string(//@authenticate)=NO matched regex NO
File:./EXINQCS.urimap Rule 0: XPath:string(//@name)=EXINQCS matched regex ^EX
File:./EXINQCS.urimap Rule 1: XPath:string(//@scheme)=HTTP matched regex HTTP
File:./EXINQCS.urimap Rule 2: XPath:string(//@authenticate)=NO matched regex NO
Exiting with RC=0

This allows for different projects or environments to have their own set of rules.

You can run ./validatecicsbundle -h to get details on the command line options.

When to validate the CICS bundle

Now you have a script and a set of rules to validate the CICS bundle, but when would you run this script?

A CICS bundle typically goes through the following build and deployment stages:

  1. Develop the bundle using CICS Explorer, then check-in the bundle into a source code management (SCM) system, such as Rational Team Concert.
  2. A build script checks out the bundle and any dependent projects from the SCM, calls the CICS build toolkit to build it, and then copies the built bundle into a binary repository, such as a file system or UrbanCode Deploy.
  3. A deployment script copies the built bundle from the binary repository together with a properties file that has variable values unique to the target deployment environment, then calls the CICS build toolkit to resolve variables used in the resource attributes. Finally the bundle is copied to the target zFS and installed into CICS, perhaps using DFHDPLOY or UrbanCode Deploy.

The best time to run the validatecicsbundle script is in stage 3, immediately after you have resolved the variables. This is the point when the bundle will not be changed and you know the details about the target environment. Is it the test, QA or production environment? You can have rules appropriate for each one.

Summary

CICS bundles present a new way to define and manage CICS resources. The resources are defined in XML files so tools such as xmllint can be used find out details about those resources, and tools such as sed used to compare those details against a regular expression. This process can be scripted and the rules combined into a file and run as part of an automated devops pipeline. You can then be confident all the bundles that are deployed only contain resources and attributes that conform to your needs.

It will be interesting to hear via the comments below your experiences deploying CICS bundles and the tools you use, and if you have written scripts that would be useful to others, please consider contributing them to the cics-bundle-scripts project.

References

Join The Discussion

Your email address will not be published. Required fields are marked *