IspwHelper.groovy

package com.compuware.devops.util

import groovy.json.JsonSlurper
import jenkins.plugins.http_request.*
import com.compuware.devops.util.TaskInfo

/* Wrapper class to simplify use of ISPW functions */
class IspwHelper implements Serializable
{
    def steps

    def String ispwUrl
    def String ispwRuntime
    def String ispwApplication
    def String ispwRelease
    def String ispwContainer
    def String ispwContainerType
    def String applicationPathNum
    def String ispwOwner
    def String ispwTargetLevel


    def String mfSourceFolder

    def String hciConnId
    def String hciTokenId

IspwHelper

    IspwHelper(steps, pConfig)
    {

        this.steps              = steps
        this.ispwUrl            = pConfig.ispwUrl
        this.ispwRuntime        = pConfig.ispwRuntime
        this.ispwApplication    = pConfig.ispwApplication
        this.ispwRelease        = pConfig.ispwRelease
        this.ispwContainer      = pConfig.ispwContainer
        this.ispwContainerType  = pConfig.ispwContainerType
        this.ispwOwner          = pConfig.ispwOwner
        this.ispwTargetLevel    = pConfig.ispwTargetLevel
        this.applicationPathNum = pConfig.applicationPathNum

        this.mfSourceFolder     = pConfig.mfSourceFolder

        this.hciConnId          = pConfig.hciConnId
        this.hciTokenId         = pConfig.hciTokenId
    }

downloadSources

    /* Download sources for the ISPW Set which triggered the current pipeline */
    def downloadSources()
    {
        steps.checkout([
            $class:             'IspwContainerConfiguration',
            componentType:      '',                                 // optional filter for component types in ISPW
            connectionId:       "${hciConnId}",
            credentialsId:      "${hciTokenId}",
            containerName:      "${ispwContainer}",
            containerType:      "${ispwContainerType}",     // 0-Assignment 1-Release 2-Set
            ispwDownloadAll:    true,                              // false will not download files that exist in the workspace and haven't previous changed
            serverConfig:       '',                                 // ISPW runtime config.  if blank ISPW will use the default runtime config
            serverLevel:        ''                                  // level to download the components from
        ])
    }

    /* Download copy books used in the downloaded sources  */
    /* Since copy books do not have to be part of the current set, the downloaded programs need to be parsed to determine copy books */
    /* Since the SCM downloader plugin does not provide the option to download specific members, */
    /* the required copy books will be copied from the ISPW libraries to a single PDS using an IEBCOPY job */
    /* Then this PDS will be downloaded */
    def downloadCopyBooks(String workspace)
    {
        /* Class JclSkeleton will allow using "JCL Skeletons" to generate the requires JCL */
        JclSkeleton jclSkeleton = new JclSkeleton(steps, workspace, ispwApplication, applicationPathNum)

        /* A Groovy idiosyncrasy prevents constructors to use methods, therefore class might require an additional "initialize" method to initialize the class */
        jclSkeleton.initialize()

        /* Method referencedCopyBooks will parse the downloaded sources and generate a list of required copy books */
        def copyBookList = referencedCopyBooks(workspace)  

        if(copyBookList.size() > 0)
        {
            // Get a string with JCL to create a PDS with referenced Copybooks
            def pdsDatasetName  = 'HDDRXM0.DEVOPS.ISPW.COPY.PDS'

            // The createIebcopyCopyBooksJcl will create the JCL for the IEBCOPY job */
            def processJcl      = jclSkeleton.createIebcopyCopyBooksJcl(pdsDatasetName, copyBookList)

            // Submit the JCL created to create a PDS with Copybooks
            steps.topazSubmitFreeFormJcl( 
                connectionId:       "${hciConnId}",
                credentialsId:      "${hciTokenId}",
                jcl:                processJcl,
                maxConditionCode:   '4'
            )

            // Download the generated PDS
            steps.checkout([
                $class:         'PdsConfiguration',
                connectionId:   "${hciConnId}",
                credentialsId:  "${hciTokenId}",
                fileExtension:  'cpy',
                filterPattern:  "${pdsDatasetName}",
                targetFolder:   "${ispwApplication}/${mfSourceFolder}"
            ])

            // Delete the downloaded Dataset
            processJcl = jclSkeleton.createDeleteTempDsn(pdsDatasetName)

            steps.topazSubmitFreeFormJcl(
                connectionId:       "${hciConnId}",
                credentialsId:      "${hciTokenId}",
                jcl:                processJcl,
                maxConditionCode:   '4'
            )
        }
        else
        {
            steps.echo "No Copy Books to download"
        }
    }

referencedCopyBooks

    /* Parse downloaded sources and get a list of copy books */
    def List referencedCopyBooks(String workspace)
    {

        steps.echo "Get all .cbl in current workspace"

        // findFiles method requires the "Pipeline Utilities Plugin"
        // Get all Cobol Sources in the MF_Source folder into an array 
        def listOfSources   = steps.findFiles(glob: "**/${ispwApplication}/${mfSourceFolder}/*.cbl")
        def listOfCopybooks = []
        def lines           = []
        def cbook           = /\bCOPY\b/
        def tokenItem       = ''
        def seventhChar     = ''
        def lineToken       = ''

        // Define a empty array for the list of programs
        listOfSources.each
        {
            steps.echo "Scanning Program: ${it}"
            def cpyFile = "${workspace}\\${it}"

            File file = new File(cpyFile)

            if (file.exists())
            {
                lines = file.readLines().findAll({book -> book =~ /$cbook/})

                lines.each
                {
                    lineToken   = it.toString().tokenize()
                    seventhChar = ""

                    if (lineToken.get(0).toString().length() >= 7)
                    {
                        seventhChar = lineToken.get(0).toString()[6]
                    }

                    for(int i=0;i<lineToken.size();i++)
                    {
                        tokenItem = lineToken.get(i).toString()

                        if (tokenItem == "COPY" && seventhChar != "*" )
                        {
                            steps.echo "Copybook: ${lineToken.get(i+1)}"
                            tokenItem = lineToken.get(i+1).toString()

                            if (tokenItem.endsWith("."))
                            {
                                listOfCopybooks.add(tokenItem.substring(0,tokenItem.size()-1))
                            }
                            else
                            {
                                listOfCopybooks.add(tokenItem)
                            }

                        i = lineToken.size()
                        }
                    }
                }
            }
        }

        return listOfCopybooks

    }

RegressAssignmentList

    /* Regress a list of assignments */
    def regressAssignmentList(assignmentList, cesToken)
    {
        for(int i = 0; i < assignmentList.size(); i++)
        {

            steps.echo "Regress Assignment ${assignmentList[0].toString()}, Level ${ispwTargetLevel}"

            regressAssignment(assignmentList[i], cesToken)

        }
    }

regressAssignment

    /* Regress one assignment */
    def regressAssignment(assignment, cesToken)
    {
        def requestBodyParm = '''{
            "runtimeConfiguration": "''' + ispwRuntime + '''"
        }'''

        steps.httpRequest(
                url:                    "${ispwUrl}/ispw/${ispwRuntime}/assignments/${assignment}/tasks/regress?level=${ispwTargetLevel}",
                httpMode:               'POST',
                consoleLogResponseBody: true,
                contentType:            'APPLICATION_JSON',
                requestBody:            requestBodyParm,
                customHeaders:          [[
                                        maskValue:  true,
                                        name:       'authorization',
                                        value:      "${cesToken}"
                                        ]]
            )
    }
}