use of co.cask.cdap.common.NotFoundException in project cdap by caskdata.
the class ProgramLifecycleHttpHandler method programHistory.
/**
* Returns program runs of an app version based on options it returns either currently running or completed or failed.
* Default it returns all.
*/
@GET
@Path("/apps/{app-name}/versions/{app-version}/{program-type}/{program-name}/runs")
public void programHistory(HttpRequest request, HttpResponder responder, @PathParam("namespace-id") String namespaceId, @PathParam("app-name") String appName, @PathParam("app-version") String appVersion, @PathParam("program-type") String type, @PathParam("program-name") String programName, @QueryParam("status") String status, @QueryParam("start") String startTs, @QueryParam("end") String endTs, @QueryParam("limit") @DefaultValue("100") final int resultLimit) throws Exception {
ProgramType programType = getProgramType(type);
if (programType == null || programType == ProgramType.WEBAPP) {
throw new NotFoundException(String.format("Program history is not supported for program type '%s'.", type));
}
long start = (startTs == null || startTs.isEmpty()) ? 0 : Long.parseLong(startTs);
long end = (endTs == null || endTs.isEmpty()) ? Long.MAX_VALUE : Long.parseLong(endTs);
ProgramId program = new ApplicationId(namespaceId, appName, appVersion).program(programType, programName);
ProgramSpecification specification = lifecycleService.getProgramSpecification(program);
if (specification == null) {
throw new NotFoundException(program);
}
getRuns(responder, program, status, start, end, resultLimit);
}
use of co.cask.cdap.common.NotFoundException in project cdap by caskdata.
the class ProgramLifecycleHttpHandler method doGetSchedules.
protected void doGetSchedules(HttpResponder responder, String namespace, String app, String version, @Nullable String workflow, @Nullable String format) throws NotFoundException, BadRequestException {
boolean asScheduleSpec = returnScheduleAsSpec(format);
ApplicationId applicationId = new ApplicationId(namespace, app, version);
ApplicationSpecification appSpec = store.getApplication(applicationId);
if (appSpec == null) {
throw new NotFoundException(applicationId);
}
List<ProgramSchedule> schedules;
if (workflow != null) {
WorkflowId workflowId = applicationId.workflow(workflow);
if (appSpec.getWorkflows().get(workflow) == null) {
throw new NotFoundException(workflowId);
}
schedules = programScheduler.listSchedules(workflowId);
} else {
schedules = programScheduler.listSchedules(applicationId);
}
List<ScheduleDetail> details = Schedulers.toScheduleDetails(schedules);
if (asScheduleSpec) {
List<ScheduleSpecification> specs = ScheduleDetail.toScheduleSpecs(details);
responder.sendJson(HttpResponseStatus.OK, specs, Schedulers.SCHEDULE_SPECS_TYPE, GSON_FOR_SCHEDULES);
} else {
responder.sendJson(HttpResponseStatus.OK, details, Schedulers.SCHEDULE_DETAILS_TYPE, GSON_FOR_SCHEDULES);
}
}
use of co.cask.cdap.common.NotFoundException in project cdap by caskdata.
the class MonitorHandler method restartInstances.
private void restartInstances(HttpResponder responder, String serviceName, int instanceId, boolean restartAll) throws Exception {
long startTimeMs = System.currentTimeMillis();
boolean isSuccess = true;
if (!serviceManagementMap.containsKey(serviceName)) {
throw new NotFoundException(String.format("Invalid service name %s", serviceName));
}
MasterServiceManager masterServiceManager = serviceManagementMap.get(serviceName);
try {
if (!masterServiceManager.isServiceEnabled()) {
String message = String.format("Failed to restart instance for %s because the service is not enabled.", serviceName);
LOG.debug(message);
isSuccess = false;
throw new ForbiddenException(message);
}
if (restartAll) {
masterServiceManager.restartAllInstances();
} else {
if (instanceId < 0 || instanceId >= masterServiceManager.getInstances()) {
throw new IllegalArgumentException();
}
masterServiceManager.restartInstances(instanceId);
}
responder.sendStatus(HttpResponseStatus.OK);
} catch (IllegalStateException ise) {
String message = String.format("Failed to restart instance for %s because the service may not be ready yet", serviceName);
LOG.debug(message, ise);
isSuccess = false;
throw new ServiceUnavailableException(message);
} catch (IllegalArgumentException iex) {
String message = String.format("Failed to restart instance %d for service: %s because invalid instance id", instanceId, serviceName);
LOG.debug(message, iex);
isSuccess = false;
throw new BadRequestException(message);
} catch (Exception ex) {
LOG.warn(String.format("Exception when trying to restart instances for service %s", serviceName), ex);
isSuccess = false;
throw new Exception(String.format("Error restarting instance %d for service: %s", instanceId, serviceName));
} finally {
long endTimeMs = System.currentTimeMillis();
if (restartAll) {
serviceStore.setRestartAllInstancesRequest(serviceName, startTimeMs, endTimeMs, isSuccess);
} else {
serviceStore.setRestartInstanceRequest(serviceName, startTimeMs, endTimeMs, isSuccess, instanceId);
}
}
}
use of co.cask.cdap.common.NotFoundException in project cdap by caskdata.
the class MonitorHandler method getServiceInstance.
/**
* Returns the number of instances of CDAP Services
*/
@Path("/system/services/{service-name}/instances")
@GET
public void getServiceInstance(HttpRequest request, HttpResponder responder, @PathParam("service-name") String serviceName) throws Exception {
JsonObject reply = new JsonObject();
if (!serviceManagementMap.containsKey(serviceName)) {
throw new NotFoundException(String.format("Invalid service name %s", serviceName));
}
MasterServiceManager serviceManager = serviceManagementMap.get(serviceName);
if (serviceManager.isServiceEnabled()) {
int actualInstance = serviceManagementMap.get(serviceName).getInstances();
reply.addProperty("provisioned", actualInstance);
reply.addProperty("requested", getSystemServiceInstanceCount(serviceName));
responder.sendJson(HttpResponseStatus.OK, reply);
} else {
throw new ForbiddenException(String.format("Service %s is not enabled", serviceName));
}
}
use of co.cask.cdap.common.NotFoundException in project cdap by caskdata.
the class ProgramLifecycleHttpHandlerTest method testBatchStatus.
@Test
public void testBatchStatus() throws Exception {
final String statusUrl1 = getVersionedAPIPath("status", Constants.Gateway.API_VERSION_3_TOKEN, TEST_NAMESPACE1);
final String statusUrl2 = getVersionedAPIPath("status", Constants.Gateway.API_VERSION_3_TOKEN, TEST_NAMESPACE2);
// invalid json must return 400
Assert.assertEquals(400, doPost(statusUrl1, "").getStatusLine().getStatusCode());
Assert.assertEquals(400, doPost(statusUrl2, "").getStatusLine().getStatusCode());
// empty array is valid args
Assert.assertEquals(200, doPost(statusUrl1, EMPTY_ARRAY_JSON).getStatusLine().getStatusCode());
Assert.assertEquals(200, doPost(statusUrl2, EMPTY_ARRAY_JSON).getStatusLine().getStatusCode());
// deploy an app in namespace1
deploy(WordCountApp.class, Constants.Gateway.API_VERSION_3_TOKEN, TEST_NAMESPACE1);
// deploy another app in namespace2
deploy(AppWithServices.class, Constants.Gateway.API_VERSION_3_TOKEN, TEST_NAMESPACE2);
// data requires appId, programId, and programType. Test missing fields/invalid programType
Assert.assertEquals(400, doPost(statusUrl1, "[{'appId':'WordCountApp', 'programType':'Flow'}]").getStatusLine().getStatusCode());
Assert.assertEquals(400, doPost(statusUrl1, "[{'appId':'WordCountApp', 'programId':'WordCountFlow'}]").getStatusLine().getStatusCode());
Assert.assertEquals(400, doPost(statusUrl1, "[{'programType':'Flow', 'programId':'WordCountFlow'}, {'appId':" + "'AppWithServices', 'programType': 'service', 'programId': 'NoOpService'}]").getStatusLine().getStatusCode());
Assert.assertEquals(400, doPost(statusUrl1, "[{'appId':'WordCountApp', 'programType':'Flow' " + "'programId':'WordCountFlow'}]").getStatusLine().getStatusCode());
// Test missing app, programType, etc
List<JsonObject> returnedBody = readResponse(doPost(statusUrl1, "[{'appId':'NotExist', 'programType':'Flow', " + "'programId':'WordCountFlow'}]"), LIST_OF_JSONOBJECT_TYPE);
Assert.assertEquals(new NotFoundException(new ApplicationId("testnamespace1", "NotExist")).getMessage(), returnedBody.get(0).get("error").getAsString());
returnedBody = readResponse(doPost(statusUrl1, "[{'appId':'WordCountApp', 'programType':'flow', 'programId':'NotExist'}," + "{'appId':'WordCountApp', 'programType':'flow', 'programId':'WordCountFlow'}]"), LIST_OF_JSONOBJECT_TYPE);
Assert.assertEquals(new NotFoundException(new ProgramId("testnamespace1", "WordCountApp", ProgramType.FLOW, "NotExist")).getMessage(), returnedBody.get(0).get("error").getAsString());
Assert.assertEquals(new NotFoundException(new ProgramId("testnamespace1", "WordCountApp", ProgramType.FLOW, "NotExist")).getMessage(), returnedBody.get(0).get("error").getAsString());
// The programType should be consistent. Second object should have proper status
Assert.assertEquals("Flow", returnedBody.get(1).get("programType").getAsString());
Assert.assertEquals(STOPPED, returnedBody.get(1).get("status").getAsString());
// test valid cases for namespace1
HttpResponse response = doPost(statusUrl1, "[{'appId':'WordCountApp', 'programType':'Flow', 'programId':'WordCountFlow'}," + "{'appId': 'WordCountApp', 'programType': 'Service', 'programId': " + "'WordFrequencyService'}]");
verifyInitialBatchStatusOutput(response);
// test valid cases for namespace2
response = doPost(statusUrl2, "[{'appId': 'AppWithServices', 'programType': 'Service', 'programId': " + "'NoOpService'}]");
verifyInitialBatchStatusOutput(response);
// start the flow
Id.Program wordcountFlow1 = Id.Program.from(TEST_NAMESPACE1, WORDCOUNT_APP_NAME, ProgramType.FLOW, WORDCOUNT_FLOW_NAME);
Id.Program service2 = Id.Program.from(TEST_NAMESPACE2, APP_WITH_SERVICES_APP_ID, ProgramType.SERVICE, APP_WITH_SERVICES_SERVICE_NAME);
startProgram(wordcountFlow1);
// test status API after starting the flow
response = doPost(statusUrl1, "[{'appId':'WordCountApp', 'programType':'Flow', 'programId':'WordCountFlow'}," + "{'appId': 'WordCountApp', 'programType': 'Mapreduce', 'programId': 'VoidMapReduceJob'}]");
Assert.assertEquals(200, response.getStatusLine().getStatusCode());
returnedBody = readResponse(response, LIST_OF_JSONOBJECT_TYPE);
Assert.assertEquals(ProgramRunStatus.RUNNING.toString(), returnedBody.get(0).get("status").getAsString());
Assert.assertEquals(STOPPED, returnedBody.get(1).get("status").getAsString());
// start the service
startProgram(service2);
// test status API after starting the service
response = doPost(statusUrl2, "[{'appId': 'AppWithServices', 'programType': 'Service', 'programId': " + "'NoOpService'}]");
Assert.assertEquals(200, response.getStatusLine().getStatusCode());
returnedBody = readResponse(response, LIST_OF_JSONOBJECT_TYPE);
Assert.assertEquals(ProgramRunStatus.RUNNING.toString(), returnedBody.get(0).get("status").getAsString());
// stop the flow
stopProgram(wordcountFlow1);
waitState(wordcountFlow1, STOPPED);
// stop the service
stopProgram(service2);
waitState(service2, STOPPED);
// try posting a status request with namespace2 for apps in namespace1
response = doPost(statusUrl2, "[{'appId':'WordCountApp', 'programType':'Flow', 'programId':'WordCountFlow'}," + "{'appId': 'WordCountApp', 'programType': 'Service', 'programId': 'WordFrequencyService'}," + "{'appId': 'WordCountApp', 'programType': 'Mapreduce', 'programId': 'VoidMapReduceJob'}]");
returnedBody = readResponse(response, LIST_OF_JSONOBJECT_TYPE);
Assert.assertEquals(new NotFoundException(new ApplicationId("testnamespace2", "WordCountApp")).getMessage(), returnedBody.get(0).get("error").getAsString());
Assert.assertEquals(new NotFoundException(new ApplicationId("testnamespace2", "WordCountApp")).getMessage(), returnedBody.get(1).get("error").getAsString());
Assert.assertEquals(new NotFoundException(new ApplicationId("testnamespace2", "WordCountApp")).getMessage(), returnedBody.get(2).get("error").getAsString());
}
Aggregations