use of io.cdap.cdap.proto.BatchRunnableInstances 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"}]
* </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"}]
* </code></pre>
*/
@POST
@Path("/instances")
@AuditPolicy(AuditDetail.REQUEST_BODY)
public void getInstances(FullHttpRequest 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.code(), 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.code(), 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, GSON.toJson(output));
}
use of io.cdap.cdap.proto.BatchRunnableInstances in project cdap by caskdata.
the class ProgramLifecycleHttpHandler method getProgramInstances.
/**
* Get requested and provisioned instances for a program type.
* The program type passed here should be one that can have instances (flows, services, ...)
* Requires caller to do this validation.
*/
private BatchRunnableInstances getProgramInstances(BatchRunnable runnable, ApplicationSpecification spec, ProgramId programId) {
int requested;
String programName = programId.getProgram();
ProgramType programType = programId.getType();
if (programType == ProgramType.WORKER) {
if (!spec.getWorkers().containsKey(programName)) {
return new BatchRunnableInstances(runnable, HttpResponseStatus.NOT_FOUND.code(), "Worker: " + programName + " not found");
}
requested = spec.getWorkers().get(programName).getInstances();
} else if (programType == ProgramType.SERVICE) {
if (!spec.getServices().containsKey(programName)) {
return new BatchRunnableInstances(runnable, HttpResponseStatus.NOT_FOUND.code(), "Service: " + programName + " not found");
}
requested = spec.getServices().get(programName).getInstances();
} else {
return new BatchRunnableInstances(runnable, HttpResponseStatus.BAD_REQUEST.code(), "Instances not supported for program type + " + programType);
}
int provisioned = getInstanceCount(programId, programName);
// use the pretty name of program types to be consistent
return new BatchRunnableInstances(runnable, HttpResponseStatus.OK.code(), provisioned, requested);
}
Aggregations