use of co.cask.cdap.proto.ProgramStatus in project cdap by caskdata.
the class ProgramLifecycleHttpHandler method getStatuses.
/**
* Returns the status for all programs 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, etc.).
* <p>
* Example input:
* <pre><code>
* [{"appId": "App1", "programType": "Service", "programId": "Service1"},
* {"appId": "App1", "programType": "Mapreduce", "programId": "MapReduce2"},
* {"appId": "App2", "programType": "Flow", "programId": "Flow1"}]
* </code></pre>
* </p><p>
* The response will be an array of JsonObjects each of which will contain the three input parameters
* as well as 2 fields, "status" which maps to the status of the program and "statusCode" which maps to the
* status code for the data in that JsonObjects.
* </p><p>
* If an error occurs in the input (for the example above, App2 does not exist), then all JsonObjects for which the
* parameters have a valid status will have the status field but all JsonObjects for which the parameters do not have
* a valid status will have an error message and statusCode.
* </p><p>
* For example, if there is no App2 in the data above, then the response would be 200 OK with following possible data:
* </p>
* <pre><code>
* [{"appId": "App1", "programType": "Service", "programId": "Service1", "statusCode": 200, "status": "RUNNING"},
* {"appId": "App1", "programType": "Mapreduce", "programId": "Mapreduce2", "statusCode": 200, "status": "STOPPED"},
* {"appId":"App2", "programType":"Flow", "programId":"Flow1", "statusCode":404, "error": "App: App2 not found"}]
* </code></pre>
*/
@POST
@Path("/status")
@AuditPolicy(AuditDetail.REQUEST_BODY)
public void getStatuses(HttpRequest request, HttpResponder responder, @PathParam("namespace-id") String namespaceId) throws Exception {
List<BatchProgram> programs = validateAndGetBatchInput(request, BATCH_PROGRAMS_TYPE);
List<BatchProgramStatus> statuses = new ArrayList<>(programs.size());
for (BatchProgram program : programs) {
ProgramId programId = new ProgramId(namespaceId, program.getAppId(), program.getProgramType(), program.getProgramId());
try {
ProgramStatus programStatus = lifecycleService.getProgramStatus(programId);
statuses.add(new BatchProgramStatus(program, HttpResponseStatus.OK.getCode(), null, programStatus.name()));
} catch (NotFoundException e) {
statuses.add(new BatchProgramStatus(program, HttpResponseStatus.NOT_FOUND.getCode(), e.getMessage(), null));
}
}
responder.sendJson(HttpResponseStatus.OK, statuses);
}
use of co.cask.cdap.proto.ProgramStatus in project cdap by caskdata.
the class ProgramLifecycleHttpHandler method getStatus.
/**
* Returns status of a type specified by the type{flows,workflows,mapreduce,spark,services,schedules}.
*/
@GET
@Path("/apps/{app-id}/versions/{version-id}/{program-type}/{program-id}/status")
public void getStatus(HttpRequest request, HttpResponder responder, @PathParam("namespace-id") String namespaceId, @PathParam("app-id") String appId, @PathParam("version-id") String versionId, @PathParam("program-type") String type, @PathParam("program-id") String programId) throws Exception {
ApplicationId applicationId = new ApplicationId(namespaceId, appId, versionId);
if (SCHEDULES.equals(type)) {
JsonObject json = new JsonObject();
ScheduleId scheduleId = applicationId.schedule(programId);
ApplicationSpecification appSpec = store.getApplication(applicationId);
if (appSpec == null) {
throw new NotFoundException(applicationId);
}
json.addProperty("status", programScheduleService.getStatus(scheduleId).toString());
responder.sendJson(HttpResponseStatus.OK, json.toString());
return;
}
ProgramType programType;
try {
programType = ProgramType.valueOfCategoryName(type);
} catch (IllegalArgumentException e) {
throw new BadRequestException(e);
}
ProgramId program = applicationId.program(programType, programId);
ProgramStatus programStatus = lifecycleService.getProgramStatus(program);
Map<String, String> status = ImmutableMap.of("status", programStatus.name());
responder.sendJson(HttpResponseStatus.OK, GSON.toJson(status));
}
use of co.cask.cdap.proto.ProgramStatus in project cdap by caskdata.
the class ProgramLifecycleHttpHandler method getProgramStatusSchedules.
/**
* Get schedules containing {@link ProgramStatusTrigger} filtered by triggering program, and optionally by
* triggering program statuses or schedule status
* @param triggerNamespaceId namespace of the triggering program in {@link ProgramStatusTrigger}
* @param triggerAppName application name of the triggering program in {@link ProgramStatusTrigger}
* @param triggerAppVersion application version of the triggering program in {@link ProgramStatusTrigger}
* @param triggerProgramType program type of the triggering program in {@link ProgramStatusTrigger}
* @param triggerProgramName program name of the triggering program in {@link ProgramStatusTrigger}
* @param triggerProgramStatuses comma separated {@link ProgramStatus} in {@link ProgramStatusTrigger}.
* Schedules with {@link ProgramStatusTrigger} triggered by none of the
* {@link ProgramStatus} in triggerProgramStatuses will be filtered out.
* If not specified, schedules will be returned regardless of triggering program status.
* @param scheduleStatus status of the schedule. Can only be one of "SCHEDULED" or "SUSPENDED".
* If specified, only schedules with matching status will be returned.
*/
@GET
@Path("schedules/trigger-type/program-status")
public void getProgramStatusSchedules(HttpRequest request, HttpResponder responder, @QueryParam("trigger-namespace-id") String triggerNamespaceId, @QueryParam("trigger-app-name") String triggerAppName, @QueryParam("trigger-app-version") @DefaultValue(ApplicationId.DEFAULT_VERSION) String triggerAppVersion, @QueryParam("trigger-program-type") String triggerProgramType, @QueryParam("trigger-program-name") String triggerProgramName, @QueryParam("trigger-program-statuses") String triggerProgramStatuses, @QueryParam("schedule-status") String scheduleStatus) throws Exception {
if (triggerNamespaceId == null) {
throw new BadRequestException("Must specify trigger-namespace-id as a query param");
}
if (triggerAppName == null) {
throw new BadRequestException("Must specify trigger-app-name as a query param");
}
if (triggerProgramType == null) {
throw new BadRequestException("Must specify trigger-program-type as a query param");
}
if (triggerProgramName == null) {
throw new BadRequestException("Must specify trigger-program-name as a query param");
}
ProgramType programType;
try {
programType = ProgramType.valueOfCategoryName(triggerProgramType);
} catch (IllegalArgumentException e) {
throw new BadRequestException(e.getMessage(), e);
}
ProgramScheduleStatus programScheduleStatus;
try {
programScheduleStatus = scheduleStatus == null ? null : ProgramScheduleStatus.valueOf(scheduleStatus);
} catch (IllegalArgumentException e) {
throw new BadRequestException(String.format("Invalid schedule status '%s'. Must be one of %s.", scheduleStatus, Joiner.on(',').join(ProgramScheduleStatus.values())), e);
}
ProgramId triggerProgramId = new NamespaceId(triggerNamespaceId).app(triggerAppName, triggerAppVersion).program(programType, triggerProgramName);
Set<co.cask.cdap.api.ProgramStatus> queryProgramStatuses = new HashSet<>();
if (triggerProgramStatuses != null) {
try {
for (String status : triggerProgramStatuses.split(",")) {
queryProgramStatuses.add(co.cask.cdap.api.ProgramStatus.valueOf(status));
}
} catch (Exception e) {
throw new BadRequestException(String.format("Unable to parse program statuses '%s'. Must be comma separated " + "valid ProgramStatus names such as COMPLETED, FAILED, KILLED.", triggerProgramStatuses), e);
}
} else {
// Query for schedules with all the statuses if no query status is specified
Collections.addAll(queryProgramStatuses, co.cask.cdap.api.ProgramStatus.values());
}
List<ScheduleDetail> details = programScheduleService.findTriggeredBy(triggerProgramId, queryProgramStatuses).stream().filter(record -> programScheduleStatus == null || record.getMeta().getStatus().equals(programScheduleStatus)).map(ProgramScheduleRecord::toScheduleDetail).collect(Collectors.toList());
responder.sendJson(HttpResponseStatus.OK, GSON.toJson(details, Schedulers.SCHEDULE_DETAILS_TYPE));
}
use of co.cask.cdap.proto.ProgramStatus in project cdap by caskdata.
the class ProgramLifecycleHttpHandler method deleteFlowQueues.
/**
* Deletes queues.
*/
@DELETE
@Path("/apps/{app-id}/flows/{flow-id}/queues")
public void deleteFlowQueues(HttpRequest request, HttpResponder responder, @PathParam("namespace-id") String namespaceId, @PathParam("app-id") String appId, @PathParam("flow-id") String flowId) throws Exception {
FlowId flow = new FlowId(namespaceId, appId, flowId);
try {
ProgramStatus status = lifecycleService.getProgramStatus(flow);
if (ProgramStatus.RUNNING == status) {
responder.sendString(HttpResponseStatus.FORBIDDEN, "Flow is running, please stop it first.");
} else {
queueAdmin.dropAllForFlow(flow);
FlowUtils.deleteFlowPendingMetrics(metricStore, namespaceId, appId, flowId);
responder.sendStatus(HttpResponseStatus.OK);
}
} catch (SecurityException e) {
responder.sendStatus(HttpResponseStatus.UNAUTHORIZED);
}
}
use of co.cask.cdap.proto.ProgramStatus in project cdap by caskdata.
the class ProgramLifecycleHttpHandler method getStatuses.
/**
* Returns the status for all programs 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, etc.).
* <p>
* Example input:
* <pre><code>
* [{"appId": "App1", "programType": "Service", "programId": "Service1"},
* {"appId": "App1", "programType": "Mapreduce", "programId": "MapReduce2"},
* {"appId": "App2", "programType": "Flow", "programId": "Flow1"}]
* </code></pre>
* </p><p>
* The response will be an array of JsonObjects each of which will contain the three input parameters
* as well as 2 fields, "status" which maps to the status of the program and "statusCode" which maps to the
* status code for the data in that JsonObjects.
* </p><p>
* If an error occurs in the input (for the example above, App2 does not exist), then all JsonObjects for which the
* parameters have a valid status will have the status field but all JsonObjects for which the parameters do not have
* a valid status will have an error message and statusCode.
* </p><p>
* For example, if there is no App2 in the data above, then the response would be 200 OK with following possible data:
* </p>
* <pre><code>
* [{"appId": "App1", "programType": "Service", "programId": "Service1", "statusCode": 200, "status": "RUNNING"},
* {"appId": "App1", "programType": "Mapreduce", "programId": "Mapreduce2", "statusCode": 200, "status": "STOPPED"},
* {"appId":"App2", "programType":"Flow", "programId":"Flow1", "statusCode":404, "error": "App: App2 not found"}]
* </code></pre>
*/
@POST
@Path("/status")
@AuditPolicy(AuditDetail.REQUEST_BODY)
public void getStatuses(FullHttpRequest request, HttpResponder responder, @PathParam("namespace-id") String namespaceId) throws Exception {
List<BatchProgram> programs = validateAndGetBatchInput(request, BATCH_PROGRAMS_TYPE);
List<BatchProgramStatus> statuses = new ArrayList<>(programs.size());
for (BatchProgram program : programs) {
ProgramId programId = new ProgramId(namespaceId, program.getAppId(), program.getProgramType(), program.getProgramId());
try {
ProgramStatus programStatus = lifecycleService.getProgramStatus(programId);
statuses.add(new BatchProgramStatus(program, HttpResponseStatus.OK.code(), null, programStatus.name()));
} catch (NotFoundException e) {
statuses.add(new BatchProgramStatus(program, HttpResponseStatus.NOT_FOUND.code(), e.getMessage(), null));
}
}
responder.sendJson(HttpResponseStatus.OK, GSON.toJson(statuses));
}
Aggregations