use of io.cdap.cdap.app.program.ProgramDescriptor in project cdap by cdapio.
the class CapabilityManagementServiceTest method testProgramStart.
@Test
public void testProgramStart() throws Exception {
String externalConfigPath = tmpFolder.newFolder("capability-config-program").getAbsolutePath();
cConfiguration.set(Constants.Capability.CONFIG_DIR, externalConfigPath);
String appName = CapabilitySleepingWorkflowApp.NAME;
Class<CapabilitySleepingWorkflowApp> appClass = CapabilitySleepingWorkflowApp.class;
String version = "1.0.0";
String namespace = "default";
// deploy the artifact
deployTestArtifact(namespace, appName, version, appClass);
// enable a capability with no system apps and programs
CapabilityConfig enabledConfig = new CapabilityConfig("Enable healthcare", CapabilityStatus.ENABLED, "healthcare", Collections.emptyList(), Collections.emptyList(), Collections.emptyList());
writeConfigAsFile(externalConfigPath, enabledConfig.getCapability(), enabledConfig);
capabilityManagementService.runTask();
String capability = enabledConfig.getCapability();
capabilityStatusStore.checkAllEnabled(Collections.singleton(capability));
// deploy an app with this capability and start a workflow
ApplicationId applicationId = new ApplicationId(namespace, appName);
Id.Artifact artifactId = Id.Artifact.from(new Id.Namespace(namespace), appName, version);
ApplicationWithPrograms applicationWithPrograms = applicationLifecycleService.deployApp(new NamespaceId(namespace), appName, null, artifactId, null, op -> {
});
Iterable<ProgramDescriptor> programs = applicationWithPrograms.getPrograms();
for (ProgramDescriptor program : programs) {
programLifecycleService.start(program.getProgramId(), new HashMap<>(), false, false);
}
ProgramId programId = new ProgramId(applicationId, ProgramType.WORKFLOW, CapabilitySleepingWorkflowApp.SleepWorkflow.class.getSimpleName());
// Capability management service might not yet have deployed application.
// So wait till program exists and is in running state.
waitState(programId, "RUNNING");
assertProgramRuns(programId, ProgramRunStatus.RUNNING, 1);
// disable the capability - the program that was started should stop
CapabilityConfig disabledConfig = new CapabilityConfig("Disable healthcare", CapabilityStatus.DISABLED, "healthcare", Collections.emptyList(), Collections.emptyList(), Collections.emptyList());
writeConfigAsFile(externalConfigPath, capability, disabledConfig);
capabilityManagementService.runTask();
assertProgramRuns(programId, ProgramRunStatus.KILLED, 1);
assertProgramRuns(programId, ProgramRunStatus.RUNNING, 0);
try {
capabilityStatusStore.checkAllEnabled(Collections.singleton(capability));
Assert.fail("expecting exception");
} catch (CapabilityNotAvailableException ex) {
}
// try starting programs
for (ProgramDescriptor program : programs) {
try {
programLifecycleService.start(program.getProgramId(), new HashMap<>(), false, false);
Assert.fail("expecting exception");
} catch (CapabilityNotAvailableException ex) {
// expecting exception
}
}
new File(externalConfigPath, capability).delete();
capabilityManagementService.runTask();
Assert.assertTrue(capabilityStatusStore.getConfigs(Collections.singleton(capability)).isEmpty());
}
use of io.cdap.cdap.app.program.ProgramDescriptor in project cdap by cdapio.
the class ProgramGenerationStage method process.
@Override
public void process(final ApplicationDeployable input) throws Exception {
List<ProgramDescriptor> programDescriptors = new ArrayList<>();
final ApplicationSpecification appSpec = input.getSpecification();
// Now, we iterate through all ProgramSpecification and generate programs
Iterable<ProgramSpecification> specifications = Iterables.concat(appSpec.getMapReduce().values(), appSpec.getWorkflows().values(), appSpec.getServices().values(), appSpec.getSpark().values(), appSpec.getWorkers().values());
for (ProgramSpecification spec : specifications) {
ProgramType type = ProgramTypes.fromSpecification(spec);
ProgramId programId = input.getApplicationId().program(type, spec.getName());
programDescriptors.add(new ProgramDescriptor(programId, appSpec));
}
emit(new ApplicationWithPrograms(input, programDescriptors));
}
use of io.cdap.cdap.app.program.ProgramDescriptor in project cdap by cdapio.
the class ProgramNotificationSubscriberServiceTest method testWorkflowInnerPrograms.
@Test
public void testWorkflowInnerPrograms() throws Exception {
AppFabricTestHelper.deployApplication(Id.Namespace.DEFAULT, ProgramStateWorkflowApp.class, null, cConf);
ProgramRunId workflowRunId = NamespaceId.DEFAULT.app(ProgramStateWorkflowApp.class.getSimpleName()).workflow(ProgramStateWorkflowApp.ProgramStateWorkflow.class.getSimpleName()).run(RunIds.generate());
ApplicationSpecification appSpec = TransactionRunners.run(transactionRunner, context -> {
return AppMetadataStore.create(context).getApplication(workflowRunId.getParent().getParent()).getSpec();
});
ProgramDescriptor programDescriptor = new ProgramDescriptor(workflowRunId.getParent(), appSpec);
// Start and run the workflow
Map<String, String> systemArgs = new HashMap<>();
systemArgs.put(ProgramOptionConstants.SKIP_PROVISIONING, Boolean.TRUE.toString());
systemArgs.put(SystemArguments.PROFILE_NAME, ProfileId.NATIVE.getScopedName());
programStateWriter.start(workflowRunId, new SimpleProgramOptions(workflowRunId.getParent(), new BasicArguments(systemArgs), new BasicArguments()), null, programDescriptor);
programStateWriter.running(workflowRunId, null);
ProgramRunId mrRunId = workflowRunId.getParent().getParent().mr(ProgramStateWorkflowApp.ProgramStateMR.class.getSimpleName()).run(RunIds.generate());
ProgramRunId sparkRunId = workflowRunId.getParent().getParent().spark(ProgramStateWorkflowApp.ProgramStateSpark.class.getSimpleName()).run(RunIds.generate());
ProgramId sparkId2 = workflowRunId.getParent().getParent().spark(ProgramStateWorkflowApp.ProgramStateSpark2.class.getSimpleName());
// Start and run the MR and Spark inside
for (ProgramRunId programRunId : Arrays.asList(mrRunId, sparkRunId)) {
workflowStateWriter.addWorkflowNodeState(workflowRunId, new WorkflowNodeStateDetail(programRunId.getProgram(), NodeStatus.STARTING));
workflowStateWriter.addWorkflowNodeState(workflowRunId, new WorkflowNodeStateDetail(programRunId.getProgram(), NodeStatus.RUNNING));
systemArgs = new HashMap<>(systemArgs);
systemArgs.put(ProgramOptionConstants.RUN_ID, programRunId.getRun());
systemArgs.put(ProgramOptionConstants.WORKFLOW_NAME, workflowRunId.getProgram());
systemArgs.put(ProgramOptionConstants.WORKFLOW_RUN_ID, workflowRunId.getRun());
systemArgs.put(ProgramOptionConstants.WORKFLOW_NODE_ID, programRunId.getProgram());
systemArgs.put(ProgramOptionConstants.PROGRAM_NAME_IN_WORKFLOW, programRunId.getProgram());
programStateWriter.start(programRunId, new SimpleProgramOptions(programRunId.getParent(), new BasicArguments(systemArgs), new BasicArguments()), null, programDescriptor);
programStateWriter.running(programRunId, null);
// Wait for the inner program running
Tasks.waitFor(ProgramRunStatus.RUNNING, () -> TransactionRunners.run(transactionRunner, context -> {
AppMetadataStore metadataStoreDataset = AppMetadataStore.create(context);
RunRecordDetail meta = metadataStoreDataset.getRun(programRunId);
if (meta == null) {
return null;
}
return meta.getStatus();
}), 10, TimeUnit.SECONDS);
}
// Stop the Spark normally
programStateWriter.completed(sparkRunId);
// Error out the Workflow without stopping the MR
programStateWriter.error(workflowRunId, new IllegalStateException("Explicitly error out"));
// Wait for the Workflow state changed to failed
Tasks.waitFor(ProgramRunStatus.FAILED, () -> TransactionRunners.run(transactionRunner, context -> {
AppMetadataStore metadataStoreDataset = AppMetadataStore.create(context);
RunRecordDetail meta = metadataStoreDataset.getRun(workflowRunId);
if (meta == null) {
return null;
}
return meta.getStatus();
}), 10000, TimeUnit.SECONDS);
// The MR run record should be changed to ERROR state as well (without race)
TransactionRunners.run(transactionRunner, context -> {
AppMetadataStore metadataStoreDataset = AppMetadataStore.create(context);
RunRecordDetail meta = metadataStoreDataset.getRun(mrRunId);
Assert.assertNotNull(meta);
Assert.assertEquals(ProgramRunStatus.FAILED, meta.getStatus());
});
// The Spark run record should stay as COMPLETED
TransactionRunners.run(transactionRunner, context -> {
AppMetadataStore metadataStoreDataset = AppMetadataStore.create(context);
RunRecordDetail meta = metadataStoreDataset.getRun(sparkRunId);
Assert.assertNotNull(meta);
Assert.assertEquals(ProgramRunStatus.COMPLETED, meta.getStatus());
});
// Since the Spark2 program hasn't been executed, there should be no run record
TransactionRunners.run(transactionRunner, context -> {
AppMetadataStore metadataStoreDataset = AppMetadataStore.create(context);
Map<ProgramRunId, RunRecordDetail> runs = metadataStoreDataset.getRuns(sparkId2, ProgramRunStatus.ALL, 0, Long.MAX_VALUE, 100, null);
Assert.assertTrue(runs.isEmpty());
});
}
use of io.cdap.cdap.app.program.ProgramDescriptor in project cdap by cdapio.
the class ProgramNotificationSubscriberServiceTest method testHeartBeatStoreForProgramStatusMessages.
@Test
public void testHeartBeatStoreForProgramStatusMessages() throws Exception {
ProgramId programId = NamespaceId.DEFAULT.app("someapp", "1.0-SNAPSHOT").program(ProgramType.SERVICE, "s");
Map<String, String> systemArguments = new HashMap<>();
systemArguments.put(ProgramOptionConstants.SKIP_PROVISIONING, Boolean.TRUE.toString());
systemArguments.put(SystemArguments.PROFILE_NAME, ProfileId.NATIVE.getScopedName());
ProgramOptions programOptions = new SimpleProgramOptions(programId, new BasicArguments(systemArguments), new BasicArguments());
ProgramRunId runId = programId.run(RunIds.generate());
ArtifactId artifactId = NamespaceId.DEFAULT.artifact("testArtifact", "1.0").toApiArtifactId();
ApplicationSpecification appSpec = new DefaultApplicationSpecification("name", "1.0.0", ProjectInfo.getVersion().toString(), "desc", null, artifactId, Collections.emptyMap(), Collections.emptyMap(), Collections.emptyMap(), Collections.emptyMap(), Collections.emptyMap(), Collections.emptyMap(), Collections.emptyMap(), Collections.emptyMap(), Collections.emptyMap());
ProgramDescriptor programDescriptor = new ProgramDescriptor(programId, appSpec);
TransactionRunners.run(transactionRunner, context -> {
programStateWriter.start(runId, programOptions, null, programDescriptor);
});
checkProgramStatus(artifactId, runId, ProgramRunStatus.STARTING);
long startTime = System.currentTimeMillis();
TransactionRunners.run(transactionRunner, context -> {
programStateWriter.running(runId, null);
});
// perform scan on heart beat store - ensure latest message notification is running
checkProgramStatus(artifactId, runId, ProgramRunStatus.RUNNING);
heartbeatDatasetStatusCheck(startTime, ProgramRunStatus.RUNNING);
long suspendTime = System.currentTimeMillis();
TransactionRunners.run(transactionRunner, context -> {
programStateWriter.suspend(runId);
});
// perform scan on heart beat store - ensure latest message notification is suspended
checkProgramStatus(artifactId, runId, ProgramRunStatus.SUSPENDED);
heartbeatDatasetStatusCheck(suspendTime, ProgramRunStatus.SUSPENDED);
long resumeTime = System.currentTimeMillis();
TransactionRunners.run(transactionRunner, context -> {
programStateWriter.resume(runId);
});
// app metadata records as RUNNING
checkProgramStatus(artifactId, runId, ProgramRunStatus.RUNNING);
// heart beat messages wont have been sent due to high interval. resuming program will be recorded as running
// in run record by app meta
heartbeatDatasetStatusCheck(resumeTime, ProgramRunStatus.RUNNING);
// killed status check after error
long stopTime = System.currentTimeMillis();
TransactionRunners.run(transactionRunner, context -> {
programStateWriter.error(runId, new Throwable("Testing"));
});
checkProgramStatus(artifactId, runId, ProgramRunStatus.FAILED);
heartbeatDatasetStatusCheck(stopTime, ProgramRunStatus.FAILED);
ProgramRunId runId2 = programId.run(RunIds.generate());
TransactionRunners.run(transactionRunner, context -> {
programStateWriter.start(runId2, programOptions, null, programDescriptor);
});
checkProgramStatus(artifactId, runId2, ProgramRunStatus.STARTING);
startTime = System.currentTimeMillis();
TransactionRunners.run(transactionRunner, context -> {
programStateWriter.running(runId2, null);
});
// perform scan on heart beat store - ensure latest message notification is running
checkProgramStatus(artifactId, runId2, ProgramRunStatus.RUNNING);
heartbeatDatasetStatusCheck(startTime, ProgramRunStatus.RUNNING);
// completed status check
stopTime = System.currentTimeMillis();
TransactionRunners.run(transactionRunner, context -> {
programStateWriter.completed(runId2);
});
checkProgramStatus(artifactId, runId2, ProgramRunStatus.COMPLETED);
heartbeatDatasetStatusCheck(stopTime, ProgramRunStatus.COMPLETED);
ProgramRunId runId3 = programId.run(RunIds.generate());
TransactionRunners.run(transactionRunner, context -> {
programStateWriter.start(runId3, programOptions, null, programDescriptor);
});
checkProgramStatus(artifactId, runId3, ProgramRunStatus.STARTING);
startTime = System.currentTimeMillis();
TransactionRunners.run(transactionRunner, context -> {
programStateWriter.running(runId3, null);
});
// perform scan on heart beat store - ensure latest message notification is running
checkProgramStatus(artifactId, runId3, ProgramRunStatus.RUNNING);
heartbeatDatasetStatusCheck(startTime, ProgramRunStatus.RUNNING);
// completed status check
stopTime = System.currentTimeMillis();
TransactionRunners.run(transactionRunner, context -> {
programStateWriter.stop(runId3, 10);
});
checkProgramStatus(artifactId, runId3, ProgramRunStatus.STOPPING);
heartbeatDatasetStatusCheck(stopTime, ProgramRunStatus.STOPPING);
}
use of io.cdap.cdap.app.program.ProgramDescriptor in project cdap by cdapio.
the class ProgramNotificationSubscriberServiceTest method testAppSpecNotRequiredToWriteState.
@Test
public void testAppSpecNotRequiredToWriteState() throws Exception {
ProgramId programId = NamespaceId.DEFAULT.app("someapp").program(ProgramType.SERVICE, "s");
Map<String, String> systemArguments = new HashMap<>();
systemArguments.put(ProgramOptionConstants.SKIP_PROVISIONING, Boolean.TRUE.toString());
systemArguments.put(SystemArguments.PROFILE_NAME, ProfileId.NATIVE.getScopedName());
ProgramOptions programOptions = new SimpleProgramOptions(programId, new BasicArguments(systemArguments), new BasicArguments());
ProgramRunId runId = programId.run(RunIds.generate());
ArtifactId artifactId = NamespaceId.DEFAULT.artifact("testArtifact", "1.0").toApiArtifactId();
ApplicationSpecification appSpec = new DefaultApplicationSpecification("name", "1.0.0", ProjectInfo.getVersion().toString(), "desc", null, artifactId, Collections.emptyMap(), Collections.emptyMap(), Collections.emptyMap(), Collections.emptyMap(), Collections.emptyMap(), Collections.emptyMap(), Collections.emptyMap(), Collections.emptyMap(), Collections.emptyMap());
ProgramDescriptor programDescriptor = new ProgramDescriptor(programId, appSpec);
programStateWriter.start(runId, programOptions, null, programDescriptor);
Tasks.waitFor(ProgramRunStatus.STARTING, () -> TransactionRunners.run(transactionRunner, context -> {
AppMetadataStore metadataStoreDataset = AppMetadataStore.create(context);
RunRecordDetail meta = metadataStoreDataset.getRun(runId);
if (meta == null) {
return null;
}
Assert.assertEquals(artifactId, meta.getArtifactId());
return meta.getStatus();
}), 10, TimeUnit.SECONDS);
programStateWriter.completed(runId);
}
Aggregations