Executing a job (Job class operations)


This sample session walks you through the basics of executing a job. Note that this session uses operations from the Job class. There are similar operations available for installing/uninstalling applications using the Component Template class. For more information, see Installing-or-uninstalling-an-application-Component-Template-class.

To execute a job

  1. Find out what operations are available. To do this, you can use the following URI syntax:
    /type/PropertySetClasses/SystemObject/Job
    Browser example:

    https://myAppServer:9843/type/PropertySetClasses/SystemObject/Job
    ?username=myName&password=myPassword&role=myRole

    This returns a list of available operations. For convenience, a sample list of available operations is included in Available operations and arguments (Job class).

  2. Within your client, construct an HTTP POST request.

This POST request contains a URI that specifies the job and the operation.

  • Job: You can specify the job by using the /id prefix or by using the /group prefix.
  • Operation: You specify the operation by ending the URI with the string "Operations/ <operation_name>"
    For example:

    /id/SystemObject/Job/SnapshotJob/d163b519-4c1d-4830-9972-87386a7e0c8f/
    Operations/execute
    urlConnection.setRequestProperty("Accept", "text/xml");
    /group/Jobs/MyJobs/job1/Operations/executeAgainstServers

    If the operation takes arguments, provide them as data in the POST request. For information about how to do this using the various argument formats, see Argument formats.


Example job request and response

Suppose you want to invoke the following URI:
/group/Jobs/myJobGroup/myJob/Operations/executeAgainstServers
This example shows you how to invoke it against two servers.

  1. The executeAgainstServers  operation takes one argument (list of the URIs of the servers you want to execute against). In addition, you need to pass the name of this one argument (servers) and this argument's type. There are a number of ways to create this request--here is one sample way:

    private String createServerArgument(List<String> uris) throws JSONException, IOException
    {
    StringWriter writer = new StringWriter();
    JSONWriter jsonWriter = new JSONWriter(writer);
    jsonWriter.object();
    jsonWriter.key("OperationArguments");
    jsonWriter.array();
    jsonWriter.object();
    jsonWriter.key("name");
    jsonWriter.value("servers");
    jsonWriter.key("type");
    jsonWriter.value("/type/PropertySetClasses/SystemObject/Server");
    jsonWriter.key("uris");
    jsonWriter.array();
    for(String uri : uris)
    {
    jsonWriter.value(uri);
    }
    jsonWriter.endArray();
    jsonWriter.endObject();
    jsonWriter.endArray();
    jsonWriter.endObject();
    writer.close();
    String data = writer.toString();
    return data;
    }

    This creates the following data, which you include in the POST request that executes the job:
    Request:

    {
    "OperationArguments":[
    {
    "name":"servers",
    "type":"\/type\/PropertySetClasses\/SystemObject\/Server",
    "uris":["URI1","URI2"]}
    ]
    }
  2. After the job executes, it returns an OperationResultResponse, which looks something like this:
    Response:

    {
       "OperationResultResponse":{
           "OperationResult":{
               "type":"String",
               "value":"/id/SystemObject/Job/{job_type}/{job_guid}/Status/{Status_Token}"
           }
       }
    }
  3. If you perform a GET on the URI contained in this response, you get a StatusResponse, which looks something like this:

    {
    "StatusResponse":{
    "Status":{
    "name":"Status3",
    "status":"COMPLETE",
    "uri":"\/id\/SystemObject\/Job\/Update Server Properties Job\/
    95eb1d98-25a4-4212-94a1-17b65768d8f7\/Statuses\/Status3"
    ,
    "targetURI":"\/id\/SystemObject\/Job Run\/a3c0f3e9-bc90-4e15-
    8b50-2c545ab4e907"
    ,
    "hadErrors":"false",
    "hadWarnings":"true",
    "isAbort":"false"
    }
    }
    }
  4. The uri entry is the same URI you used to get this StatusResponse. targetURI provides more detailed information about the job run. If you perform a GET on targetURI, you get a PropertySetInstanceResponse, which looks something like this:

    "PropertySetInstanceResponse":{
           "PropertySetInstance":{
               "name":"Run at Wed Aug 04 15:07:50 EDT 2010",
               "type":"\/type\/PropertySetClasses\/SystemObject\/Job Run",
               "description":"",
               "dbKey":"DBKey:SJobRunModelKeyImpl:3-2000129",
               "objectId":"a3c0f3e9-bc90-4e15-8b50-2c545ab4e907",
               "uri":"\/id\/SystemObject\/Job Run\/a3c0f3e9-bc90-4e15-8b50-2c545ab4e907",
               "modelType":"UPDATE_SERVER_PROPERTY_JOB_RUN",
               "modelTypeId":"386",
               "PropertyValues":{
                   "totalCount":"24",
                   "Elements":[
                       {
                           "name":"HAD_ERRORS",
                           "type":"Boolean",
                           "value":"false",
                           "uri":"\/id\/SystemObject\/Job Run\/a3c0f3e9-bc90-4e15-8b50-2c545ab4e907\/
    PropertyValues\/HAD_ERRORS"

                       },
                       {
                           "name":"IS_ABORTED",
                           "type":"Boolean",
                           "value":"false",
                           "uri":"\/id\/SystemObject\/Job Run\/a3c0f3e9-bc90-4e15-8b50-2c545ab4e907\/
    PropertyValues\/IS_ABORTED"

                       },
                       {
                           "name":"IS_RUNNING",
                           "type":"Boolean",
                           "value":"false",
                           "uri":"\/id\/SystemObject\/Job Run\/a3c0f3e9-bc90-4e15-8b50-2c545ab4e907\/
    PropertyValues\/IS_RUNNING"

                       },
                       {
                           "name":"USER_MODIFIED",
                           "type":"String",
                           "value":"",
                           "uri":"\/id\/SystemObject\/Job Run\/a3c0f3e9-bc90-4e15-8b50-2c545ab4e907\/
    PropertyValues\/USER_MODIFIED"

                       },
                       {
                           "name":"USER_CREATED",
                           "type":"String",
                           "value":"",
                           "uri":"\/id\/SystemObject\/Job Run\/a3c0f3e9-bc90-4e15-8b50-2c545ab4e907\/
    PropertyValues\/USER_CREATED"

                       },
                       {
                           "name":"IS_RESET",
                           "type":"Boolean",
                           "value":"false",
                           "uri":"\/id\/SystemObject\/Job Run\/a3c0f3e9-bc90-4e15-8b50-2c545ab4e907\/
    PropertyValues\/IS_RESET"

                       },
                       {
                           "name":"IS_CANCELLED",
                           "type":"Boolean",
                           "value":"false",
                           "uri":"\/id\/SystemObject\/Job Run\/a3c0f3e9-bc90-4e15-8b50-2c545ab4e907\/
    PropertyValues\/IS_CANCELLED"

                       },
                       {
                           "name":"ROLE_CREATED",
                           "type":"String",
                           "value":"",
                           "uri":"\/id\/SystemObject\/Job Run\/a3c0f3e9-bc90-4e15-8b50-2c545ab4e907\/
    PropertyValues\/ROLE_CREATED"

                       },
                       {
                           "name":"DATE_MODIFIED",
                           "type":"Date",
                           "value":"2010\/08\/04 15:07:53-0400",
                           "uri":"\/id\/SystemObject\/Job Run\/a3c0f3e9-bc90-4e15-8b50-2c545ab4e907\/
    PropertyValues\/DATE_MODIFIED"

                       },
                       {
                           "name":"NAME",
                           "type":"String",
                           "value":"Run at Wed Aug 04 15:07:50 EDT 2010",
                           "uri":"\/id\/SystemObject\/Job Run\/a3c0f3e9-bc90-4e15-8b50-2c545ab4e907\/
    PropertyValues\/NAME"

                       },
                       {
                           "name":"DESCRIPTION",
                           "type":"String",
                           "value":"",
                           "uri":"\/id\/SystemObject\/Job Run\/a3c0f3e9-bc90-4e15-8b50-2c545ab4e907\/
    PropertyValues\/DESCRIPTION"

                       },
                       {
                           "name":"IS_COMPLETED",
                           "type":"Boolean",
                           "value":"true",
                           "uri":"\/id\/SystemObject\/Job Run\/a3c0f3e9-bc90-4e15-8b50-2c545ab4e907\/
    PropertyValues\/IS_COMPLETED"

                       },
                       {
                           "name":"AUTO_GENERATED",
                           "type":"Boolean",
                           "value":"",
                           "uri":"\/id\/SystemObject\/Job Run\/a3c0f3e9-bc90-4e15-8b50-2c545ab4e907\/
    PropertyValues\/AUTO_GENERATED"

                       },
                       {
                           "name":"START_TIME",
                           "type":"Date",
                           "value":"2010\/08\/04 15:07:50-0400",
                           "uri":"\/id\/SystemObject\/Job Run\/a3c0f3e9-bc90-4e15-8b50-2c545ab4e907\/
    PropertyValues\/START_TIME"

                       },
                       {
                           "name":"BROKEN_OBJECT",
                           "type":"Boolean",
                           "value":"",
                           "uri":"\/id\/SystemObject\/Job Run\/a3c0f3e9-bc90-4e15-8b50-2c545ab4e907\/
    PropertyValues\/BROKEN_OBJECT"

                       },
                       {
                           "name":"JOB_NAME",
                           "type":"String",
                           "value":"job_9e0dce5d-761e-4509-bef1-8bc636c73c64",
                           "uri":"\/id\/SystemObject\/Job Run\/a3c0f3e9-bc90-4e15-8b50-2c545ab4e907\/
    PropertyValues\/JOB_NAME"

                       },
                       {
                           "name":"PRIORITY*",
                           "type":"JobPriorityEnumeration",
                           "value":"NORMAL"
                       },
                       {
                           "name":"REQUIRES_REBOOTS",
                           "type":"Boolean",
                           "value":"false",
                           "uri":"\/id\/SystemObject\/Job Run\/a3c0f3e9-bc90-4e15-8b50-2c545ab4e907\/
    PropertyValues\/REQUIRES_REBOOTS"

                       },
                       {
                           "name":"ROLE_MODIFIED",
                           "type":"String",
                           "value":"",
                           "uri":"\/id\/SystemObject\/Job Run\/a3c0f3e9-bc90-4e15-8b50-2c545ab4e907\/
    PropertyValues\/ROLE_MODIFIED"

                       },
                       {
                           "name":"IS_INCOMPLETE",
                           "type":"Boolean",
                           "value":"false",
                           "uri":"\/id\/SystemObject\/Job Run\/a3c0f3e9-bc90-4e15-8b50-2c545ab4e907\/
    PropertyValues\/IS_INCOMPLETE"

                       },
                       {
                           "name":"HAD_WARNINGS",
                           "type":"Boolean",
                           "value":"true",
                           "uri":"\/id\/SystemObject\/Job Run\/a3c0f3e9-bc90-4e15-8b50-2c545ab4e907\/
    PropertyValues\/HAD_WARNINGS"

                       },
                       {
                           "name":"END_TIME",
                           "type":"Date",
                           "value":"2010\/08\/04 15:07:50-0400",
                           "uri":"\/id\/SystemObject\/Job Run\/a3c0f3e9-bc90-4e15-8b50-2c545ab4e907\/
    PropertyValues\/END_TIME"

                       },
                       {
                           "name":"BL_ACL*",
                           "type":"BlAcl",
                           "value":""
                       },
                       {
                           "name":"DATE_CREATED",
                           "type":"Date",
                           "value":"",
                           "uri":"\/id\/SystemObject\/Job Run\/a3c0f3e9-bc90-4e15-8b50-2c545ab4e907\/
    PropertyValues\/DATE_CREATED"

                       }
                    ]
               }
           }
       }
    }

The following example shows how to copy a job using the copy job command:

Job copyJob ${job} ${NewJobName} ${JonGroup} Map<String, String>

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://bladelogic.com/webservices/framework/xsd" xmlns:clit="http://bladelogic.com/webservices/skeleton/clitunnel">
  <soapenv:Header>
     <xsd:transactionId>1</xsd:transactionId>
     <xsd:sessionId>${#TestSuite#sessionid}</xsd:sessionId>
  </soapenv:Header>
  <soapenv:Body>
     <clit:executeCommandByParamList>
        <!--Optional:-->
        <clit:nameSpace>Job</clit:nameSpace>
        <!--Optional:-->
        <clit:commandName>copyJob</clit:commandName>
        <clit:commandArguments>Job</clit:commandArguments>
        <clit:commandArguments>newJobname</clit:commandArguments>
        <clit:commandArguments>jobGroup</clit:commandArguments>
     </clit:executeCommandByParamList>
  </soapenv:Body>
</soapenv:Envelope>

Using asynchronous job notification

When you execute a job, you can use one of the following methods to obtain the job completion status:

  • Your REST client can use a polling thread to get the job's completion status. (This is the method described in detail above in Example job request and response.)
  • As an alternative, you can design your POST request to specify that you want the system to automatically send a status notification to a URL when the job ends.

Summary of polling method

To clarify the differences between the polling method and the notification method, here is a quick summary of the polling method:

Sample REST request

https://localhost:9843/group/Jobs/folder/snapshotJob/Operations/
execute?username="BLAdmin"&password=""&role="BLAdmins"

This request might return an OperationResultResponse that looks something like:

<?xml version='1.0' encoding='UTF-8'?>
<RESTXMLResponse>
<OperationResultResponse>
   <OperationResult type="Statuses"
       value="/id/SystemObject/Job/Snapshot Job/b3561823-
7800-4dc1-b0f5-830e5c93aa93/Statuses/Schedule3"
/>
   <OperationResult type="Statuses"
       value="/id/SystemObject/Job/Snapshot Job/b3561823-
7800-4dc1-b0f5-830f5d93ab93/Statuses/Schedule4"
/>
   </OperationResultResponse>
</RESTXMLResponse>

Polling step

The client now would have to take the most recent job run value from the OperationResult and poll like this:

https://localhost:9843/id/SystemObject/Job/Snapshot%20Job/b3561823-7800
-4dc1-b0f5-830f5d93ab93/Statuses/Schedule4?username=%22BLAdmin%22&password=%22%22&role=%22BLAdmins%22

This poll returns the job's completion status (StatusResponse), and would look something like this:

<RESTXMLResponse>
   <StatusResponse>
       <Status name="Status4" status="COMPLETE"
         uri="/id/SystemObject/Job/Snapshot Job/b3561823-7800-4dc1-
b0f5-830f5d93ab93/Statuses/Status4"

        targetURI="/id/SystemObject/Job Run/912384e8-0f16-4657-bc45-54d7ced51b18"
        hadErrors="false" hadWarnings="false" isAbort="false"/>
   </StatusResponse>
</RESTXMLResponse>

Note

In relatively new TrueSight Server Automation systems, the schedule number and status number are often the same, as in the current example. As time goes on, these numbers typically fall out of sync, and the job status number might be different (that is, higher) than the schedule number. 

Asynchronous notification alternative

As an alternative to having to poll to get the completion status, you can include a notifyURL argument in the initial POST. This argument specifies a URL where the system can send the StatusResponse.
For example, you might include the following data in the POST request that executes the job:
Request:

https://localhost:9843/group/Jobs/Test/FileDeploy/Operations/execute?username=BLAdmin
&password=""&role=BLAdmins&notifyURL=https://my.notification.url&notifyRetryCount=3

For further arguments that you can include in this request, see Notification arguments.

After the StatusResponse arrives at the notification URL, you need to identify the correct job and job run with which this status is associated. To do this, use the value of the OperationResult that got returned from your first request. In this example, the OperationResult is:

<OperationResult type="Statuses"
       value="/id/SystemObject/Job/Snapshot Job/
b3561823-7800-4dc1-b0f5-830f5d93ab93/Statuses/Schedule4"
/>

Use the value up to Statuses (without the Schedule number) to query for all runs of the job with the specified ID:

"/id/SystemObject/Job/Snapshot Job/
b3561823-7800-4dc1-b0f5-830f5d93ab93/Statuses"

From the list of job runs that is returned, choose the most recent, that is, the status name that contains the highest number.

In this example, the most recent job run has the following status:

<Status name="Status4" status="COMPLETE"
uri="/id/SystemObject/Job/Snapshot Job/b3561823-7800-4dc1-b0f5-830f5d93ab93/Statuses/Status4"
targetURI="/id/SystemObject/Job Run/912384e8-0f16-4657-bc45-54d7ced51b18"
hadErrors="false" hadWarnings="false" isAbort="false"/>

so the URI is:

"/id/SystemObject/Job/Snapshot Job/b3561823-7800-4dc1-b0f5-830f5d93ab93/
Statuses/Status4"

In this example, you determined that Schedule number 4 (from the OperationResult) represents a job run with Status number 4 for obtaining notification information.

Note

In relatively new TrueSight Server Automation systems, the schedule number and status number are often the same, as in the current example. As time goes on, these numbers typically fall out of sync, and the job status number might be different (that is, higher) than the schedule number. 

Notification arguments

In addition to the notifyURL argument described above, there are a number of additional notification arguments:

Argument

Description

notifyURL=<url to POST the completion notification>

Required if you want to trigger the notification mechanism.

notifyAccept=JSON

Optional. HTTP_ACCEPT MIME type. The default is JSON.

notifyRetryCount=3

Optional. Number of retries. The default is 10.

notifyRetryPause=10

Optional. Number of seconds between retries. The default is 20 seconds.

notifyTimeout=30

Optional. Time to wait before failing a socket connection and also the read timeout for receiving confirmation back. Thus a 30 second timeout might reach nearly 60 seconds and still work. The default is 300.

Available operations and arguments (Job class)

<Operation name="execute" returnType="Statuses" />
 <Operation name="executeAgainstComponents" returnType="Statuses">
 <OperationArguments totalCount="1">
 <OperationArgument name="components" type="/type/PropertySetClasses/
SystemObject/Component"
list="true" />
 </OperationArguments>
 </Operation>
 <Operation name="executeAgainstServers" returnType="Statuses">
 <OperationArguments totalCount="1">
 <OperationArgument name="servers" type="/type/PropertySetClasses/
SystemObject/Server"
list="true" />
 </OperationArguments>
 </Operation>
 <Operation name="executeAgainstStaticServerGroups" returnType="Statuses">
 <OperationArguments totalCount="1">
 <OperationArgument name="staticServerGroups" type="/type/PropertySetClasses/
SystemObject/
Static Group"
list="true" />
 </OperationArguments>
 </Operation>
 <Operation name="executeAgainstSmartServerGroups" returnType="Statuses">
 <OperationArguments totalCount="1">
 <OperationArgument name="smartServerGroups" type="/type/PropertySetClasses/
SystemObject/Smart Group"
list="true" />
 </OperationArguments>
 </Operation>
 <Operation name="executeAgainstStaticComponentGroups" returnType="Statuses">
 <OperationArguments totalCount="1">
 <OperationArgument name="staticComponentGroups" type="/type/PropertySetClasses/SystemObject/
Static Group"
list="true" />
 </OperationArguments>
 </Operation>
 <Operation name="executeAgainstSmartComponentGroups" returnType="Statuses">
 <OperationArguments totalCount="1">
 <OperationArgument name="smartComponentGroups" type="/type/PropertySetClasses/
SystemObject/Smart Group"
list="true" />
 </OperationArguments>
 </Operation>
</Operation> 

Argument formats

You can use the following argument formats:

  • Primitive
  • Class instance
  • URI

The following examples show how to use these formats. Note the following when formatting arguments:

  • You need to specify the name and type of each argument.
  • Depending on the argument type (and also whether it is a single or a list), the tag name is different. For example: value, values, ClassInstance, ClassInstances, uri, uris.
  • The name and type must match the operation signature provided in the GET operation.
{
   "OperationArguments":[
       {
           "name":"singlePrimitive",
           "type":"String",
           "value":"Some String"
       },
       {
           "name":"listPrimitive",
           "type":"String",
           "values":[
               "Some String 1",
               "Some String 2"
            ]
       },
       {
           "name":"singleClassInstance",
           "type":"/type/PropertySetClasses/SystemObject/User",
           "ClassInstance":{
               "name":"RESTTestUser1274991923976",
               "type":"/type/PropertySetClasses/SystemObject\/User",
               "description":"a user",
               "dbKey":"",
               "objectId":"bf10f2ab-301f-4853-ba24-36c026ba1fe8",
               "PropertyValues":[
                   {
                       "PropertyValue":{
                           "name":"DESCRIPTION",
                           "type":"String",
                           "value":"a user"
                       }
                   },
                   {
                       "PropertyValue":{
                           "name":"NAME",
                           "type":"String",
                           "value":"RESTTestUser1274991923976"
                       }
                   }
                ]
           }
       },
       {
           "name":"listClassInstance",
           "type":"/type/PropertySetClasses/SystemObject/User",
           "ClassInstances":[
               {
                   "name":"RESTTestUser1274991923976",
                   "type":"/type/PropertySetClasses/SystemObject\/User",
                   "description":"a user",
                   "dbKey":"",
                   "objectId":"bf10f2ab-301f-4853-ba24-36c026ba1fe8",
                   "PropertyValues":[
                       {
                           "PropertyValue":{
                               "name":"DESCRIPTION",
                               "type":"String",
                               "value":"a user"
                           }
                       },
                       {
                           "PropertyValue":{
                       "name":"NAME",
                               "type":"String",
                               "value":"RESTTestUser1274991923976"
                           }
                       }
                    ]
               },
               {
                   "name":"RESTTestUser1274991923976",
                   "type":"/type/PropertySetClasses/SystemObject\/User",
                   "description":"a user",
                   "dbKey":"",
                   "objectId":"bf10f2ab-301f-4853-ba24-36c026ba1fe8",
                   "PropertyValues":[
                       {
                           "PropertyValue":{
                               "name":"DESCRIPTION",
                               "type":"String",
                               "value":"a user"
                           }
                       },
                       {
                           "PropertyValue":{
                               "name":"NAME",
                               "type":"String",
                               "value":"RESTTestUser1274991923976"
                           }
                       }
                    ]
               }
            ]
       },
       {
           "name":"singleURI",
           "type":"/type/PropertySetClasses/SystemObject/User",
           "uri":"/id/SystemObject/User/abcd1245"
       },
       {
           "name":"multipleURIs",
           "type":"/type/PropertySetClasses/SystemObject/User",
           "uris":[
               "/id/SystemObject/User/abcd1245",
               "/id/SystemObject/User/abcd6789"
            ]
       }
    ]
}

 

Tip: For faster searching, add an asterisk to the end of your partial query. Example: cert*