use of co.cask.cdap.proto.ProgramRecord in project cdap by caskdata.
the class ProgramLifecycleHttpHandler method deleteQueues.
@DELETE
@Path("/queues")
public synchronized void deleteQueues(HttpRequest request, HttpResponder responder, @PathParam("namespace-id") String namespaceId) throws NamespaceNotFoundException {
// synchronized to avoid a potential race condition here:
// 1. the check for state returns that all flows are STOPPED
// 2. The API deletes queues because
// Between 1. and 2., a flow is started using the /namespaces/{namespace-id}/apps/{app-id}/flows/{flow-id}/start API
// Averting this race condition by synchronizing this method. The resource that needs to be locked here is
// runtimeService. This should work because the method that is used to start a flow - startStopProgram - is also
// synchronized on this.
// This synchronization works in HA mode because even in HA mode there is only one leader at a time.
NamespaceId namespace = validateAndGetNamespace(namespaceId);
try {
List<ProgramRecord> flows = lifecycleService.list(validateAndGetNamespace(namespaceId), ProgramType.FLOW);
for (ProgramRecord flow : flows) {
String appId = flow.getApp();
String flowId = flow.getName();
ProgramId programId = new ProgramId(namespaceId, appId, ProgramType.FLOW, flowId);
ProgramStatus status = lifecycleService.getProgramStatus(programId);
if (ProgramStatus.STOPPED != status) {
responder.sendString(HttpResponseStatus.FORBIDDEN, String.format("Flow '%s' from application '%s' in namespace '%s' is running, " + "please stop it first.", flowId, appId, namespaceId));
return;
}
}
queueAdmin.dropAllInNamespace(namespace);
// delete process metrics that are used to calculate the queue size (system.queue.pending metric)
FlowUtils.deleteFlowPendingMetrics(metricStore, namespaceId, null, null);
responder.sendStatus(HttpResponseStatus.OK);
} catch (Exception e) {
LOG.error("Error while deleting queues in namespace " + namespace, e);
responder.sendString(HttpResponseStatus.INTERNAL_SERVER_ERROR, e.getMessage());
}
}
use of co.cask.cdap.proto.ProgramRecord 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);
testWorkflowCommand(app.workflow(FakeWorkflow.NAME));
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);
}
}
}
use of co.cask.cdap.proto.ProgramRecord in project cdap by caskdata.
the class ProgramLifecycleHttpHandlerTest method verifyProgramList.
private void verifyProgramList(String namespace, String appName, final ProgramType programType, int expected) throws Exception {
HttpResponse response = requestAppDetail(namespace, appName);
Assert.assertEquals(200, response.getStatusLine().getStatusCode());
String json = EntityUtils.toString(response.getEntity());
ApplicationDetail appDetail = GSON.fromJson(json, ApplicationDetail.class);
Collection<ProgramRecord> programs = Collections2.filter(appDetail.getPrograms(), new Predicate<ProgramRecord>() {
@Override
public boolean apply(@Nullable ProgramRecord record) {
return programType.getCategoryName().equals(record.getType().getCategoryName());
}
});
Assert.assertEquals(expected, programs.size());
}
use of co.cask.cdap.proto.ProgramRecord in project cdap by caskdata.
the class ProgramLifecycleService method list.
/**
* Lists all programs with the specified program type in a namespace. If perimeter security and authorization are
* enabled, only returns the programs that the current user has access to.
*
* @param namespaceId the namespace to list datasets for
* @return the programs in the provided namespace
*/
public List<ProgramRecord> list(NamespaceId namespaceId, ProgramType type) throws Exception {
Collection<ApplicationSpecification> appSpecs = store.getAllApplications(namespaceId);
List<ProgramRecord> programRecords = new ArrayList<>();
for (ApplicationSpecification appSpec : appSpecs) {
switch(type) {
case FLOW:
createProgramRecords(namespaceId, appSpec.getName(), type, appSpec.getFlows().values(), programRecords);
break;
case MAPREDUCE:
createProgramRecords(namespaceId, appSpec.getName(), type, appSpec.getMapReduce().values(), programRecords);
break;
case SPARK:
createProgramRecords(namespaceId, appSpec.getName(), type, appSpec.getSpark().values(), programRecords);
break;
case SERVICE:
createProgramRecords(namespaceId, appSpec.getName(), type, appSpec.getServices().values(), programRecords);
break;
case WORKER:
createProgramRecords(namespaceId, appSpec.getName(), type, appSpec.getWorkers().values(), programRecords);
break;
case WORKFLOW:
createProgramRecords(namespaceId, appSpec.getName(), type, appSpec.getWorkflows().values(), programRecords);
break;
default:
throw new Exception("Unknown program type: " + type.name());
}
}
return programRecords;
}
use of co.cask.cdap.proto.ProgramRecord in project cdap by caskdata.
the class BaseBatchCommand method readArgs.
/**
* Reads arguments to get app id, program types, and list of input programs.
*/
protected Args<T> readArgs(Arguments arguments) throws ApplicationNotFoundException, UnauthenticatedException, IOException, UnauthorizedException {
String appName = arguments.get(ArgumentName.APP.getName());
ApplicationId appId = cliConfig.getCurrentNamespace().app(appName);
Set<ProgramType> programTypes = getDefaultProgramTypes();
if (arguments.hasArgument(ArgumentName.PROGRAM_TYPES.getName())) {
programTypes.clear();
String programTypesStr = arguments.get(ArgumentName.PROGRAM_TYPES.getName());
for (String programTypeStr : Splitter.on(',').trimResults().split(programTypesStr)) {
ProgramType programType = ProgramType.valueOf(programTypeStr.toUpperCase());
programTypes.add(programType);
}
}
List<T> programs = new ArrayList<>();
Map<ProgramType, List<ProgramRecord>> appPrograms = appClient.listProgramsByType(appId);
for (ProgramType programType : programTypes) {
List<ProgramRecord> programRecords = appPrograms.get(programType);
if (programRecords != null) {
for (ProgramRecord programRecord : programRecords) {
programs.add(createProgram(programRecord));
}
}
}
return new Args<>(appId, programTypes, programs);
}
Aggregations