use of io.cdap.cdap.proto.ProgramHistory in project cdap by caskdata.
the class DefaultStore method getRuns.
@Override
public List<ProgramHistory> getRuns(Collection<ProgramId> programs, ProgramRunStatus status, long startTime, long endTime, int limitPerProgram) {
return TransactionRunners.run(transactionRunner, context -> {
List<ProgramHistory> result = new ArrayList<>(programs.size());
AppMetadataStore appMetadataStore = getAppMetadataStore(context);
Set<ProgramId> existingPrograms = appMetadataStore.filterProgramsExistence(programs);
for (ProgramId programId : programs) {
if (!existingPrograms.contains(programId)) {
result.add(new ProgramHistory(programId, Collections.emptyList(), new ProgramNotFoundException(programId)));
continue;
}
List<RunRecord> runs = appMetadataStore.getRuns(programId, status, startTime, endTime, limitPerProgram, null).values().stream().map(record -> RunRecord.builder(record).build()).collect(Collectors.toList());
result.add(new ProgramHistory(programId, runs, null));
}
return result;
});
}
use of io.cdap.cdap.proto.ProgramHistory 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.ProgramHistory in project cdap by caskdata.
the class ProgramLifecycleService method getRunRecords.
/**
* Get the latest runs within the specified start and end times for the specified programs.
*
* @param programs the programs to get runs for
* @param programRunStatus status of runs to return
* @param start earliest start time of runs to return
* @param end latest start time of runs to return
* @param limit the maximum number of runs per program to return
* @return the latest runs for the program sorted by start time, with the newest run as the first run
* @throws NotFoundException if the application to which this program belongs was not found or the program is not
* found in the app
* @throws UnauthorizedException if the principal does not have access to the program
* @throws Exception if there was some other exception performing authorization checks
*/
public List<ProgramHistory> getRunRecords(Collection<ProgramId> programs, ProgramRunStatus programRunStatus, long start, long end, int limit) throws Exception {
List<ProgramHistory> result = new ArrayList<>();
// do this in batches to avoid transaction timeouts.
List<ProgramId> batch = new ArrayList<>(20);
for (ProgramId program : programs) {
batch.add(program);
if (batch.size() >= 20) {
addProgramHistory(result, batch, programRunStatus, start, end, limit);
batch.clear();
}
}
if (!batch.isEmpty()) {
addProgramHistory(result, batch, programRunStatus, start, end, limit);
}
return result;
}
use of io.cdap.cdap.proto.ProgramHistory 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);
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);
ProgramRunStatus runStatus = (status == null) ? ProgramRunStatus.ALL : ProgramRunStatus.valueOf(status.toUpperCase());
List<RunRecord> records = lifecycleService.getRunRecords(program, runStatus, start, end, resultLimit).stream().filter(record -> !isTetheredRunRecord(record)).collect(Collectors.toList());
responder.sendJson(HttpResponseStatus.OK, GSON.toJson(records));
}
Aggregations