Search in sources :

Example 1 with ProgramStatus

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);
}
Also used : BatchProgramStatus(co.cask.cdap.proto.BatchProgramStatus) ArrayList(java.util.ArrayList) NamespaceNotFoundException(co.cask.cdap.common.NamespaceNotFoundException) NotFoundException(co.cask.cdap.common.NotFoundException) ProgramId(co.cask.cdap.proto.id.ProgramId) BatchProgram(co.cask.cdap.proto.BatchProgram) ProgramStatus(co.cask.cdap.proto.ProgramStatus) BatchProgramStatus(co.cask.cdap.proto.BatchProgramStatus) Path(javax.ws.rs.Path) AuditPolicy(co.cask.cdap.common.security.AuditPolicy) POST(javax.ws.rs.POST)

Example 2 with ProgramStatus

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));
}
Also used : ApplicationSpecification(co.cask.cdap.api.app.ApplicationSpecification) JsonObject(com.google.gson.JsonObject) NamespaceNotFoundException(co.cask.cdap.common.NamespaceNotFoundException) NotFoundException(co.cask.cdap.common.NotFoundException) BadRequestException(co.cask.cdap.common.BadRequestException) ProgramType(co.cask.cdap.proto.ProgramType) ApplicationId(co.cask.cdap.proto.id.ApplicationId) ScheduleId(co.cask.cdap.proto.id.ScheduleId) ProgramId(co.cask.cdap.proto.id.ProgramId) ProgramStatus(co.cask.cdap.proto.ProgramStatus) BatchProgramStatus(co.cask.cdap.proto.BatchProgramStatus) Path(javax.ws.rs.Path) GET(javax.ws.rs.GET)

Example 3 with ProgramStatus

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));
}
Also used : ProgramId(co.cask.cdap.proto.id.ProgramId) ConflictException(co.cask.cdap.common.ConflictException) BadRequestException(co.cask.cdap.common.BadRequestException) UnauthorizedException(co.cask.cdap.security.spi.authorization.UnauthorizedException) IOException(java.io.IOException) MethodNotAllowedException(co.cask.cdap.common.MethodNotAllowedException) NotImplementedException(co.cask.cdap.common.NotImplementedException) ServiceUnavailableException(co.cask.cdap.common.ServiceUnavailableException) NamespaceNotFoundException(co.cask.cdap.common.NamespaceNotFoundException) JsonSyntaxException(com.google.gson.JsonSyntaxException) NotFoundException(co.cask.cdap.common.NotFoundException) ProgramScheduleStatus(co.cask.cdap.internal.app.runtime.schedule.ProgramScheduleStatus) BadRequestException(co.cask.cdap.common.BadRequestException) ProgramType(co.cask.cdap.proto.ProgramType) NamespaceId(co.cask.cdap.proto.id.NamespaceId) ScheduleDetail(co.cask.cdap.proto.ScheduleDetail) ProgramStatus(co.cask.cdap.proto.ProgramStatus) BatchProgramStatus(co.cask.cdap.proto.BatchProgramStatus) HashSet(java.util.HashSet) Path(javax.ws.rs.Path) GET(javax.ws.rs.GET)

Example 4 with ProgramStatus

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);
    }
}
Also used : FlowId(co.cask.cdap.proto.id.FlowId) ProgramStatus(co.cask.cdap.proto.ProgramStatus) BatchProgramStatus(co.cask.cdap.proto.BatchProgramStatus) Path(javax.ws.rs.Path) DELETE(javax.ws.rs.DELETE)

Example 5 with ProgramStatus

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));
}
Also used : BatchProgramStatus(co.cask.cdap.proto.BatchProgramStatus) ArrayList(java.util.ArrayList) NamespaceNotFoundException(co.cask.cdap.common.NamespaceNotFoundException) NotFoundException(co.cask.cdap.common.NotFoundException) ProgramId(co.cask.cdap.proto.id.ProgramId) BatchProgram(co.cask.cdap.proto.BatchProgram) ProgramStatus(co.cask.cdap.proto.ProgramStatus) BatchProgramStatus(co.cask.cdap.proto.BatchProgramStatus) Path(javax.ws.rs.Path) AuditPolicy(co.cask.cdap.common.security.AuditPolicy) POST(javax.ws.rs.POST)

Aggregations

BatchProgramStatus (co.cask.cdap.proto.BatchProgramStatus)7 ProgramStatus (co.cask.cdap.proto.ProgramStatus)7 Path (javax.ws.rs.Path)7 ProgramId (co.cask.cdap.proto.id.ProgramId)6 NamespaceNotFoundException (co.cask.cdap.common.NamespaceNotFoundException)5 NotFoundException (co.cask.cdap.common.NotFoundException)5 BadRequestException (co.cask.cdap.common.BadRequestException)4 ServiceUnavailableException (co.cask.cdap.common.ServiceUnavailableException)3 ProgramType (co.cask.cdap.proto.ProgramType)3 GET (javax.ws.rs.GET)3 ConflictException (co.cask.cdap.common.ConflictException)2 MethodNotAllowedException (co.cask.cdap.common.MethodNotAllowedException)2 NotImplementedException (co.cask.cdap.common.NotImplementedException)2 AuditPolicy (co.cask.cdap.common.security.AuditPolicy)2 BatchProgram (co.cask.cdap.proto.BatchProgram)2 ApplicationId (co.cask.cdap.proto.id.ApplicationId)2 NamespaceId (co.cask.cdap.proto.id.NamespaceId)2 UnauthorizedException (co.cask.cdap.security.spi.authorization.UnauthorizedException)2 JsonSyntaxException (com.google.gson.JsonSyntaxException)2 IOException (java.io.IOException)2