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¶
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 responsePossible 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…
endpoint?pageSize=10&offset=0
endpoint?pageSize=10&offset=10
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:
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>