Skip to content

API

In addition to the Mantis UI, there is a REST API with which you can maintain Mantis Jobs and Job Clusters. This page describes the open source version of the Mantis REST API.

You can use the Mantis REST API to submit Jobs based on existing Job Cluster or to connect to the output of running Jobs. It is easier to set up or update new Job Clusters by using the Mantis UI, but you can also do this with the Mantis REST API.

Response Content Type

Mantis API endpoints always return JSON, and do not respect content-type headers in API requests.

Summary of REST API

Cluster APIs

endpoint verb purpose
/api/v1/jobClusters GET Return a list of Mantis clusters.
/api/v1/jobClusters POST Create a new cluster.
/api/v1/jobClusters/clusterName GET Return information about a single cluster by name.
/api/v1/jobClusters/clusterName PUT Update the information about a particular cluster.
/api/v1/jobClusters/clusterName DELETE Permanently delete a paticular cluster.
/api/v1/jobClusters/clusterName/actions/updateArtifact POST Update the job cluster artifact and optionally resubmit the job.
/api/v1/jobClusters/clusterName/actions/updateSla POST Update cluster SLA information.
/api/v1/jobClusters/clusterName/actions/updateMigrationStrategy POST Update the cluster migration strategy.
/api/v1/jobClusters/clusterName/actions/updateLabel POST Update cluster labels.
/api/v1/jobClusters/clusterName/actions/enableCluster POST Enable a disabled cluster.
/api/v1/jobClusters/clusterName/actions/disableCluster POST Disable a cluster.
/api/v1/mantis/publish/streamJobClusterMap GET Return a mapping of Mantis Publish push-based streams to clusters.

Job APIs

endpoint verb purpose
/api/v1/jobs GET Return a list of jobs.
/api/v1/jobClusters/clusterName/jobs GET Return a list of jobs for a particular cluster.
/api/v1/jobs/jobID GET Return information about a particular job.
/api/v1/jobClusters/clusterName/jobs/jobID GET Return information about a particular job.
/api/v1/jobs/jobID DELETE Permanently kill a particular job.
/api/v1/jobClusters/clusterName/jobs POST Submit a new job.
/api/v1/jobs/actions/quickSubmit POST Update a job cluster and submit a new job at the same time.
/api/v1/jobs/jobID/actions/postJobStatus POST Post job heartbeat status.
/api/v1/jobs/jobID/actions/scaleStage POST Horizontally scale a stage.
/api/v1/jobs/jobID/actions/resubmitWorker POST Resubmit a worker.

Admin APIs

endpoint verb purpose
/api/v1/masterInfo GET Return Job Master information.
/api/v1/masterConfigs GET Return Job Master configs.
/api/v1/agentClusters/ GET Get information about active agent clusters.
/api/v1/agentClusters/ POST Activate or deactivate an agent cluster.
/api/v1/agentClusters/jobs GET Get jobs and host information for an agent cluster.
/api/v1/agentClusters/autoScalePolicy GET Retrieve the Agent Cluster Scaling Policy.

Streaming WebSocket/SSE APIs

endpoint verb purpose
ws://masterHost:7101/api/v1/jobStatusStream/jobID n/a Stream Job Status Changes.
/api/v1/jobDiscoveryStream/jobID (SSE) GET Return streaming (SSE) scheduling information for a particular job.
/api/v1/jobs/schedulingInfo/jobID (SSE) GET Return streaming (SSE) scheduling information for a particular job.
/api/v1/jobClusters/discoveryInfoStream/clusterName (SSE) GET Return streaming (SSE) discovery info for the given job cluster.
/api/v1/lastSubmittedJobIdStream/clusterName (SSE) GET Return streaming (SSE) job information for a particular cluster.
/api/v1/jobConnectbyid/jobID (SSE) n/a Collect messages from the job sinks and merge them into a single websocket or SSE stream.
/api/v1/jobConnectbyname/jobName (SSE) n/a Collect messages from the job sinks and merge them into a single websocket or SSE stream.
/api/v1/jobsubmitandconnect (SSE) POST Submit a job, collect messages from the job sinks, and merge them into a single websocket or SSE stream.

Cluster Tasks

TBD

Get a List of Clusters

  • /api/v1/jobClusters (GET)

To retrieve a list of JSON objects that include details about the available Job Clusters, issue a GET command to the Mantis REST API endpoint /api/v1/jobClusters/.

Query Parameters
Query Parameter Purpose
ascending (optional) You can use this to indicate whether or not to sort the records in ascending order (true
fields (optional) By default this endpoint will return all of the fields in the payload. You can set fields to a comma-delimited series of payload fields, in which case this endpoint will return only those fields of the payload. For example ?fields=name.
offset (optional) The record number to begin with in the set of records to return in this request (use this with pageSize to get records by the page). See Pagination for more details.
pageSize (optional) The maximum number of records to return in this request (default = 0, which means all records). See Pagination for more details.
sortBy (optional) You can set this to the name of any payload field whose values are Comparable and this endpoint will return its results sorted by that field.
matching (optional) You can set this to a regular expression, and Mantis will filter the list of Job Clusters on the server side, and will return only those that match this expression.
Example Response Format

GET /api/v1/jobClusters?pageSize=5&fields=name&sortBy=name&ascending=false

{
  "list":
    [{"name":"jschmoeSLATest"},
     {"name":"sinefn"},
     {"name":"Validation_ZV93BAWR2"},
     {"name":"Validation_Z8NB06L1A"},
     {"name":"Validation_Y828QAI01"}],
  "prev":null,
  "next":"/api/v1/jobClusters?pageSize=5&fields=name&sortBy=name&ascending=false&offset=5"
}
Possible Response Codes
Response Code Reason
200 normal response
405 incorrect HTTP verb (use GET instead)
500 unknown server error

Create a New Cluster

  • /api/v1/jobClusters (POST)

Before you submit a Mantis Job, you must first have set up a Job Cluster. A Job Cluster contains a unique name for the Job, a URL of the Job’s .jar or .zip artifact file, resource requirements to run your Job, and other optional information such as SLA values for minimum and maximum Jobs to keep active for this Cluster, or a cron-based schedule to launch a Job for this Cluster. Each new Job can be considered as an instance of the Job Cluster, and is given a unique ID by appending a number suffix to the Cluster name. The Job inherits the resource requirements from the Cluster unless whoever submits the Job overrides these at submit time.

A Job Cluster name must match this regular expression: ^[A-Za-z]+[A-Za-z0-9+-_=:;]*

To create a new Job Cluster, issue a POST command to the Mantis REST API endpoint /api/v1/jobClusters with a request body that matches format of the following example:

Example Request Body
{
  "jobDefinition": {
    "name": "jschmoe_validation",
    "user": "jschmoe",
    "jobJarFileLocation": "https://some.host/mantis-artifacts/mantis-examples-sine-function-0.2.9.zip",
    "version": "0.2.9 2019-03-19 17:01:36",
    "schedulingInfo": {
      "stages": {
        "1": {
          "numberOfInstances": "1",
          "machineDefinition": {
            "cpuCores": "1",
            "memoryMB": "1024",
            "diskMB": "1024",
            "networkMbps": "128",
            "numPorts": "1"
          },
          "scalable": false,
          "softConstraints": [],
          "hardConstraints": []
        }
      }
    },
    "parameters": [],
    "labels": [
      {
        "name": "_mantis.user",
        "value": "jschmoe"
      },
      {
        "name": "_mantis.ownerEmail",
        "value": "jschmoe@netflix.com"
      },
      {
        "name": "_mantis.artifact",
        "value": "mantis-examples-sine-function"
      },
      {
        "name": "_mantis.artifact.version",
        "value": "0.2.9"
      }
    ],
    "migrationConfig": {
      "strategy": "PERCENTAGE",
      "configString": "{\"percentToMove\":25,\"intervalMs\":60000}"
    },
    "slaMin": "0",
    "slaMax": "0",
    "cronSpec": null,
    "cronPolicy": "KEEP_EXISTING"
  },
  "owner": {
    "contactEmail": "jschmoe@netflix.com",
    "description": "",
    "name": "Joe Schmoe",
    "repo": "",
    "teamName": ""
  }
}
Example Response Format
{
  "name": "jschmoe_validation1",
  "jars": [
    {
      "url": "https://mantis.us-east-1.prod.netflix.net/mantis-artifacts/mantis-examples-sine-function-0.2.9.zip",
      "uploadedAt": 1553040262171,
      "version": "0.2.9 2019-03-19 17:01:36",
      "schedulingInfo": {
        "stages": {
          "1": {
            "numberOfInstances": 1,
            "machineDefinition": {
              "cpuCores": 1,
              "memoryMB": 1024,
              "networkMbps": 128,
              "diskMB": 1024,
              "numPorts": 1
            },
            "hardConstraints": [],
            "softConstraints": [],
            "scalingPolicy": null,
            "scalable": false
          }
        }
      }
    }
  ],
  "sla": {
    "min": 0,
    "max": 0,
    "cronSpec": null,
    "cronPolicy": null
  },
  "parameters": [],
  "owner": {
    "name": "Joe Schmoe",
    "teamName": "",
    "description": "",
    "contactEmail": "jschmoe@netflix.com",
    "repo": ""
  },
  "lastJobCount": 0,
  "disabled": false,
  "isReadyForJobMaster": false,
  "migrationConfig": {
    "strategy": "PERCENTAGE",
    "configString": "{\"percentToMove\":25,\"intervalMs\":60000}"
  },
  "labels": [
    {
      "name": "_mantis.user",
      "value": "jschmoe"
    },
    {
      "name": "_mantis.ownerEmail",
      "value": "jschmoe@netflix.com"
    },
    {
      "name": "_mantis.artifact",
      "value": "mantis-examples-sine-function"
    },
    {
      "name": "_mantis.artifact.version",
      "value": "0.2.9"
    }
  ],
  "cronActive": false,
  "latestVersion": "0.2.9 2019-03-19 17:01:36"
}
Possible Response Codes
Response Code Reason
201 normal response
405 incorrect HTTP verb (use POST instead)
409 cluster name already exists
500 unknown server error

Setting Jobs to Launch at Particular Times

You can use the cronSpec field in the body of this request to specify when to launch the Jobs in the Cluster. By default this is blank ("").

If you set cronSpec to a non-blank value, this also sets the min and max values for the Job Cluster to 0 and 1 respectively. That is to say, you can have no more than one Job running at any one time for that Cluster.

Optionally, you can provide a policy (cronpolicy) to use when a cron trigger fires while a previosuly submitted Job for the Job Cluster is still running. The possible policy values are KEEP_EXISTING (do not replace the current Job) and KEEP_NEW (replace the current Job with a new one). The default policy is KEEP_EXISTING.

Note

If the Mantis Master is down during a time window when cron would normally have fired, that cron trigger time window is lost. Mantis does not check for this upon restart. The next cron trigger will resume normally.


Get Information about a Cluster

  • /api/v1/jobClusters/clusterName (GET)

To retrieve a JSON object that includes details about a Job Cluster, issue a GET command to the Mantis REST API endpoint /api/v1/jobClusters/clusterName.

Query Parameters
Query Parameter Purpose
fields (optional) By default this endpoint will return all of the fields in the payload. You can set fields to a comma-delimited series of payload fields, in which case this endpoint will return only those fields of the payload.
Example Response Format
{
  "name": "jschmoe_validation1",
  "jars": [
    {
      "url": "https://mantis.us-east-1.prod.netflix.net/mantis-artifacts/mantis-examples-sine-function-0.2.9.zip",
      "uploadedAt": 1553040262171,
      "version": "0.2.9 2019-03-19 17:01:36",
      "schedulingInfo": {
        "stages": {
          "1": {
            "numberOfInstances": 1,
            "machineDefinition": {
              "cpuCores": 1,
              "memoryMB": 1024,
              "networkMbps": 128,
              "diskMB": 1024,
              "numPorts": 1
            },
            "hardConstraints": [],
            "softConstraints": [],
            "scalingPolicy": null,
            "scalable": false
          }
        }
      }
    }
  ],
  "sla": {
    "min": 0,
    "max": 0,
    "cronSpec": null,
    "cronPolicy": null
  },
  "parameters": [],
  "owner": {
    "name": "Joe Schmoe",
    "teamName": "",
    "description": "",
    "contactEmail": "jschmoe@netflix.com",
    "repo": ""
  },
  "lastJobCount": 0,
  "disabled": false,
  "isReadyForJobMaster": false,
  "migrationConfig": {
    "strategy": "PERCENTAGE",
    "configString": "{\"percentToMove\":25,\"intervalMs\":60000}"
  },
  "labels": [
    {
      "name": "_mantis.user",
      "value": "jschmoe"
    },
    {
      "name": "_mantis.ownerEmail",
      "value": "jschmoe@netflix.com"
    },
    {
      "name": "_mantis.artifact",
      "value": "mantis-examples-sine-function"
    },
    {
      "name": "_mantis.artifact.version",
      "value": "0.2.9"
    }
  ],
  "cronActive": false,
  "latestVersion": "0.2.9 2019-03-19 17:01:36"
}
Possible Response Codes
Response Code Reason
200 normal response
404 no cluster with that cluster name was found
405 incorrect HTTP verb (use GET instead)
500 unknown server error

Change Information about a Cluster

  • /api/v1/jobClusters/clusterName (PUT)

To update an existing Job Cluster, send a PUT command to the Mantis REST API endpoint /api/v1/jobClusters/clusterName with the same sort of body described above in the case of a Job Cluster create operation. Increment the version number so as to differentiate your new Cluster from the previous Job artifacts. If you try to update an existing Job Cluster by reusing the version number of an existing one, the operation will fail.

Example Request Body
{
  "jobDefinition": {
    "name": "Validation_jschmoe",
    "user": "validator",
    "jobJarFileLocation": "https://some.host/mantis-artifacts/mantis-examples-sine-function-0.2.9.zip",
    "parameters": [
      {
        "name": "useRandom",
        "value": false
      }
    ],
    "schedulingInfo": {
      "stages": {
        "0": {
          "numberOfInstances": 1,
          "machineDefinition": {
            "cpuCores": 2,
            "memoryMB": 4096,
            "diskMB": 10,
            "numPorts": 1
          },
          "hardConstraints": null,
          "softConstraints": null,
          "scalable": false
        },
        "1": {
          "numberOfInstances": 1,
          "machineDefinition": {
            "cpuCores": 2,
            "memoryMB": 4096,
            "diskMB": 10,
            "numPorts": 1
          },
          "hardConstraints": null,
          "softConstraints": null,
          "scalable": false
        }
      }
    },
    "slaMin": 0,
    "slaMax": 0,
    "cronSpec": null,
    "cronPolicy": "KEEP_EXISTING",
    "migrationConfig": {
      "configString": "{\"percentToMove\":60, \"intervalMs\":30000}",
      "strategy": "PERCENTAGE"
    }
  },
  "owner": {
    "name": "validator",
    "teamName": "Mantis",
    "description": "integration validator",
    "contactEmail": "mantisteam@netflix.com"
  }
}
Example Response Format

sine-function Job cluster updated

Possible Response Codes
Response Code Reason
200 normal response
400 client failure
404 no existing cluster with that cluster name was found
405 incorrect HTTP verb (use PUT instead)
500 unknown server error

Delete a Cluster

  • /api/v1/jobClusters/clusterName (DELETE)

To permanently delete an existing Job Cluster, send a DELETE command to the Mantis REST API endpoint /api/v1/jobClusters/clusterName.

Query Parameters
Query Parameter Purpose
user (required) Must match the original user in the cluster payload.
Example Response Format

TBD

Possible Response Codes
Response Code Reason
202 normal response: asynchronous delete has been scheduled
405 incorrect HTTP verb (use DELETE instead)
500 unknown server error

Update a Cluster’s Artifacts

  • /api/v1/jobClusters/clusterName/actions/updateArtifact (POST)

You can make a “quick update” of an existing Job Cluster and also submit a new Job with the updated cluster artifacts. This lets you update the Job Cluster with minimal information, without having to specify the scheduling info, as long as at least one Job was previously submitted for this Job Cluster. Mantis copies the scheduling information, Job parameters, and so forth, from the last Job submitted.

To do this, send a POST command to the Mantis REST API endpoint /api/v1/jobClusters/clusterName/actions/updateArtifact with a body that matches the format of the following example:

Example Request Body
{
  "name": "ValidatorDemo",
  "version": "0.0.1 2019-02-06 11:30:49",
  "url": "mantis-artifacts/demo-0.0.1-dev201901231434.zip",
  "skipsubmit": false,
  "user": "jschmoe"
}
Example Response Format

sine-function Job cluster updated

Possible Response Codes
Response Code Reason
204 normal response
404 no cluster with the given cluster name was found
405 incorrect HTTP verb (use POST instead)
500 unknown server error

You will receive in the response the Job ID of the newly submitted Job (unless you set skipsubmit to true in the request body, in which case no such Job will be created).


Update a Cluster’s SLA

  • /api/v1/jobClusters/clusterName/actions/updateSla (POST)

To update the SLA of a Job Cluster without having to submit a new version, send a POST command to the Mantis REST API endpoint /api/v1/jobClusters/clusterName/actions/updateSla with a body that matches the format of the following example:

Example Request Body
{ 
  "user": "YourUserName",
  "name": "Foo",
  "min": 0,
  "max": 2,
  "cronspec": "5 * * * * ?",
  "cronpolicy": "KEEP_EXISTING",
  "forceenable": true
}

The fields of this body are as follows:

SLA Field Purpose
user (required) name of the user calling this endpoint
name (required) name of the Job Cluster
min minimum number of Jobs to keep running
max maximum number of Jobs to allow running simultaneously
cronspec cron specification, see below for format and examples
cronpolicy either KEEP_EXISTING or KEEP_NEW (see above for details)
forceenable either true or false; reenable the Job Cluster if it is in the disabled state

Note

While min, max, cronspec, cronpolicy, and forceenable are all optional fields, you should provide at minimum either cronspec or the combination of min & max.

The cron specification string is defined by Quartz CronTrigger. Here are some examples:

Examples of cronspec Values
example cronspec value resulting job trigger time
"0 0 12 * * ?" Fire at 12 p.m. (noon) every day.
"0 15 10 ? * *" Fire at 10:15 a.m. every day.
"0 15 10 * * ?" Fire at 10:15 a.m. every day.
"0 0-5 14 * * ?" Fire every minute starting at 2 p.m. and ending at 2:05 p.m., every day.

Scheduling information for Jobs launched by means of cron triggers is inherited from the scheduling information for the Job Cluster.

Warning

If a Job takes required parameters, the Job will not launch successfully if the Job Cluster does not establish defaults for those parameters. A Job launched by means of a cron trigger always uses these default parameters to launch the Job.

If you provide an invalid cron specification, this will disable the Job Cluster. To fix this, when you reformulate your cron specification, also set forceenable to "true" in the body that you send via POST to /api/v2/jobClusters/clusterName/actions/updateSla.

Example Response Format

sine-function SLA updated

Possible Response Codes
Response Code Reason
204 normal response
404 no cluster with the given cluster name was found
405 incorrect HTTP verb (use POST instead)
500 unknown server error
Example: Creating a Job Cluster with a cron Specification

The following POST body to /api/v2/jobClusters/clusterName/actions/updateSla would specify Jobs that are launched based on a timed schedule:

{
  "jobDefinition": {
    "name": "Foo",
    "user": "YourUserName",
    "version": "1.0",
    "parameters": [
      {
        "name": "param1",
        "value": "value1"
      },
      {
        "name": "param2",
        "value": "value2"
      }
    ],
    "schedulingInfo": {
      "stages": {
        "1": {
          "numberOfInstances": 1,
          "machineDefinition": {
            "cpuCores": 2,
            "memoryMB": 4096,
            "diskMB": 10
          },
          "hardConstraints": null,
          "softConstraints": null,
          "scalable": false
        }
      }
    },
    "slaMin": 0,
    "slaMax": 0,
    "cronSpec": "2 * * * * ?",
    "cronPolicy":"KEEP_EXISTING",
    "jobJarFileLocation": "http://www.jobjars.com/foo"
  },
  "owner": {
    "name": "MyName",
    "teamName": "myTeam",
    "description": "description",
    "contactEmail": "email@company.com",
    "repo": "http://repos.com/myproject.git"
  }
}

Update a Cluster’s Migration Strategy

  • /api/v1/jobClusters/clusterName/actions/updateMigrationStrategy (POST)

You can quickly update the migration strategy of an existing Job Cluster without having to update the entirety of the Cluster definition. To do this, send a POST command to the Mantis REST API endpoint /api/v1/jobClusters/clusterName/actions/updateMigrationStrategy with a body that matches the format of the following example:

Example Request Body
{
  "name": "NameOfJobCluster",
  "migrationConfig": {
    "strategy": "PERCENTAGE",
    "configString": "{\"percentToMove\":10, \"intervalMs\":1000}"
  },
  "user": "YourUserName"
}

You will receive in the response the migration strategy config that you have updated the Job Cluster to.

Example Response Format

sine-function worker migration config updated

Possible Response Codes
Response Code Reason
204 normal response
404 no cluster with the given cluster name was found
405 incorrect HTTP verb (use POST instead)
500 unknown server error

Update a Cluster’s Labels

  • /api/v1/jobClusters/clusterName/actions/updateLabel (POST)

You can quickly update the labels of an existing Job Cluster without having to update the entirety of the Cluster definition. To do this, send a POST command to the Mantis REST API endpoint /api/v1/jobClusters/clusterName/actions/updateLabel with a body that matches the format of the following example:

Example Request Body
{
  "name": "SPaaSBackpressureDemp",
  "labels": [
    {
      "name": "_mantis.user",
      "value": "jschmoe"
    },
    {
      "name": "_mantis.ownerEmail",
      "value": "jschmoe@netflix.com"
    },
    {
      "name": "_mantis.artifact",
      "value": "backpressure-demo-aggregator-0.0.1"
    },
    {
      "name": "_mantis.artifact.version",
      "value": "dev201901231434"
    },
    {
      "name": "_mantis.jobType",
      "value": "aggregator"
    },
    {
      "name": "_mantis.criticality",
      "value": "medium"
    },
    {
      "name": "myTestLabel",
      "value": "bingo"
    }
  ],
  "user": "jschmoe"
}
Example Response Format

sine-function labels updated

Possible Response Codes
Response Code Reason
204 normal response
404 no cluster with the given cluster name was found
405 incorrect HTTP verb (use POST instead)
500 unknown server error

Enable a Cluster

  • /api/v1/jobClusters/clusterName/actions/enableCluster (POST)

You can quickly change the state of an existing Job Cluster to enabled=true without having to update the entirety of the Cluster definition.

To do this, send a POST command to the Mantis REST API endpoint /api/v1/jobClusters/clusterName/actions/enableCluster with a body that matches the format of the following example:

Example Request Body
{
  "name": "SPaaSBackpressureDemp",
  "user": "jschmoe"
}
Example Response Format

sine-function enabled

Possible Response Codes
Response Code Reason
204 normal response
404 no cluster with the given cluster name was found
405 incorrect HTTP verb (use POST instead)
500 unknown server error

Disable a Cluster

  • /api/v1/jobClusters/clusterName/actions/disableCluster (POST)

You can quickly change the state of an existing Job Cluster to enabled=false without having to update the entirety of the Cluster definition.

When you disable a Job Cluster Mantis will not allow new Job submissions under that Cluster and it will terminate any Jobs from that Cluster that are currently running. Mantis will also stop enforcing the SLA requirements for the Cluster, including any cron setup that would otherwise launch new Jobs.

This is useful when a Job Cluster must be temporarily made inactive, for instance if you have determined that there is a problem with it.

To do this, send a POST command to the Mantis REST API endpoint /api/v1/jobClusters/clusterName/actions/disableCluster with a body that matches the format of the following example:

Example Request Body
{
  "name": "SPaaSBackpressureDemp",
  "user": "jschmoe"
}
Example Response Format

sine-function disabled

Possible Response Codes
Response Code Reason
204 normal response
404 no cluster with the given cluster name was found
405 incorrect HTTP verb (use POST instead)
500 unknown server error

Get a Map of Mantis Publish Push-Based Streams to Clusters

  • /api/v1/mantis/publish/streamJobClusterMap (GET)

describe

Example Response Format
{
  "version": "1",
  "timestamp": 2,
  "mappings": {
    "__default__": {
      "requestEventStream": "SharedMantisPublishEventSource",
      "__default__": "SharedMantisPublishEventSource"
    }
  }
}
Possible Response Codes
Response Code Reason
200 normal response
405 incorrect HTTP verb (use GET instead)
500 unknown server error

Job Tasks

TBD

Get a List of Jobs

  • /api/v1/jobs (GET)

To retrieve a JSON array of IDs of the active Jobs, issue a GET command to the Mantis REST API endpoint /api/v1/jobs.

Query Parameters
Query Parameter Purpose
ascending (optional) You can use this to indicate whether or not to sort the records in ascending order (true
compact (optional) Ask the server to return compact responses (true
fields (optional) By default this endpoint will return all of the fields in the payload. You can set fields to a comma-delimited series of payload fields, in which case this endpoint will return only those fields in the response.
limit (optional) The maximum record size to return (default = no limit).
offset (optional) The record number to begin with in the set of records to return in this request (use this with pageSize to get records by the page). See Pagination for more details.
pageSize (optional) The maximum number of records to return in this request (default = 0, which means all records). See Pagination for more details.
sortBy (optional) You can set this to the name of any payload field whose values are Comparable and this endpoint will return its results sorted by that field.

There is also a series of query parameters that you can use to set server-side filters that will restrict the jobs represented in the resulting list of jobs to only those jobs that match the filters:

Query Parameter What It Filters
activeOnly (optional) The activeOnly field (boolean). By default, this is true.
jobState (optional) Job state, Active or Terminal. By default, this endpoint filters on jobState=Active. This query parameter has precedence over the activeOnly parameter.
labels (optional) Labels in the labels array. You can express this by setting this parameter to a comma-delimited list of label strings.
labels.op (optional) Use this parameter to tell the server whether to treat the list of labels you have provided as an or (default: a job that contains any of the labels will be returned in the list), or an and (only jobs that contain all of the labels will be returned). Set this to or or and.
matching (optional) The cluster name. Set this to a regex string. You can also use the /api/v1/jobClusters/clusterName/jobs endpoint if you mean to match a specific cluster name and do not need the flexibility of a regex filter.
stageNumber (optional) Stage number (integer). This filters the list to contain only those jobs corresponding to workers that are relevant to the specified stage.
workerIndex (optional) The workerIndex field (integer).
workerNumber (optional) The workerNumber field (integer).
workerState (optional) The workerState field (Noop, Active (default), or Terminal)

describe

Example Response Format
{
        "list": [
            {
                "jobMetadata": {
                    "jobId": "sine-test-4",
                    "name": "sine-test",
                    "user": "someuser",
                    "submittedAt": 1574188324276,
                    "startedAt": 1574188354708,
                    "jarUrl": "http://mantis-examples-sine-function-0.2.9.zip",
                    "numStages": 1,
                    "sla": {
                        "runtimeLimitSecs": 0,
                        "minRuntimeSecs": 0,
                        "slaType": "Lossy",
                        "durationType": "Perpetual",
                        "userProvidedType": ""
                    },
                    "state": "Launched",
                    "subscriptionTimeoutSecs": 0,
                    "parameters": [
                        {
                            "name": "useRandom",
                            "value": "True"
                        }
                    ],
                    "nextWorkerNumberToUse": 40,
                    "migrationConfig": {
                        "strategy": "PERCENTAGE",
                        "configString": "{\"percentToMove\":25,\"intervalMs\":60000}"
                    },
                    "labels": [
                        {
                            "name": "_mantis.user",
                            "value": "zxu"
                        },
                        {
                            "name": "_mantis.ownerEmail",
                            "value": "zxu@netflix.com"
                        },
                        {
                            "name": "_mantis.artifact.version",
                            "value": "0.2.9"
                        },
                        {
                            "name": "_mantis.artifact",
                            "value": "mantis-examples-sine-function-0.2.9.zip"
                        },
                        {
                            "name": "_mantis.version",
                            "value": "0.2.9 2019-03-19 17:01:36"
                        }
                    ]
                },
                "stageMetadataList": [
                    {
                        "jobId": "sine-test-4",
                        "stageNum": 1,
                        "numStages": 1,
                        "machineDefinition": {
                            "cpuCores": 1.0,
                            "memoryMB": 1024.0,
                            "networkMbps": 128.0,
                            "diskMB": 1024.0,
                            "numPorts": 1
                        },
                        "numWorkers": 1,
                        "hardConstraints": [],
                        "softConstraints": [],
                        "scalingPolicy": null,
                        "scalable": false
                    }
                ],
                "workerMetadataList": [
                    {
                        "workerIndex": 0,
                        "workerNumber": 31,
                        "jobId": "sine-test-4",
                        "stageNum": 1,
                        "numberOfPorts": 5,
                        "metricsPort": 7150,
                        "consolePort": 7152,
                        "debugPort": 7151,
                        "customPort": 7153,
                        "ports": [
                            7154
                        ],
                        "state": "Started",
                        "slave": "100.82.168.140",
                        "slaveID": "f39108b0-da43-45df-8b12-c132d85de7c0-S1",
                        "cluster": "mantisagent-staging-m5.2xlarge-1",
                        "acceptedAt": 1575675900626,
                        "launchedAt": 1575675996506,
                        "startingAt": 1575676025493,
                        "startedAt": 1575676026661,
                        "completedAt": -1,
                        "reason": "Normal",
                        "resubmitOf": 22,
                        "totalResubmitCount": 4
                    }
                ],
                "version": null
            }
        ],
        "prev": null,
        "next": null,
        "total": 1
    }
Possible Response Codes
Response Code Reason
200 normal response
405 incorrect HTTP verb (use GET instead)
500 unknown server error

Get Information About a Particular Job

  • /api/v1/jobs/jobID (GET)
  • /api/v1/jobClusters/clusterName/jobs/jobID (GET)

To retrieve a JSON record of a particular Job, issue a GET command to the Mantis REST API endpoint /api/v1/jobs/jobID or /api/v1/jobClusters/clusterName/jobs/jobID.

Query Parameters
Query Parameter Purpose
fields (optional) By default this endpoint will return all of the fields in the payload. You can set fields to a comma-delimited series of payload fields, in which case this endpoint will return only those fields in the response.
archived (optional) By default only information about an active job will be returned. Set this to true if you want information about the job returned even if it is an archived inactive job.

describe

Example Response Format
{
            "jobMetadata": {
                "jobId": "sine-function-7531",
                "name": "sine-function",
                "user": "someuser",
                "submittedAt": 1576002266997,
                "startedAt": 0,
                "jarUrl": "http://mantis-examples-sine-function-0.2.9.zip",
                "numStages": 2,
                "sla": {
                    "runtimeLimitSecs": 0,
                    "minRuntimeSecs": 0,
                    "slaType": "Lossy",
                    "durationType": "Perpetual",
                    "userProvidedType": ""
                },
                "state": "Accepted",
                "subscriptionTimeoutSecs": 0,
                "parameters": [
                    {
                        "name": "useRandom",
                        "value": "False"
                    }
                ],
                "nextWorkerNumberToUse": 10,
                "migrationConfig": {
                    "strategy": "PERCENTAGE",
                    "configString": "{\"percentToMove\":25,\"intervalMs\":60000}"
                },
                "labels": [
                    {
                        "name": "_mantis.artifact",
                        "value": "mantis-examples-sine-function-0.2.9.zip"
                    },
                    {
                        "name": "_mantis.version",
                        "value": "0.2.9 2018-04-23 13:22:02"
                    }
                ]
            },
            "stageMetadataList": [
                {
                    "jobId": "sine-function-7531",
                    "stageNum": 0,
                    "numStages": 2,
                    "machineDefinition": {
                        "cpuCores": 2.0,
                        "memoryMB": 4096.0,
                        "networkMbps": 128.0,
                        "diskMB": 1024.0,
                        "numPorts": 1
                    },
                    "numWorkers": 1,
                    "hardConstraints": [],
                    "softConstraints": [],
                    "scalingPolicy": null,
                    "scalable": false
                },
                {
                    "jobId": "sine-function-7531",
                    "stageNum": 1,
                    "numStages": 2,
                    "machineDefinition": {
                        "cpuCores": 1.0,
                        "memoryMB": 1024.0,
                        "networkMbps": 128.0,
                        "diskMB": 1024.0,
                        "numPorts": 1
                    },
                    "numWorkers": 1,
                    "hardConstraints": [],
                    "softConstraints": [],
                    "scalingPolicy": null,
                    "scalable": false
                }
            ],
            "workerMetadataList": [
                {
                    "workerIndex": 0,
                    "workerNumber": 1,
                    "jobId": "sine-function-7531",
                    "stageNum": 0,
                    "numberOfPorts": 5,
                    "metricsPort": -1,
                    "consolePort": -1,
                    "debugPort": -1,
                    "customPort": -1,
                    "ports": [],
                    "state": "Accepted",
                    "slave": null,
                    "slaveID": null,
                    "cluster": null,
                    "acceptedAt": 1576002267005,
                    "launchedAt": -1,
                    "startingAt": -1,
                    "startedAt": -1,
                    "completedAt": -1,
                    "reason": "Normal",
                    "resubmitOf": 0,
                    "totalResubmitCount": 0
                },
                {
                    "workerIndex": 0,
                    "workerNumber": 2,
                    "jobId": "sine-function-7531",
                    "stageNum": 1,
                    "numberOfPorts": 5,
                    "metricsPort": -1,
                    "consolePort": -1,
                    "debugPort": -1,
                    "customPort": -1,
                    "ports": [],
                    "state": "Accepted",
                    "slave": null,
                    "slaveID": null,
                    "cluster": null,
                    "acceptedAt": 1576002267007,
                    "launchedAt": -1,
                    "startingAt": -1,
                    "startedAt": -1,
                    "completedAt": -1,
                    "reason": "Normal",
                    "resubmitOf": 0,
                    "totalResubmitCount": 0
                }
            ],
            "version": "0.2.9 2018-04-23 13:22:02"
        }
Possible Response Codes
Response Code Reason
200 normal response
404 no job with that ID was found
405 incorrect HTTP verb (use GET instead)
500 unknown server error

Kill a Job

  • /api/v1/jobs/jobID (DELETE)

To permanently kill a particular Job, issue a DELETE command to the Mantis REST API endpoint endpoint /api/v1/jobs/jobID.

Query Parameters
Query Parameter Purpose
reason (required) Specify why you are killing this job.
user (required) Specify which user is initiating this request.
Example Response Format

empty

No response

Possible Response Codes
Response Code Reason
202 the kill request has been accepted and is being processed asynchronously
404 no job with that ID was found
405 incorrect HTTP verb (use DELETE instead)
500 unknown server error

List the Archived Workers for a Job

  • /api/v1/jobs/jobID/archivedWorkers (GET)

To list all of the archived workers for a particular Job, issue a GET command to the Mantis REST API endpoint endpoint /api/v1/jobs/jobID/archivedWorkers.

Query Parameters
Query Parameter Purpose
ascending (optional) You can use this to indicate whether or not to sort the records in ascending order (true
fields (optional) By default this endpoint will return all of the fields in the payload. You can set fields to a comma-delimited series of payload fields, in which case this endpoint will return only those fields in the response.
limit (optional) The maximum record size to return (default = no limit).
offset (optional) The record number to begin with in the set of records to return in this request (use this with pageSize to get records by the page). See Pagination for more details.
pageSize (optional) The maximum number of records to return in this request (default = 0, which means all records). See Pagination for more details.
sortBy (optional) You can set this to the name of any payload field whose values are Comparable and this endpoint will return its results sorted by that field.

describe

Example Response Format
{
        "list": [
            {
                "workerIndex": 0,
                "workerNumber": 2,
                "jobId": "sine-function-7532",
                "stageNum": 1,
                "numberOfPorts": 5,
                "metricsPort": 7155,
                "consolePort": 7157,
                "debugPort": 7156,
                "customPort": 7158,
                "ports": [
                    7159
                ],
                "state": "Failed",
                "slave": "100.85.130.224",
                "slaveID": "079f4fa6-f910-4247-b5d0-f5574f36cace-S5274",
                "cluster": "mantisagent-main-m5.2xlarge-1",
                "acceptedAt": 1576003739758,
                "launchedAt": 1576003739861,
                "startingAt": 1576003748544,
                "startedAt": 1576003750069,
                "completedAt": 1576003959366,
                "reason": "Relaunched",
                "resubmitOf": 0,
                "totalResubmitCount": 0
            }
        ],
        "prev": null,
        "next": null,
        "total": 1
    }
Possible Response Codes
Response Code Reason
200 normal response
404 no job with that ID was found
405 incorrect HTTP verb (use GET instead)
500 unknown server error

Get a List of Jobs for a Particular Cluster

  • /api/v1/jobClusters/clusterName/jobs (GET)

To retrieve a JSON array of IDs of the active Jobs in a particular cluster, issue a GET command to the Mantis REST API endpoint /api/v1/jobClusters/clusterName/jobs.

Query Parameters
Query Parameter Purpose
ascending (optional) You can use this to indicate whether or not to sort the records in ascending order (true
compact (optional) Ask the server to return compact responses (true
fields (optional) By default this endpoint will return all of the fields in the payload. You can set fields to a comma-delimited series of payload fields, in which case this endpoint will return only those fields in the response.
limit (optional) The maximum record size to return (default = no limit).
offset (optional) The record number to begin with in the set of records to return in this request (use this with pageSize to get records by the page). See Pagination for more details.
pageSize (optional) The maximum number of records to return in this request (default = 0, which means all records). See Pagination for more details.
sortBy (optional) You can set this to the name of any payload field whose values are Comparable and this endpoint will return its results sorted by that field.

There is also a series of query parameters that you can use to set server-side filters that will restrict the jobs represented in the resulting list of jobs to only those jobs that match the filters:

Query Parameter What It Filters
activeOnly (optional) The activeOnly field (boolean). By default, this is true.
jobState (optional) Job state, Active or Terminal. By default, this endpoint filters on jobState=Active. This query parameter has precedence over the activeOnly parameter.
labels (optional) Labels in the labels array. You can express this by setting this parameter to a comma-delimited list of label strings.
labels.op (optional) Use this parameter to tell the server whether to treat the list of labels you have provided as an or (default: a job that contains any of the labels will be returned in the list), or an and (only jobs that contain all of the labels will be returned). Set this to or or and.
stageNumber (optional) Stage number (integer). This filters the list to contain only those jobs corresponding to workers that are relevant to the specified stage.
workerIndex (optional) The workerIndex field (integer).
workerNumber (optional) The workerNumber field (integer).
workerState (optional) The workerState field (Noop, Active (default), or Terminal)

describe

Example Response Format
{
        "list": [
            {
                "jobMetadata": {
                    "jobId": "sine-function-7532",
                    "name": "sine-function",
                    "user": "someuser",
                    "submittedAt": 1576003739750,
                    "startedAt": 1576003750076,
                    "jarUrl": "http://mantis-examples-sine-function-0.2.9.zip",
                    "numStages": 2,
                    "sla": {
                        "runtimeLimitSecs": 0,
                        "minRuntimeSecs": 0,
                        "slaType": "Lossy",
                        "durationType": "Perpetual",
                        "userProvidedType": ""
                    },
                    "state": "Launched",
                    "subscriptionTimeoutSecs": 0,
                    "parameters": [
                        {
                            "name": "useRandom",
                            "value": "False"
                        }
                    ],
                    "nextWorkerNumberToUse": 10,
                    "migrationConfig": {
                        "strategy": "PERCENTAGE",
                        "configString": "{\"percentToMove\":25,\"intervalMs\":60000}"
                    },
                    "labels": [
                        {
                            "name": "_mantis.isResubmit",
                            "value": "true"
                        },
                        {
                            "name": "_mantis.artifact",
                            "value": "mantis-examples-sine-function-0.2.9.zip"
                        },
                        {
                            "name": "_mantis.version",
                            "value": "0.2.9 2018-04-23 13:22:02"
                        }
                    ]
                },
                "stageMetadataList": [
                    {
                        "jobId": "sine-function-7532",
                        "stageNum": 0,
                        "numStages": 2,
                        "machineDefinition": {
                            "cpuCores": 2.0,
                            "memoryMB": 4096.0,
                            "networkMbps": 128.0,
                            "diskMB": 1024.0,
                            "numPorts": 1
                        },
                        "numWorkers": 1,
                        "hardConstraints": [],
                        "softConstraints": [],
                        "scalingPolicy": null,
                        "scalable": false
                    },
                    {
                        "jobId": "sine-function-7532",
                        "stageNum": 1,
                        "numStages": 2,
                        "machineDefinition": {
                            "cpuCores": 1.0,
                            "memoryMB": 1024.0,
                            "networkMbps": 128.0,
                            "diskMB": 1024.0,
                            "numPorts": 1
                        },
                        "numWorkers": 1,
                        "hardConstraints": [],
                        "softConstraints": [],
                        "scalingPolicy": null,
                        "scalable": false
                    }
                ],
                "workerMetadataList": [
                    {
                        "workerIndex": 0,
                        "workerNumber": 1,
                        "jobId": "sine-function-7532",
                        "stageNum": 0,
                        "numberOfPorts": 5,
                        "metricsPort": 7150,
                        "consolePort": 7152,
                        "debugPort": 7151,
                        "customPort": 7153,
                        "ports": [
                            7154
                        ],
                        "state": "Started",
                        "slave": "100.85.130.224",
                        "slaveID": "079f4fa6-f910-4247-b5d0-f5574f36cace-S5274",
                        "cluster": "mantisagent-main-m5.2xlarge-1",
                        "acceptedAt": 1576003739756,
                        "launchedAt": 1576003739861,
                        "startingAt": 1576003748558,
                        "startedAt": 1576003749967,
                        "completedAt": -1,
                        "reason": "Normal",
                        "resubmitOf": 0,
                        "totalResubmitCount": 0
                    },
                    {
                        "workerIndex": 0,
                        "workerNumber": 3,
                        "jobId": "sine-function-7532",
                        "stageNum": 1,
                        "numberOfPorts": 5,
                        "metricsPort": 7165,
                        "consolePort": 7167,
                        "debugPort": 7166,
                        "customPort": 7168,
                        "ports": [
                            7169
                        ],
                        "state": "Started",
                        "slave": "100.85.130.224",
                        "slaveID": "079f4fa6-f910-4247-b5d0-f5574f36cace-S5274",
                        "cluster": "mantisagent-main-m5.2xlarge-1",
                        "acceptedAt": 1576003959366,
                        "launchedAt": 1576003959407,
                        "startingAt": 1576003961542,
                        "startedAt": 1576003962822,
                        "completedAt": -1,
                        "reason": "Normal",
                        "resubmitOf": 2,
                        "totalResubmitCount": 1
                    }
                ],
                "version": "0.2.9 2018-04-23 13:22:02"
            }
        ],
        "prev": null,
        "next": null,
        "total": 1
    }
Possible Response Codes
Response Code Reason
200 normal response
404 no cluster with the given cluster name was found
405 incorrect HTTP verb (use GET instead)
500 unknown server error

Submit a New Job for a Particular Cluster

  • /api/v1/jobClusters/clusterName/jobs (POST)

To submit a new Job based on a Job Cluster, issue a POST command to the /api/v1/jobClusters/clusterName/jobs endpoint with a request body like the following:

Example Request Body
{
  "name": "myClusterName",
  "user": "jschmoe",
  "jobJarFileLocation": null,
  "version": "0.0.1 2019-02-06 13:30:07",
  "subscriptionTimeoutSecs": 0,
  "jobSla": {
    "runtimeLimitSecs": "0",
    "slaType": "Lossy",
    "durationType": "Perpetual",
    "userProvidedType": ""
  },
  "schedulingInfo": {
    "stages": {
      "0": {
        "numberOfInstances": 1,
        "machineDefinition": {
          "cpuCores": 0.35,
          "memoryMB": 600,
          "networkMbps": 30,
          "diskMB": 100,
          "numPorts": 1
        },
        "hardConstraints": null,
        "softConstraints": null,
        "scalable": false
      },
      "1": {
        "numberOfInstances": 1,
        "machineDefinition": {
          "cpuCores": 0.35,
          "memoryMB": 600,
          "networkMbps": 30,
          "diskMB": 100,
          "numPorts": 1
        },
        "hardConstraints": null,
        "softConstraints": null,
        "scalable": true
      }
    }
  },
  "parameters": [
    {
      "name": "criterion",
      "value": "mock"
    },
    {
      "name": "sourceJobName",
      "value": "RequestSource"
    },
    {
      "name": "spaasJobId",
      "value": "spaasjschmoe-clsessionizer_backpressuretest"
    }
  ],
  "isReadyForJobMaster": false
}
Example Response Format

(Same as "Get Information about a Job" below) (Same as "Get Information about a Job" above)

Possible Response Codes
Response Code Reason
201 normal response
404 no cluster with the given cluster name was found
405 incorrect HTTP verb (use POST instead)
500 unknown server error

Update a Job Cluster and Submit a New Job at the Same Time

  • /api/v1/jobs/actions/quickSubmit (POST)

You can make a “quick update” of an existing Job Cluster and also submit a new Job with the updated cluster artifacts. This lets you update the Job Cluster with minimal information, without having to specify the scheduling info, as long as at least one Job was previously submitted for this Job Cluster.

To do this, send a POST command to the Mantis REST API endpoint /api/v1/jobs/actions/quickSubmit with a body that matches the format of the following example:

Example Request Body
{
  "name": "NameOfJobCluster",
  "user": "myusername",
  "jobSla": {
    "durationType": "Perpetual",
    "runtimeLimitSecs": "0",
    "minRuntimeSecs": "0",
    "userProvidedType": ""
  }
}
Example Response Format

You will receive in the response the Job ID of the newly submitted Job. E.g sine-test-5 sample response body?

Possible Response Codes
Response Code Reason
201 normal response
404 no cluster was found with a cluster name matching the value of name from the request body
405 incorrect HTTP verb (use POST instead)
500 unknown server error

Post Job Heartbeat Status

  • /api/v1/jobs/actions/postJobStatus (POST)
Query Parameters

TBD

Example Request Body
{
  "jobId": "sine-function-1",
  "status": {
    "jobId": "sine-function-1",
    "stageNum": 1,
    "workerIndex": 0,
    "workerNumber": 2,
    "type": "HEARTBEAT",
    "message": "heartbeat",
    "state": "Noop",
    "hostname": null,
    "timestamp": 1525813363585,
    "reason": "Normal",
    "payloads": [
      {
        "type": "SubscriptionState",
        "data": "false"
      },
      {
        "type": "IncomingDataDrop",
        "data": "{\"onNextCount\":0,\"droppedCount\":0}"
      }
    ]
  }
}
Example Response Format

TBD

Possible Response Codes
Response Code Reason
204 normal response
405 incorrect HTTP verb (use POST instead)
500 unknown server error

Horizontally Scale a Stage

  • /api/v1/jobs/jobID/actions/scaleStage (POST)

To manually scale a Job Processing Stage, that is, to alter the number of workers assigned to that stage, send a POST command to the Mantis REST API endpoint /api/v1/jobs/jobID/actions/scaleStage with a request body in the following format:

Note

You can only manually scale a Processing Stage if the Job was submitted with the scalable flag turned on.

Example Request Body
{
  "JobId": "ValidatorDemo-33",
  "StageNumber": 1,
  "NumWorkers": 3
}

NumWorkers here is the number of workers you want to be assigned to the stage after the scaling action takes place (that is, it is not the delta by which you want to change the number of workers in the stage).

Example Response Format

TBD

Possible Response Codes
Response Code Reason
204 normal response
404 no Job with that Job ID was found
405 incorrect HTTP verb (use POST instead)
500 unknown server error

Resubmit a Worker

  • /api/v1/jobs/jobID/actions/resubmitWorker (POST)

To resubmit a particular worker for a particular Job, send a POST command to the Mantis REST API endpoint /api/v1/jobs/jobID/actions/resubmitWorker with a request body resembling the following:

Example Request Body
{
  "user": "jschmoe",
  "workerNumber": 5,
  "reason": "test worker resubmit"
}

Note

workerNumber is the worker number not the worker index.

Example Response Format

TBD

Possible Response Codes
Response Code Reason
200 normal response
404 no Job with that Job ID was found
405 incorrect HTTP verb (use POST instead)
500 unknown server error

Administrative Tasks

TBD

Return Job Master Information

  • /api/v1/masterInfo (GET)

TBD

Example Response Body
{
  "hostname": "100.86.121.198",
  "hostIP": "100.86.121.198",
  "apiPort": 7101,
  "schedInfoPort": 7101,
  "apiPortV2": 7075,
  "apiStatusUri": "api/v1/jobs/actions/postJobStatus",
  "consolePort": 7101,
  "createTime": 1548803881867,
  "fullApiStatusUri": "http://100.86.121.198:7101/api/v1/jobs/actions/postJobStatus"
}
Possible Response Codes
Response Code Reason
200 normal response
405 incorrect HTTP verb (use GET instead)
500 unknown server error

Return Job Master Configs

  • /api/v1/masterConfigs (GET)

TBD

Example Response Body
[
  {
    "name": "JobConstraints",
    "value": "[\"UniqueHost\",\"ExclusiveHost\",\"ZoneBalance\",\"M4Cluster\",\"M3Cluster\",\"M5Cluster\"]"
  },
  {
    "name": "ScalingReason",
    "value": "[\"CPU\",\"Memory\",\"Network\",\"DataDrop\",\"KafkaLag\",\"UserDefined\",\"KafkaProcessed\"]"
  },
  {
    "name": "MigrationStrategyEnum",
    "value": "[\"ONE_WORKER\",\"PERCENTAGE\"]"
  },
  {
    "name": "WorkerResourceLimits",
    "value": "{\"maxCpuCores\":8,\"maxMemoryMB\":28000,\"maxNetworkMbps\":1024}"
  }
]
Possible Response Codes
Response Code Reason
200 normal response
405 incorrect HTTP verb (use GET instead)
500 unknown server error

Get Information about Agent Clusters

  • /api/v1/agentClusters/ (GET)

Returns information about active agent clusters (agent clusters are physical AWS resources that Mantis connects to).

Example Response Body

response body?

Possible Response Codes
Response Code Reason
200 normal response
405 incorrect HTTP verb (use GET instead)
500 unknown server error

Activate or Deactivate an Agent Cluster

  • /api/v1/agentClusters/ (POST)

TBD

Example Request Body
["mantisagent-staging-cl1-m5.2xlarge-1-v00"]

(an array of active clusters)

Example Response Body

response body?

Possible Response Codes
Response Code Reason
200 normal response
400 client failure
405 incorrect HTTP verb (use POST instead)
500 unknown server error

Retrieve the Agent Cluster Scaling Policy

  • /api/v1/agentClusters/autoScalePolicy (GET)

TBD

Example Response Body

response body?

Possible Response Codes
Response Code Reason
200 normal response
405 incorrect HTTP verb (use GET instead)
500 unknown server error

Get Jobs and Host Information for an Agent Cluster

  • /api/v1/agentClusters/jobs (GET)

TBD

Example Response Body

response body?

Possible Response Codes
Response Code Reason
200 normal response
405 incorrect HTTP verb (use GET instead)
500 unknown server error

Streaming WebSocket/SSE Tasks

TBD: introduction

Stream Job Status Changes

  • ws://masterHost:7101/api/v1/jobStatusStream/jobID

TBD: description

See also: mantisapi/websocket/

Example Response Stream Excerpt
{
  "status": {
    "jobId": "SPaaSBackpressureDemp-26",
    "stageNum": 1,
    "workerIndex": 0,
    "workerNumber": 7,
    "type": "INFO",
    "message": "SPaaSBackpressureDemp-26-worker-0-7 worker status update",
    "state": "StartInitiated",
    "hostname": null,
    "timestamp": 1549404217065,
    "reason": "Normal",
    "payloads": []
  }
}

Stream Scheduling Information for a Job

  • /api/v1/jobDiscoveryStream/jobID (GET)
  • /api/v1/jobs/schedulingInfo/jobID (GET)

To retrieve an SSE stream of scheduling information for a particular job, send an HTTP GET command to either the Mantis REST API endpoint /api/v1/jobDiscoveryStream/jobID or /api/v1/jobs/schedulingInfo/jobID.

Query Parameters
jobDiscoveryStream Query Parameter Purpose
sendHB (optional) Indicate whether or not to send heartbeats (default=false).
jobs/schedulingInfo Query Parameter Purpose
jobId (required) The job ID of the job for which scheduling information is to be streamed.
Example Response Stream Excerpt

response body?

Possible Response Codes
Response Code Reason
200 normal response
404 no Job with that Job ID was found
405 incorrect HTTP verb (use GET instead)
500 unknown server error

Get Streaming (SSE) Discovery Info for a Cluster

  • /api/v1/jobClusters/discoveryInfoStream/clusterName (GET)

describe

Example Response Format

TBD

Possible Response Codes
Response Code Reason
200 normal response
405 incorrect HTTP verb (use GET instead)
500 unknown server error

Stream Job Information for a Cluster

  • /api/v1/lastSubmittedJobIdStream/clusterName (GET)

To retrieve an SSE stream of job information for a particular cluster, send an HTTP GET command to the Mantis REST API endpoint /api/v1/lastSubmittedJobIdStream/clusterName.

Query Parameters
Query Parameter Purpose
sendHB Indicate whether or not to send heartbeats.
Example Response Stream Excerpt

response body?

Possible Response Codes
Response Code Reason
200 normal response
404 no Cluster with that Cluster name was found
405 incorrect HTTP verb (use GET instead)
500 unknown server error

Stream Job Sink Messages

  • /api/v1/jobConnectbyid/jobID (SSE)
  • /api/v1/jobConnectbyname/jobName (SSE)

Collect messages from the job sinks and merge them into a single websocket or SSE stream.

Example Response Stream Excerpt
data: {"x": 928400.000000, "y": 3.139934}
data: {"x": 928402.000000, "y": -9.939772}
data: {"x": 928404.000000, "y": 5.132876}
data: {"x": 928406.000000, "y": 5.667712}

Submit Job and Stream Job Sink Messages

  • /api/v1/jobsubmitandconnect (POST)

To submit a job and then collect messages from the job sinks and merge them into a single websocket or SSE stream, send a POST request to /api/v1/jobsubmitandconnect with a request body that describes the job.

Example Request Body
{
  "name": "ValidatorDemo",
  "user": "jschmoe",
  "jobSla": {
    "durationType": "Perpetual",
    "runtimeLimitSecs": "0",
    "minRuntimeSecs": "0",
    "userProvidedType": ""
  }
}
Example Response Stream Excerpt
data: {"x": 928400.000000, "y": 3.139934}
data: {"x": 928402.000000, "y": -9.939772}
data: {"x": 928404.000000, "y": 5.132876}
data: {"x": 928406.000000, "y": 5.667712}

Pagination

You can configure some endpoints to return their responses in pages. This is to say that rather than returning all of the data responsive to a request all at once, the endpoint can return a specific subset of the data at a time.

An endpoint that supports pagination will typically do so by means of two query parameters:

Query Parameter Purpose
pageSize the maximum number of records to return in this request (default = 0, which means all records)
offset the record number to begin with in the set of records to return in this request

So, for example, you might make consecutive requests for…

  1. endpoint?pageSize=10&offset=0
  2. endpoint?pageSize=10&offset=10
  3. endpoint?pageSize=10&offset=20

…and so forth, until you reach the final page of records.

When you request records in a paginated fashion like this, the Mantis API will enclose them in a JSON structure like the following:

{ "list": [ { "Id": originalOffset, ⋮ }, { "Id": originalOffset+1, ⋮ }, ⋮ ], "prev": "/api/v1/endpoint?pageSize=pageSize&offset=originalOffset+pageSize", "next": "/api/v1/endpoint?pageSize=pageSize&offset=originalOffset−pageSize" }

For example:

{
  "list": [
    {
      "Id": 101,
      
    },
    {
      "Id": 102,
      
    }
  ],
  "next": "/api/v1/someResource?pageSize=20&offset=120",
  "prev": "/api/v1/someResource?pageSize=20&offset=80"
}

prev and/or next will be null if there is no previous or next page, that is, if you are at the first and/or last page in the pagination.


WebSocket

Some desktops have trouble dealing with SSE. In such a case you can use WebSocket to connect to a Job (other API features are only available via the Mantis REST API).

The WebSocket API runs from the same servers as the Mantis REST API, and you can reach it by using the ws:// protocol on port 7102 or the wss:// protocol on port 7103.

Connecting to Job Output (Sink)

  • Append this to the WebSocket URI to connect to a Job by name: /jobconnectbyname/JobName

  • Append this to the WebSocket URI to connect to a specific running Job ID: /jobconnectbyid/JobID

Upon connecting, the server starts writing messages that are coming in from the corresponding Jobs.

You can append query parameters to the WebSocket URI (preceded by “?”) as is the case in a REST API. Use this to pass any Sink parameters your Job accepts. All Jobs accept the “sampleMSec=mSecs” Sink parameter which limits the rate at which the Sink output is sampled by the server.

Submitting and Connecting to Job Output

  • Append this to the WebSocket URI to submit and connect to the submitted Job: /jobsubmitandconnect

Note that you will have to send one message on the WebSocket, which is the same JSON payload that you would send as a POST body for the equivalent REST API. The server then submits the Job and then starts writing messages into the WebSocket as it gets output from the Job.

You can append query parameters to the WebSocket URI (preceded by “?”) as is the case in a REST API. Use this to pass any Sink parameters your Job accepts. All Jobs accept the “sampleMSec=mSecs” sink parameter which limits the rate at which the Sink output is sampled by the server.

Example: Javascript to Connect a Job

<!DOCTYPE html>  
<meta charset="utf-8" />  
<title>WebSocket Test</title>  
<script language="javascript" type="text/javascript">  
var wsUri = "ws://your-domain.com/jobconnectbyname/YourJobName?sampleMSec=2000";
var output;  
function init() { 
  output = document.getElementById("output"); 
  testWebSocket(); 
}
function testWebSocket() { 
  websocket = new WebSocket(wsUri);
  websocket.onopen = function(evt) { onOpen(evt) }; 
  websocket.onclose = function(evt) { onClose(evt) }; 
  websocket.onmessage = function(evt) { onMessage(evt) }; 
  websocket.onerror = function(evt) { onError(evt) }; 
}  
function onOpen(evt) {
  writeToScreen("CONNECTED"); 
}
function onClose(evt) { 
  writeToScreen("DISCONNECTED"); 
}
function onMessage(evt) {
  writeToScreen('<span style="color: blue;">RESPONSE: ' + evt.data+'</span>');
}
function onError(evt) {
  writeToScreen('<span style="color: red;">ERROR:</span> ' + evt.data);
}
function doSend(message) { 
  websocket.send(message); 
}
function writeToScreen(message) { 
  var pre = document.createElement("p"); 
  pre.style.wordWrap = "break-word"; 
  pre.innerHTML = message; output.appendChild(pre); 
}
window.addEventListener("load", init, true);  
</script>  
<h2>WebSocket Test</h2>  
<div id="output"></div>

Example: Javascript to Submit a Job and Connect to It

<!DOCTYPE html>  
<meta charset="utf-8" />  
<title>WebSocket Test</title>  
<script language="javascript" type="text/javascript">  
var wsUri = "ws://your-domain.com/jobsubmitandconnect/"; 
var output;  
function init() { 
  output = document.getElementById("output"); 
  testWebSocket(); 
}
function testWebSocket() { 
  websocket = new WebSocket(wsUri);
  websocket.onopen = function(evt) { onOpen(evt) }; 
  websocket.onclose = function(evt) { onClose(evt) }; 
  websocket.onmessage = function(evt) { onMessage(evt) }; 
  websocket.onerror = function(evt) { onError(evt) }; 
}  
function onOpen(evt) { 
  writeToScreen("CONNECTED"); 
  // Change this to your job's submit json content.
  // See job submit REST API above for another example.
  doSend("{\n" +
                "  \"name\":\"Outliers-mock3\",\n" +
                "  \"version\":\"\",\n" +
                "  \"parameters\":[],\n" +
                "  \"jobSla\":{\"runtimeLimitSecs\":0,\"durationType\":\"Transient\",\"userProvidedType\":\"{\\\"unique\\\":\\\"foobar\\\"}\"},\n" +
                "  \"subscriptionTimeoutSecs\":\"90\",\n" +
                "  \"jobJarFileLocation\":null,\n" +
                "  \"schedulingInfo\":{\"stages\":{\"1\":{\"numberOfInstances\":1,\"machineDefinition\":{\"cpuCores\":1.0,\"memoryMB\":2048.0,\"diskMB\":1.0,\"scalable\":\"true\"}}}\n" +
                "}");
}  
function onClose(evt) { 
  writeToScreen("DISCONNECTED"); 
}
function onMessage(evt) {
  writeToScreen('<span style="color: blue;">RESPONSE: ' + evt.data+'</span>');
}
function onError(evt) {
  writeToScreen('<span style="color: red;">ERROR:</span> ' + evt.data);
}
function doSend(message) { 
  websocket.send(message); 
}
function writeToScreen(message) { 
  var pre = document.createElement("p"); 
  pre.style.wordWrap = "break-word"; 
  pre.innerHTML = message; output.appendChild(pre); 
}
window.addEventListener("load", init, true);  
</script>  
<h2>WebSocket Test</h2>  
<div id="output"></div>