use of io.cdap.cdap.proto.BatchProgramHistory in project cdap by caskdata.
the class AppFabricTestBase method getProgramRuns.
protected List<BatchProgramHistory> getProgramRuns(NamespaceId namespace, List<ProgramId> programs) throws Exception {
List<BatchProgram> request = programs.stream().map(program -> new BatchProgram(program.getApplication(), program.getType(), program.getProgram())).collect(Collectors.toList());
HttpResponse response = doPost(getVersionedAPIPath("runs", namespace.getNamespace()), GSON.toJson(request));
assertResponseCode(200, response);
return GSON.fromJson(response.getResponseBodyAsString(), BATCH_PROGRAM_RUNS_TYPE);
}
use of io.cdap.cdap.proto.BatchProgramHistory in project cdap by caskdata.
the class ProgramLifecycleHttpHandler method getLatestRuns.
/**
* Returns the latest runs for all program runnables 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.
* <p>
* Example input:
* <pre><code>
* [{"appId": "App1", "programType": "Service", "programId": "Service1"},
* {"appId": "App1", "programType": "Workflow", "programId": "testWorkflow"},
* {"appId": "App2", "programType": "Workflow", "programId": "DataPipelineWorkflow"}]
* </code></pre>
* </p><p>
* </p><p>
* The response will be an array of JsonObjects each of which will contain the three input parameters
* as well as 2 fields, "runs" which is a list of the latest run records 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, workflow in app1 does not exist),
* then all JsonObjects for which the parameters have a valid status will have the count 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 workflow in App1 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, "runs": [...]},
* {"appId": "App1", "programType": "Workflow", "programId": "testWorkflow", "statusCode": 404,
* "error": "Program 'testWorkflow' is not found"},
* {"appId": "App2", "programType": "Workflow", "programId": "DataPipelineWorkflow", "runnableId": "Flowlet1",
* "statusCode": 200, "runs": [...]}]
* </code></pre>
*/
@POST
@Path("/runs")
public void getLatestRuns(FullHttpRequest request, HttpResponder responder, @PathParam("namespace-id") String namespaceId) throws Exception {
List<BatchProgram> programs = validateAndGetBatchInput(request, BATCH_PROGRAMS_TYPE);
List<ProgramId> programIds = programs.stream().map(batchProgram -> new ProgramId(namespaceId, batchProgram.getAppId(), batchProgram.getProgramType(), batchProgram.getProgramId())).collect(Collectors.toList());
List<BatchProgramHistory> response = new ArrayList<>(programs.size());
List<ProgramHistory> result = lifecycleService.getRunRecords(programIds, ProgramRunStatus.ALL, 0, Long.MAX_VALUE, 1);
for (ProgramHistory programHistory : result) {
ProgramId programId = programHistory.getProgramId();
Exception exception = programHistory.getException();
BatchProgram batchProgram = new BatchProgram(programId.getApplication(), programId.getType(), programId.getProgram());
if (exception == null) {
response.add(new BatchProgramHistory(batchProgram, HttpResponseStatus.OK.code(), null, programHistory.getRuns()));
} else if (exception instanceof NotFoundException) {
response.add(new BatchProgramHistory(batchProgram, HttpResponseStatus.NOT_FOUND.code(), exception.getMessage(), Collections.emptyList()));
} else if (exception instanceof UnauthorizedException) {
response.add(new BatchProgramHistory(batchProgram, HttpResponseStatus.FORBIDDEN.code(), exception.getMessage(), Collections.emptyList()));
} else {
response.add(new BatchProgramHistory(batchProgram, HttpResponseStatus.INTERNAL_SERVER_ERROR.code(), exception.getMessage(), Collections.emptyList()));
}
}
responder.sendJson(HttpResponseStatus.OK, GSON.toJson(response));
}
use of io.cdap.cdap.proto.BatchProgramHistory in project cdap by caskdata.
the class SupportBundleTestBase method getProgramRuns.
protected List<BatchProgramHistory> getProgramRuns(NamespaceId namespace, List<ProgramId> programs) throws Exception {
List<BatchProgram> request = programs.stream().map(program -> new BatchProgram(program.getApplication(), program.getType(), program.getProgram())).collect(Collectors.toList());
HttpResponse response = doPost(getVersionedAPIPath("runs", namespace.getNamespace()), GSON.toJson(request));
assertResponseCode(200, response);
return GSON.fromJson(response.getResponseBodyAsString(), BATCH_PROGRAM_RUNS_TYPE);
}
use of io.cdap.cdap.proto.BatchProgramHistory in project cdap by caskdata.
the class ProgramLifecycleHttpHandlerTest method testProgramStartStopStatus.
@Category(XSlowTests.class)
@Test
public void testProgramStartStopStatus() throws Exception {
// deploy, check the status
deploy(AllProgramsApp.class, 200, Constants.Gateway.API_VERSION_3_TOKEN, TEST_NAMESPACE1);
ProgramId serviceId1 = new ServiceId(TEST_NAMESPACE1, AllProgramsApp.NAME, AllProgramsApp.NoOpService.NAME);
ProgramId serviceId2 = new ServiceId(TEST_NAMESPACE2, AllProgramsApp.NAME, AllProgramsApp.NoOpService.NAME);
// service is stopped initially
Assert.assertEquals(STOPPED, getProgramStatus(serviceId1));
// start service in the wrong namespace and verify that it does not start
startProgram(serviceId2, 404);
// start a service and check the status
startProgram(serviceId1);
waitState(serviceId1, RUNNING);
// stop the service and check the status
stopProgram(serviceId1);
waitState(serviceId1, STOPPED);
// deploy another app in a different namespace and verify
deploy(DummyAppWithTrackingTable.class, 200, Constants.Gateway.API_VERSION_3_TOKEN, TEST_NAMESPACE2);
Id.Program dummyMR1 = Id.Program.from(TEST_NAMESPACE1, DUMMY_APP_ID, ProgramType.MAPREDUCE, DUMMY_MR_NAME);
Id.Program dummyMR2 = Id.Program.from(TEST_NAMESPACE2, DUMMY_APP_ID, ProgramType.MAPREDUCE, DUMMY_MR_NAME);
// mapreduce is stopped initially
Assert.assertEquals(STOPPED, getProgramStatus(dummyMR2));
// start mapreduce in the wrong namespace and verify it does not start
startProgram(dummyMR1, 404);
Assert.assertEquals(STOPPED, getProgramStatus(dummyMR2));
// start map-reduce and verify status
startProgram(dummyMR2);
waitState(dummyMR2, RUNNING);
// stop the mapreduce program and check the status
stopProgram(dummyMR2);
waitState(dummyMR2, STOPPED);
// start multiple runs of the map-reduce program
startProgram(dummyMR2);
startProgram(dummyMR2);
verifyProgramRuns(dummyMR2, ProgramRunStatus.RUNNING, 1);
// stop all runs of the map-reduce program
stopProgram(dummyMR2, 200);
waitState(dummyMR2, STOPPED);
// deploy an app containing a workflow
deploy(SleepingWorkflowApp.class, 200, Constants.Gateway.API_VERSION_3_TOKEN, TEST_NAMESPACE2);
Id.Program sleepWorkflow1 = Id.Program.from(TEST_NAMESPACE1, SLEEP_WORKFLOW_APP_ID, ProgramType.WORKFLOW, SLEEP_WORKFLOW_NAME);
Id.Program sleepWorkflow2 = Id.Program.from(TEST_NAMESPACE2, SLEEP_WORKFLOW_APP_ID, ProgramType.WORKFLOW, SLEEP_WORKFLOW_NAME);
// workflow is stopped initially
Assert.assertEquals(STOPPED, getProgramStatus(sleepWorkflow2));
// start workflow in the wrong namespace and verify that it does not start
startProgram(sleepWorkflow1, 404);
Assert.assertEquals(STOPPED, getProgramStatus(sleepWorkflow2));
// start workflow and check status
startProgram(sleepWorkflow2);
waitState(sleepWorkflow2, RUNNING);
// workflow will stop itself
waitState(sleepWorkflow2, STOPPED);
// start multiple runs of the workflow
startProgram(sleepWorkflow2, ImmutableMap.of("sleep.ms", "5000"));
startProgram(sleepWorkflow2, ImmutableMap.of("sleep.ms", "5000"));
verifyProgramRuns(sleepWorkflow2, ProgramRunStatus.RUNNING, 1);
List<RunRecord> runs = getProgramRuns(sleepWorkflow2, ProgramRunStatus.RUNNING);
Assert.assertEquals(2, runs.size());
stopProgram(sleepWorkflow2, runs.get(0).getPid(), 200);
stopProgram(sleepWorkflow2, runs.get(1).getPid(), 200);
waitState(sleepWorkflow2, STOPPED);
long startTime = TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis());
// Set super long sleep so we can suspend the workflow ourselves.
startProgram(sleepWorkflow2, ImmutableMap.of("sleep.ms", "500000"));
waitState(sleepWorkflow2, RUNNING);
stopProgram(sleepWorkflow2);
waitState(sleepWorkflow2, STOPPED);
long endTime = TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis()) + 1;
// sleepWorkflow2 should be restarted
restartPrograms(new ApplicationId(TEST_NAMESPACE2, SLEEP_WORKFLOW_APP_ID), startTime, endTime);
waitState(sleepWorkflow2, RUNNING);
stopProgram(sleepWorkflow2);
waitState(sleepWorkflow2, STOPPED);
// verify batch runs endpoint
List<ProgramId> programs = ImmutableList.of(sleepWorkflow2.toEntityId(), dummyMR2.toEntityId(), serviceId2);
List<BatchProgramHistory> batchRuns = getProgramRuns(new NamespaceId(TEST_NAMESPACE2), programs);
BatchProgramHistory sleepRun = batchRuns.get(0);
BatchProgramHistory dummyMR2Run = batchRuns.get(1);
BatchProgramHistory service2Run = batchRuns.get(2);
// verify results come back in order
Assert.assertEquals(sleepWorkflow2.getId(), sleepRun.getProgramId());
Assert.assertEquals(dummyMR2.getId(), dummyMR2Run.getProgramId());
Assert.assertEquals(serviceId2.getProgram(), service2Run.getProgramId());
// verify status. AllProgramsApp was never deployed in NS2 and should not exist
Assert.assertEquals(200, sleepRun.getStatusCode());
Assert.assertEquals(200, dummyMR2Run.getStatusCode());
Assert.assertEquals(404, service2Run.getStatusCode());
// verify the run record is correct
RunRecord runRecord = getProgramRuns(sleepWorkflow2, ProgramRunStatus.ALL).iterator().next();
Assert.assertEquals(runRecord.getPid(), sleepRun.getRuns().iterator().next().getPid());
runRecord = getProgramRuns(dummyMR2, ProgramRunStatus.ALL).iterator().next();
Assert.assertEquals(runRecord.getPid(), dummyMR2Run.getRuns().iterator().next().getPid());
Assert.assertTrue(service2Run.getRuns().isEmpty());
// cleanup
HttpResponse response = doDelete(getVersionedAPIPath("apps/", Constants.Gateway.API_VERSION_3_TOKEN, TEST_NAMESPACE1));
Assert.assertEquals(200, response.getResponseCode());
response = doDelete(getVersionedAPIPath("apps/", Constants.Gateway.API_VERSION_3_TOKEN, TEST_NAMESPACE2));
Assert.assertEquals(200, response.getResponseCode());
}
Aggregations