use of co.cask.cdap.proto.BatchRunnable in project cdap by caskdata.
the class ProgramLifecycleHttpHandler method getInstances.
/**
* Returns the number of instances for all program runnables that are passed into the data. The data is an array of
* Json objects where each object must contain the following three elements: appId, programType, and programId
* (flow name, service name). Retrieving instances only applies to flows, and user
* services. For flows, another parameter, "runnableId", must be provided. This corresponds to the
* flowlet/runnable for which to retrieve the instances.
* <p>
* Example input:
* <pre><code>
* [{"appId": "App1", "programType": "Service", "programId": "Service1", "runnableId": "Runnable1"},
* {"appId": "App1", "programType": "Mapreduce", "programId": "Mapreduce2"},
* {"appId": "App2", "programType": "Flow", "programId": "Flow1", "runnableId": "Flowlet1"}]
* </code></pre>
* </p><p>
* The response will be an array of JsonObjects each of which will contain the three input parameters
* as well as 3 fields:
* <ul>
* <li>"provisioned" which maps to the number of instances actually provided for the input runnable;</li>
* <li>"requested" which maps to the number of instances the user has requested for the input runnable; and</li>
* <li>"statusCode" which maps to the http status code for the data in that JsonObjects (200, 400, 404).</li>
* </ul>
* </p><p>
* If an error occurs in the input (for the example above, Flowlet1 does not exist), then all JsonObjects for
* which the parameters have a valid instances will have the provisioned and requested fields status code fields
* but all JsonObjects for which the parameters are not valid will have an error message and statusCode.
* </p><p>
* For example, if there is no Flowlet1 in the above data, then the response could be 200 OK with the following data:
* </p>
* <pre><code>
* [{"appId": "App1", "programType": "Service", "programId": "Service1", "runnableId": "Runnable1",
* "statusCode": 200, "provisioned": 2, "requested": 2},
* {"appId": "App1", "programType": "Mapreduce", "programId": "Mapreduce2", "statusCode": 400,
* "error": "Program type 'Mapreduce' is not a valid program type to get instances"},
* {"appId": "App2", "programType": "Flow", "programId": "Flow1", "runnableId": "Flowlet1", "statusCode": 404,
* "error": "Program": Flowlet1 not found"}]
* </code></pre>
*/
@POST
@Path("/instances")
@AuditPolicy(AuditDetail.REQUEST_BODY)
public void getInstances(HttpRequest request, HttpResponder responder, @PathParam("namespace-id") String namespaceId) throws IOException, BadRequestException {
List<BatchRunnable> runnables = validateAndGetBatchInput(request, BATCH_RUNNABLES_TYPE);
// cache app specs to perform fewer store lookups
Map<ApplicationId, ApplicationSpecification> appSpecs = new HashMap<>();
List<BatchRunnableInstances> output = new ArrayList<>(runnables.size());
for (BatchRunnable runnable : runnables) {
// cant get instances for things that are not flows, services, or workers
if (!canHaveInstances(runnable.getProgramType())) {
output.add(new BatchRunnableInstances(runnable, HttpResponseStatus.BAD_REQUEST.getCode(), String.format("Program type '%s' is not a valid program type to get instances", runnable.getProgramType().getPrettyName())));
continue;
}
ApplicationId appId = new ApplicationId(namespaceId, runnable.getAppId());
// populate spec cache if this is the first time we've seen the appid.
if (!appSpecs.containsKey(appId)) {
appSpecs.put(appId, store.getApplication(appId));
}
ApplicationSpecification spec = appSpecs.get(appId);
if (spec == null) {
output.add(new BatchRunnableInstances(runnable, HttpResponseStatus.NOT_FOUND.getCode(), String.format("App: %s not found", appId)));
continue;
}
ProgramId programId = appId.program(runnable.getProgramType(), runnable.getProgramId());
output.add(getProgramInstances(runnable, spec, programId));
}
responder.sendJson(HttpResponseStatus.OK, output);
}
Aggregations