use of io.cdap.cdap.common.BadRequestException in project cdap by caskdata.
the class ProgramLifecycleHttpHandler method startPrograms.
/**
* Starts 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.). In additional, each object can contain an optional runtimeargs element,
* which is a map of arguments to start the program with.
* <p>
* Example input:
* <pre><code>
* [{"appId": "App1", "programType": "Service", "programId": "Service1"},
* {"appId": "App1", "programType": "Mapreduce", "programId": "MapReduce2", "runtimeargs":{"arg1":"val1"}}]
* </code></pre>
* </p><p>
* The response will be an array of JsonObjects each of which will contain the three input parameters
* as well as a "statusCode" field 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},
* {"appId": "App2", "programType": "Mapreduce", "programId": "Mapreduce2",
* "statusCode":404, "error": "App: App2 not found"}]
* </code></pre>
*/
@POST
@Path("/start")
@AuditPolicy({ AuditDetail.REQUEST_BODY, AuditDetail.RESPONSE_BODY })
public void startPrograms(FullHttpRequest request, HttpResponder responder, @PathParam("namespace-id") String namespaceId) throws Exception {
List<BatchProgramStart> programs = validateAndGetBatchInput(request, BATCH_STARTS_TYPE);
List<BatchProgramResult> output = new ArrayList<>(programs.size());
for (BatchProgramStart program : programs) {
ProgramId programId = new ProgramId(namespaceId, program.getAppId(), program.getProgramType(), program.getProgramId());
try {
String runId = lifecycleService.run(programId, program.getRuntimeargs(), false).getId();
output.add(new BatchProgramResult(program, HttpResponseStatus.OK.code(), null, runId));
} catch (NotFoundException e) {
output.add(new BatchProgramResult(program, HttpResponseStatus.NOT_FOUND.code(), e.getMessage()));
} catch (BadRequestException e) {
output.add(new BatchProgramResult(program, HttpResponseStatus.BAD_REQUEST.code(), e.getMessage()));
} catch (ConflictException e) {
output.add(new BatchProgramResult(program, HttpResponseStatus.CONFLICT.code(), e.getMessage()));
}
}
responder.sendJson(HttpResponseStatus.OK, GSON.toJson(output));
}
use of io.cdap.cdap.common.BadRequestException in project cdap by caskdata.
the class ProgramLifecycleHttpHandler method doAddSchedule.
private void doAddSchedule(FullHttpRequest request, HttpResponder responder, String namespace, String appName, String appVersion, String scheduleName) throws Exception {
final ApplicationId applicationId = new ApplicationId(namespace, appName, appVersion);
ScheduleDetail scheduleFromRequest = readScheduleDetailBody(request, scheduleName);
if (scheduleFromRequest.getProgram() == null) {
throw new BadRequestException("No program was specified for the schedule");
}
if (scheduleFromRequest.getProgram().getProgramType() == null) {
throw new BadRequestException("No program type was specified for the schedule");
}
if (scheduleFromRequest.getProgram().getProgramName() == null) {
throw new BadRequestException("No program name was specified for the schedule");
}
if (scheduleFromRequest.getTrigger() == null) {
throw new BadRequestException("No trigger was specified for the schedule");
}
ProgramType programType = ProgramType.valueOfSchedulableType(scheduleFromRequest.getProgram().getProgramType());
String programName = scheduleFromRequest.getProgram().getProgramName();
ProgramId programId = applicationId.program(programType, programName);
lifecycleService.ensureProgramExists(programId);
String description = Objects.firstNonNull(scheduleFromRequest.getDescription(), "");
Map<String, String> properties = Objects.firstNonNull(scheduleFromRequest.getProperties(), Collections.emptyMap());
List<? extends Constraint> constraints = Objects.firstNonNull(scheduleFromRequest.getConstraints(), NO_CONSTRAINTS);
long timeoutMillis = Objects.firstNonNull(scheduleFromRequest.getTimeoutMillis(), Schedulers.JOB_QUEUE_TIMEOUT_MILLIS);
ProgramSchedule schedule = new ProgramSchedule(scheduleName, description, programId, properties, scheduleFromRequest.getTrigger(), constraints, timeoutMillis);
programScheduleService.add(schedule);
responder.sendStatus(HttpResponseStatus.OK);
}
use of io.cdap.cdap.common.BadRequestException 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.common.BadRequestException 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.common.BadRequestException in project cdap by caskdata.
the class ProgramLifecycleHttpHandler method resetLogLevels.
private void resetLogLevels(FullHttpRequest request, HttpResponder responder, String namespace, String appName, String appVersion, String type, String programName, String runId) throws Exception {
ProgramType programType = getProgramType(type);
try {
Set<String> loggerNames = parseBody(request, SET_STRING_TYPE);
lifecycleService.resetProgramLogLevels(new ApplicationId(namespace, appName, appVersion).program(programType, programName), loggerNames == null ? Collections.emptySet() : loggerNames, runId);
responder.sendStatus(HttpResponseStatus.OK);
} catch (JsonSyntaxException e) {
throw new BadRequestException("Invalid JSON in body");
} catch (SecurityException e) {
throw new UnauthorizedException("Unauthorized to reset the log levels");
}
}
Aggregations