Creating Your First Job Flow

This example shows how to write command and script jobs that run in sequence.

Before You Begin

Ensure that you meet the following prerequisites:

  • You have successfully completed API setup, as described in Setting Up the API.

  • You have Git installed. If not, obtain it from the Git Downloads page.

  • You have local copies of the tutorial samples from GitHub and a local copy of the source code using the git clone command:

    Copy
    git clone https://github.com/controlm/automation-api-quickstart.git

Step 1: Access the Tutorial Samples

Go to the directory where the tutorial sample is located:

Copy
cd automation-api-quickstart/helix-control-m/101-create-first-job-flow

Step 2: Verify the Code for Control-M

Let's take the AutomationAPISampleFlow.json file, which contains job definitions, and verify that the code within it is valid. To do so, use the build command. The following example shows the command and a typical successful response.

Copy
> ctm build AutomationAPISampleFlow.json
 
[
   {
      "deploymentFile": "AutomationAPISampleFlow.json",
      "successfulFoldersCount": 0,
      "successfulSmartFoldersCount": 1,
      "successfulSubFoldersCount": 0,
      "successfulJobsCount": 2,
      "successfulConnectionProfilesCount": 0,
      "isDeployDescriptorValid": false
   }
]

If the code is not valid, an error is returned.

Step 3: Run the Source Code

Use the run command to run the jobs on the Control-M environment. The returned runId is used to check the job status. The following shows the command and a typical successful response.

Copy
> ctm run AutomationAPISampleFlow.json
 
{
  "runId": "7cba67de-9e0d-409d-8d93-1b8229432eee",
  "statusURI": "https://controlmEndPointHost/automation-api/run/status/7cba67de-9e0d-409d-8d93-1b82294e"
}

This code ran successfully and returned the runId of "7cba67de-9e0d-409d-8d93-1b8229432eee".

Step 4: Check Job Status Using the runId

The following command shows how to check job status using the runId. Note that when there is more than one job in the flow, the status of each job is checked and returned.

Copy
> ctm run status "7cba67de-9e0d-409d-8d93-1b8229432eee"
 
{
  "statuses": [
    {
      "jobId": "IN01:00007",
      "folderId": "IN01:00000",
      "numberOfRuns": 1,
      "name": "AutomationAPISampleFlow",
      "type": "Folder",
      "status": "Executing",
      "held": "false",
      "deleted": "false",
      "cyclic": "false",
      "startTime": "Apr 26, 2020 10:43:47 AM",
      "endTime": "",
      "estimatedStartTime": [],
      "estimatedEndTime": [],
      "outputURI": "Folder has no output",
      "logURI": "https://controlmEndPointHost/automation-api/run/job/IN01:00007/log"
    },
    {
      "jobId": "IN01:00008",
      "folderId": "IN01:00007",
      "numberOfRuns": 0,
      "name": "CommandJob",
      "folder": "AutomationAPISampleFlow",
      "type": "Command",
      "status": "Wait Host",
      "held": "false",
      "deleted": "false",
      "cyclic": "false",
      "startTime": "",
      "endTime": "",
      "estimatedStartTime": [],
      "estimatedEndTime": [],
      "outputURI": "Job did not run, it has no output",
      "logURI": "https://controlmEndPointHost/automation-api/run/job/IN01:00008/log"
    },
    {
      "jobId": "IN01:00009",
      "folderId": "IN01:00007",
      "numberOfRuns": 0,
      "name": "ScriptJob",
      "folder": "AutomationAPISampleFlow",
      "type": "Job",
      "status": "Wait Condition",
      "held": "false",
      "deleted": "false",
      "cyclic": "false",
      "startTime": "",
      "endTime": "",
      "estimatedStartTime": [],
      "estimatedEndTime": [],
      "outputURI": "Job did not run, it has no output",
      "logURI": "https://controlmEndPointHost/automation-api/run/job/IN01:00009/log"
    }
  ],
  "startIndex": 0,
  "itemsPerPage": 25,
  "total": 3

Step 5: Examine the Source Code

Let's look at the source code in the AutomationAPISampleFlow.json file. By examining the contents of this file, you'll learn about the structure of the job flow and what it should contain.

Copy
{
   "Defaults" : {
      "Application" : "SampleApp",
      "SubApplication" : "SampleSubApp",
      "RunAs" : "USERNAME",
      "Host" : "HOST",
      "Job": {
         "When" : {
            "Months": ["JAN", "OCT", "DEC"],
            "MonthDays":["22","1","11"],
            "WeekDays":["MON","TUE", "WED", "THU", "FRI"],
            "FromTime":"0300",
            "ToTime":"2100"
         },
         "ActionIfFailure" : {
            "Type": "If",
            "CompletionStatus": "NOTOK",
            "mailToTeam": {
               "Type": "Mail",
               "Message": "%%JOBNAME failed",
               "To": "[email protected]"
            }
         }
      }
   },
   "AutomationAPISampleFlow": {
      "Type": "Folder",
      "Comment" : "Code reviewed by John",
      "CommandJob": {
         "Type": "Job:Command",
         "Command": "echo my 1st job"
      },
      "ScriptJob": {
         "Type": "Job:Script",
         "FilePath":"SCRIPT_PATH",
         "FileName":"SCRIPT_NAME"
      },
      "Flow": {
         "Type": "Flow",
         "Sequence": ["CommandJob", "ScriptJob"]
      }
   }
}

The first object is called "Defaults". It allows you to define a parameter once for all objects. For example, it includes scheduling using the When parameter, which configures all jobs to run according to the same scheduling criteria. The "ActionIfFailure" object determines what action is taken if a job ends unsuccessfully.

This example contains two jobs: CommandJob and ScriptJob. These jobs are contained within a folder named AutomationAPISampleFlow. To define the sequence of job execution, the Flow object is used.

Step 6: Modify the Code to Run in Your Environment

In the code above, the following parameters need to be set to run the jobs in your environment. Change the values to match your Control-M environment.

Copy
"RunAs" : "USERNAME"
"Host" : "HOST"
 
"FilePath":"SCRIPT_PATH"
"FileName":"SCRIPT_NAME"
  • RunAs identifies the operating system user that will execute the jobs on the Agent.

  • Host defines the Agent machine where the jobs will run.

  • FilePath and FileName define the location and name of a file that contains a script to run on the Control-M/Agent.

Step 7: Rerun the Code Sample

Now that we've modified the source code in the AutomationAPISampleFlow.json file, let's rerun the sample:

Copy
> ctm run AutomationAPISampleFlow.json
 
{
  "runId": "ed40f73e-fb7a-4f07-a71c-bc2dfbc48494",
  "statusURI": "https://controlmEndPointHost/automation-api/run/status/ed40f73e-fb7a-4f07-a71c-bc2dfbc48494"
}

Each time you run the code, a new runId is generated. Let's take the new runId, and check the jobs statuses again:

Copy
> ctm run status "ed40f73e-fb7a-4f07-a71c-bc2dfbc48494"
 
{
  "statuses": [
    {
      "jobId": "IN01:0000p",
      "folderId": "IN01:00000",
      "numberOfRuns": 1,
      "name": "AutomationAPISampleFlow",
      "type": "Folder",
      "status": "Ended OK",
      "held": "false",
      "deleted": "false",
      "cyclic": "false",
      "startTime": "May 3, 2020 4:57:25 PM",
      "endTime": "May 3, 2020 4:57:28 PM",
      "estimatedStartTime": [],
      "estimatedEndTime": [],
      "outputURI": "Folder has no output",
      "logURI": "https://controlmEndPointHost/automation-api/run/job/IN01:0000p/log"
    },
    {
      "jobId": "IN01:0000q",
      "folderId": "IN01:0000p",
      "numberOfRuns": 1,
      "name": "CommandJob",
      "folder": "AutomationAPISampleFlow",
      "type": "Command",
      "status": "Ended OK",
      "held": "false",
      "deleted": "false",
      "cyclic": "false",
      "startTime": "May 3, 2020 4:57:26 PM",
      "endTime": "May 3, 2020 4:57:26 PM",
      "estimatedStartTime": [],
      "estimatedEndTime": [],
      "outputURI": "https://controlmEndPointHost/automation-api/run/job/IN01:0000q/output",
      "logURI": "https://controlmEndPointHost/automation-api/run/job/IN01:0000q/log"
    },
    {
      "jobId": "IN01:0000r",
      "folderId": "IN01:0000p",
      "numberOfRuns": 1,
      "name": "ScriptJob",
      "folder": "AutomationAPISampleFlow",
      "type": "Job",
      "status": "Ended OK",
      "held": "false",
      "deleted": "false",
      "cyclic": "false",
      "startTime": "May 3, 2020 4:57:27 PM",
      "endTime": "May 3, 2020 4:57:27 PM",
      "estimatedStartTime": [],
      "estimatedEndTime": [],
      "outputURI": "https://controlmEndPointHost/automation-api/run/job/IN01:0000r/output",
      "logURI": "https://controlmEndPointHost/automation-api/run/job/IN01:0000r/log"
    }
  ],
  "startIndex": 0,
  "itemsPerPage": 25,
  "total": 3
}

You can now see that both jobs Ended OK.

Let's view the output of CommandJob. Use the jobId to get this information, as in the following example:

Copy
> ctm run job:output::get "IN01:0000q"
 
+ echo my 1st job
my 1st job

Where to Go from Here

To learn more about what you can do with the Control-M Automation API, read through Code Reference and Services.