use of io.cdap.cdap.proto.id.ProgramId in project cdap by caskdata.
the class ProgramLifecycleHttpHandler method getServiceAvailability.
/**
* Return the availability (i.e. discoverable registration) status of a service.
*/
@GET
@Path("/apps/{app-name}/versions/{app-version}/{service-type}/{program-name}/available")
public void getServiceAvailability(HttpRequest request, HttpResponder responder, @PathParam("namespace-id") String namespaceId, @PathParam("app-name") String appName, @PathParam("app-version") String appVersion, @PathParam("service-type") String serviceType, @PathParam("program-name") String programName) throws Exception {
// Currently we only support services and sparks as the service-type
ProgramType programType = getProgramType(serviceType);
if (!ServiceDiscoverable.getUserServiceTypes().contains(programType)) {
throw new BadRequestException("Only service or spark is support for service availability check");
}
ProgramId programId = new ProgramId(new ApplicationId(namespaceId, appName, appVersion), programType, programName);
ProgramStatus status = lifecycleService.getProgramStatus(programId);
if (status == ProgramStatus.STOPPED) {
throw new ServiceUnavailableException(programId.toString(), "Service is stopped. Please start it.");
}
// Construct discoverable name and return 200 OK if discoverable is present. If not return 503.
String discoverableName = ServiceDiscoverable.getName(programId);
// TODO: CDAP-12959 - Should use the UserServiceEndpointStrategy and discover based on the version
// and have appVersion nullable for the non versioned endpoint
EndpointStrategy strategy = new RandomEndpointStrategy(() -> discoveryServiceClient.discover(discoverableName));
if (strategy.pick(300L, TimeUnit.MILLISECONDS) == null) {
LOG.trace("Discoverable endpoint {} not found", discoverableName);
throw new ServiceUnavailableException(programId.toString(), "Service is running but not accepting requests at this time.");
}
responder.sendString(HttpResponseStatus.OK, "Service is available to accept requests.");
}
use of io.cdap.cdap.proto.id.ProgramId in project cdap by caskdata.
the class ProgramLifecycleHttpHandler method doPerformAction.
private void doPerformAction(FullHttpRequest request, HttpResponder responder, String namespaceId, String appId, String appVersion, String type, String programId, String action) throws Exception {
ApplicationId applicationId = new ApplicationId(namespaceId, appId, appVersion);
if (SCHEDULES.equals(type)) {
ScheduleId scheduleId = applicationId.schedule(programId);
if (action.equals("disable") || action.equals("suspend")) {
programScheduleService.suspend(scheduleId);
} else if (action.equals("enable") || action.equals("resume")) {
programScheduleService.resume(scheduleId);
} else {
throw new BadRequestException("Action for schedules may only be 'enable', 'disable', 'suspend', or 'resume' but is'" + action + "'");
}
responder.sendJson(HttpResponseStatus.OK, "OK");
return;
}
ProgramType programType = getProgramType(type);
ProgramId program = applicationId.program(programType, programId);
Map<String, String> args = decodeArguments(request);
// we have already validated that the action is valid
switch(action.toLowerCase()) {
case "start":
lifecycleService.run(program, args, false);
break;
case "debug":
if (!isDebugAllowed(programType)) {
throw new NotImplementedException(String.format("debug action is not implemented for program type %s", programType));
}
lifecycleService.run(program, args, true);
break;
case "stop":
lifecycleService.stop(program);
break;
default:
throw new NotFoundException(String.format("%s action was not found", action));
}
responder.sendStatus(HttpResponseStatus.OK);
}
use of io.cdap.cdap.proto.id.ProgramId 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"}]
* </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"}]
* </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> batchPrograms = validateAndGetBatchInput(request, BATCH_PROGRAMS_TYPE);
List<ProgramId> programs = batchPrograms.stream().map(p -> new ProgramId(namespaceId, p.getAppId(), p.getProgramType(), p.getProgramId())).collect(Collectors.toList());
Map<ProgramId, ProgramStatus> statuses = lifecycleService.getProgramStatuses(programs);
List<BatchProgramStatus> result = new ArrayList<>(programs.size());
for (BatchProgram program : batchPrograms) {
ProgramId programId = new ProgramId(namespaceId, program.getAppId(), program.getProgramType(), program.getProgramId());
ProgramStatus status = statuses.get(programId);
if (status == null) {
result.add(new BatchProgramStatus(program, HttpResponseStatus.NOT_FOUND.code(), new NotFoundException(programId).getMessage(), null));
} else {
result.add(new BatchProgramStatus(program, HttpResponseStatus.OK.code(), null, status.name()));
}
}
responder.sendJson(HttpResponseStatus.OK, GSON.toJson(result));
}
use of io.cdap.cdap.proto.id.ProgramId in project cdap by caskdata.
the class ProgramLifecycleHttpHandler method performRunLevelStop.
/**
* Stops the particular run of the Workflow or MapReduce program.
*/
@POST
@Path("/apps/{app-id}/{program-type}/{program-id}/runs/{run-id}/stop")
public void performRunLevelStop(HttpRequest request, HttpResponder responder, @PathParam("namespace-id") String namespaceId, @PathParam("app-id") String appId, @PathParam("program-type") String type, @PathParam("program-id") String programId, @PathParam("run-id") String runId) throws Exception {
ProgramType programType = getProgramType(type);
ProgramId program = new ProgramId(namespaceId, appId, programType, programId);
lifecycleService.stop(program, runId);
responder.sendStatus(HttpResponseStatus.OK);
}
use of io.cdap.cdap.proto.id.ProgramId in project cdap by caskdata.
the class ProgramLifecycleHttpHandler method setWorkerInstances.
/**
* Sets the number of instances of a worker.
*/
@PUT
@Path("/apps/{app-id}/workers/{worker-id}/instances")
@AuditPolicy(AuditDetail.REQUEST_BODY)
public void setWorkerInstances(FullHttpRequest request, HttpResponder responder, @PathParam("namespace-id") String namespaceId, @PathParam("app-id") String appId, @PathParam("worker-id") String workerId) throws Exception {
int instances = getInstances(request);
try {
lifecycleService.setInstances(new ProgramId(namespaceId, appId, ProgramType.WORKER, workerId), instances);
responder.sendStatus(HttpResponseStatus.OK);
} catch (SecurityException e) {
responder.sendStatus(HttpResponseStatus.UNAUTHORIZED);
} catch (Throwable e) {
if (respondIfElementNotFound(e, responder)) {
return;
}
throw e;
}
}
Aggregations