use of co.cask.cdap.proto.BatchProgram 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.BatchProgram in project cdap by caskdata.
the class RestartProgramsCommand method runBatchCommand.
@Override
protected void runBatchCommand(PrintStream printStream, Args<BatchProgram> args) throws Exception {
NamespaceId namespace = args.appId.getParent();
printStream.print("Stopping programs...\n");
programClient.stop(namespace, args.programs);
printStream.print("Starting programs...\n");
List<BatchProgramStart> startList = new ArrayList<>(args.programs.size());
for (BatchProgram program : args.programs) {
startList.add(new BatchProgramStart(program));
}
programClient.start(namespace, startList);
}
use of co.cask.cdap.proto.BatchProgram 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));
}
use of co.cask.cdap.proto.BatchProgram in project cdap by caskdata.
the class ProgramLifecycleHttpHandler method stopPrograms.
/**
* Stops 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 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": "App1", "programType": "Mapreduce", "programId": "Mapreduce2", "statusCode": 200},
* {"appId":"App2", "programType":"Flow", "programId":"Flow1", "statusCode":404, "error": "App: App2 not found"}]
* </code></pre>
*/
@POST
@Path("/stop")
@AuditPolicy({ AuditDetail.REQUEST_BODY, AuditDetail.RESPONSE_BODY })
public void stopPrograms(HttpRequest request, HttpResponder responder, @PathParam("namespace-id") String namespaceId) throws Exception {
List<BatchProgram> programs = validateAndGetBatchInput(request, BATCH_PROGRAMS_TYPE);
List<ListenableFuture<BatchProgramResult>> issuedStops = new ArrayList<>(programs.size());
for (final BatchProgram program : programs) {
ProgramId programId = new ProgramId(namespaceId, program.getAppId(), program.getProgramType(), program.getProgramId());
try {
List<ListenableFuture<ProgramController>> stops = lifecycleService.issueStop(programId, null);
for (ListenableFuture<ProgramController> stop : stops) {
ListenableFuture<BatchProgramResult> issuedStop = Futures.transform(stop, new Function<ProgramController, BatchProgramResult>() {
@Override
public BatchProgramResult apply(ProgramController input) {
return new BatchProgramResult(program, HttpResponseStatus.OK.getCode(), null, input.getRunId().getId());
}
});
issuedStops.add(issuedStop);
}
} catch (NotFoundException e) {
issuedStops.add(Futures.immediateFuture(new BatchProgramResult(program, HttpResponseStatus.NOT_FOUND.getCode(), e.getMessage())));
} catch (BadRequestException e) {
issuedStops.add(Futures.immediateFuture(new BatchProgramResult(program, HttpResponseStatus.BAD_REQUEST.getCode(), e.getMessage())));
}
}
List<BatchProgramResult> output = new ArrayList<>(programs.size());
// need to keep this index in case there is an exception getting the future, since we won't have the program
// information in that scenario
int i = 0;
for (ListenableFuture<BatchProgramResult> issuedStop : issuedStops) {
try {
output.add(issuedStop.get());
} catch (Throwable t) {
LOG.warn(t.getMessage(), t);
output.add(new BatchProgramResult(programs.get(i), HttpResponseStatus.INTERNAL_SERVER_ERROR.getCode(), t.getMessage()));
}
i++;
}
responder.sendJson(HttpResponseStatus.OK, output);
}
use of co.cask.cdap.proto.BatchProgram in project cdap by caskdata.
the class ProgramClientTestRun method testAll.
@Test
public void testAll() throws Exception {
NamespaceId namespace = NamespaceId.DEFAULT;
ApplicationId app = namespace.app(FakeApp.NAME);
FlowId flow = app.flow(FakeFlow.NAME);
FlowletId flowlet = flow.flowlet(FakeFlow.FLOWLET_NAME);
appClient.deploy(namespace, createAppJarFile(FakeApp.class));
try {
// start, scale, and stop flow
verifyProgramNames(FakeApp.FLOWS, appClient.listPrograms(app, ProgramType.FLOW));
LOG.info("Starting flow");
programClient.start(flow);
assertProgramRunning(programClient, flow);
LOG.info("Getting flow history");
programClient.getAllProgramRuns(flow, 0, Long.MAX_VALUE, Integer.MAX_VALUE);
LOG.info("Scaling flowlet");
Assert.assertEquals(1, programClient.getFlowletInstances(flowlet));
programClient.setFlowletInstances(flowlet, 3);
assertFlowletInstances(programClient, flowlet, 3);
List<BatchProgram> statusRequest = new ArrayList<>();
for (ProgramRecord programRecord : appClient.listPrograms(app)) {
statusRequest.add(BatchProgram.from(programRecord));
}
List<BatchProgramStatus> statuses = programClient.getStatus(namespace, statusRequest);
for (BatchProgramStatus status : statuses) {
if (status.getProgramType() == ProgramType.FLOW && status.getProgramId().equals(FakeFlow.NAME)) {
Assert.assertEquals("RUNNING", status.getStatus());
} else {
Assert.assertEquals("STOPPED", status.getStatus());
}
}
LOG.info("Stopping flow");
programClient.stop(flow);
assertProgramStopped(programClient, flow);
LOG.info("Starting flow with debug");
programClient.start(flow, true);
assertProgramRunning(programClient, flow);
programClient.stop(flow);
assertProgramStopped(programClient, flow);
} finally {
try {
appClient.delete(app);
} catch (Exception e) {
LOG.error("Error deleting app {} during test cleanup.", app, e);
}
}
}
Aggregations