use of io.cdap.cdap.internal.app.runtime.BasicArguments in project cdap by caskdata.
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);
}
use of io.cdap.cdap.internal.app.runtime.BasicArguments in project cdap by caskdata.
the class WorkerProgramRunnerTest method startProgram.
private ProgramController startProgram(ApplicationWithPrograms app, Class<?> programClass) throws Throwable {
final AtomicReference<Throwable> errorCause = new AtomicReference<>();
final ProgramController controller = AppFabricTestHelper.submit(app, programClass.getName(), new BasicArguments(), TEMP_FOLDER_SUPPLIER);
runningPrograms.add(controller);
controller.addListener(new AbstractListener() {
@Override
public void error(Throwable cause) {
errorCause.set(cause);
}
@Override
public void killed() {
errorCause.set(new RuntimeException("Killed"));
}
}, Threads.SAME_THREAD_EXECUTOR);
return controller;
}
use of io.cdap.cdap.internal.app.runtime.BasicArguments in project cdap by caskdata.
the class SystemProgramManagementServiceTest method testIteration.
@Test
public void testIteration() throws Exception {
// deploy app to test as a system service
deployTestApp();
// Set this app as an enabled service
ApplicationId applicationId = new ApplicationId(NAMESPACE, APP_NAME, VERSION);
ProgramId programId = new ProgramId(applicationId, ProgramType.WORKFLOW, PROGRAM_NAME);
Map<ProgramId, Arguments> enabledServices = new HashMap<>();
enabledServices.put(programId, new BasicArguments(new HashMap<>()));
progmMgmtSvc.setProgramsEnabled(enabledServices);
// run one iteration of programManagementService. The program should start
progmMgmtSvc.runTask();
waitState(programId, ProgramStatus.RUNNING.name());
assertProgramRuns(programId, ProgramRunStatus.RUNNING, 1);
// Remove this app as an enabled service , program should stop
progmMgmtSvc.setProgramsEnabled(new HashMap<>());
progmMgmtSvc.runTask();
waitState(programId, ProgramStatus.STOPPED.name());
Assert.assertEquals(ProgramStatus.STOPPED.name(), getProgramStatus(programId));
assertProgramRuns(programId, ProgramRunStatus.RUNNING, 0);
// Run the program manually twice to test pruning. One run should be killed
programLifecycleService.start(programId, new HashMap<>(), false, false);
programLifecycleService.start(programId, new HashMap<>(), false, false);
assertProgramRuns(programId, ProgramRunStatus.RUNNING, 2);
progmMgmtSvc.setProgramsEnabled(enabledServices);
progmMgmtSvc.runTask();
assertProgramRuns(programId, ProgramRunStatus.KILLED, 2);
assertProgramRuns(programId, ProgramRunStatus.RUNNING, 1);
}
use of io.cdap.cdap.internal.app.runtime.BasicArguments in project cdap by cdapio.
the class DefaultRuntimeJob method run.
@Override
public void run(RuntimeJobEnvironment runtimeJobEnv) throws Exception {
// Setup process wide settings
Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler());
SLF4JBridgeHandler.removeHandlersForRootLogger();
SLF4JBridgeHandler.install();
// Get Program Options
ProgramOptions programOpts = readJsonFile(new File(DistributedProgramRunner.PROGRAM_OPTIONS_FILE_NAME), ProgramOptions.class);
ProgramRunId programRunId = programOpts.getProgramId().run(ProgramRunners.getRunId(programOpts));
ProgramId programId = programRunId.getParent();
Arguments systemArgs = programOpts.getArguments();
// Setup logging context for the program
LoggingContextAccessor.setLoggingContext(LoggingContextHelper.getLoggingContextWithRunId(programRunId, systemArgs.asMap()));
// Get the cluster launch type
Cluster cluster = GSON.fromJson(systemArgs.getOption(ProgramOptionConstants.CLUSTER), Cluster.class);
// Get App spec
ApplicationSpecification appSpec = readJsonFile(new File(DistributedProgramRunner.APP_SPEC_FILE_NAME), ApplicationSpecification.class);
ProgramDescriptor programDescriptor = new ProgramDescriptor(programId, appSpec);
// Create injector and get program runner
Injector injector = Guice.createInjector(createModules(runtimeJobEnv, createCConf(runtimeJobEnv, programOpts), programRunId, programOpts));
CConfiguration cConf = injector.getInstance(CConfiguration.class);
// Initialize log appender
LogAppenderInitializer logAppenderInitializer = injector.getInstance(LogAppenderInitializer.class);
logAppenderInitializer.initialize();
SystemArguments.setLogLevel(programOpts.getUserArguments(), logAppenderInitializer);
ProxySelector oldProxySelector = ProxySelector.getDefault();
RuntimeMonitors.setupMonitoring(injector, programOpts);
Deque<Service> coreServices = createCoreServices(injector, systemArgs, cluster);
startCoreServices(coreServices);
// regenerate app spec
ConfiguratorFactory configuratorFactory = injector.getInstance(ConfiguratorFactory.class);
try {
Map<String, String> systemArguments = new HashMap<>(programOpts.getArguments().asMap());
File pluginDir = new File(programOpts.getArguments().getOption(ProgramOptionConstants.PLUGIN_DIR, DistributedProgramRunner.PLUGIN_DIR));
// create a directory to store plugin artifacts for the regeneration of app spec to fetch plugin artifacts
DirUtils.mkdirs(pluginDir);
if (!programOpts.getArguments().hasOption(ProgramOptionConstants.PLUGIN_DIR)) {
systemArguments.put(ProgramOptionConstants.PLUGIN_DIR, DistributedProgramRunner.PLUGIN_DIR);
}
// remember the file names in the artifact folder before app regeneration
List<String> pluginFiles = DirUtils.listFiles(pluginDir, File::isFile).stream().map(File::getName).collect(Collectors.toList());
ApplicationSpecification generatedAppSpec = regenerateAppSpec(systemArguments, programOpts.getUserArguments().asMap(), programId, appSpec, programDescriptor, configuratorFactory);
appSpec = generatedAppSpec != null ? generatedAppSpec : appSpec;
programDescriptor = new ProgramDescriptor(programDescriptor.getProgramId(), appSpec);
List<String> pluginFilesAfter = DirUtils.listFiles(pluginDir, File::isFile).stream().map(File::getName).collect(Collectors.toList());
if (pluginFilesAfter.isEmpty()) {
systemArguments.remove(ProgramOptionConstants.PLUGIN_DIR);
}
// recreate it from the folders
if (!pluginFiles.equals(pluginFilesAfter)) {
systemArguments.remove(ProgramOptionConstants.PLUGIN_ARCHIVE);
}
// update program options
programOpts = new SimpleProgramOptions(programOpts.getProgramId(), new BasicArguments(systemArguments), programOpts.getUserArguments(), programOpts.isDebug());
} catch (Exception e) {
LOG.warn("Failed to regenerate the app spec for program {}, using the existing app spec", programId, e);
}
ProgramStateWriter programStateWriter = injector.getInstance(ProgramStateWriter.class);
RuntimeClientService runtimeClientService = injector.getInstance(RuntimeClientService.class);
CompletableFuture<ProgramController.State> programCompletion = new CompletableFuture<>();
try {
ProgramRunner programRunner = injector.getInstance(ProgramRunnerFactory.class).create(programId.getType());
// Create and run the program. The program files should be present in current working directory.
try (Program program = createProgram(cConf, programRunner, programDescriptor, programOpts)) {
ProgramController controller = programRunner.run(program, programOpts);
controllerFuture.complete(controller);
runtimeClientService.onProgramStopRequested(controller::stop);
controller.addListener(new AbstractListener() {
@Override
public void completed() {
programCompletion.complete(ProgramController.State.COMPLETED);
}
@Override
public void killed() {
// Write an extra state to make sure there is always a terminal state even
// if the program application run failed to write out the state.
programStateWriter.killed(programRunId);
programCompletion.complete(ProgramController.State.KILLED);
}
@Override
public void error(Throwable cause) {
// Write an extra state to make sure there is always a terminal state even
// if the program application run failed to write out the state.
programStateWriter.error(programRunId, cause);
programCompletion.completeExceptionally(cause);
}
}, Threads.SAME_THREAD_EXECUTOR);
if (stopRequested) {
controller.stop();
}
// Block on the completion
programCompletion.get();
} finally {
if (programRunner instanceof Closeable) {
Closeables.closeQuietly((Closeable) programRunner);
}
}
} catch (Throwable t) {
controllerFuture.completeExceptionally(t);
if (!programCompletion.isDone()) {
// We log here so that the logs would still send back to the program logs collection.
// Only log if the program completion is not done.
// Otherwise the program runner itself should have logged the error.
LOG.error("Failed to execute program {}", programRunId, t);
// If the program completion is not done, then this exception
// is due to systematic failure in which fail to run the program.
// We write out an extra error state for the program to make sure the program state get transited.
programStateWriter.error(programRunId, t);
}
throw t;
} finally {
stopCoreServices(coreServices, logAppenderInitializer);
ProxySelector.setDefault(oldProxySelector);
Authenticator.setDefault(null);
runCompletedLatch.countDown();
}
}
use of io.cdap.cdap.internal.app.runtime.BasicArguments in project cdap by cdapio.
the class ProgramOptions method fromNotification.
/**
* Decodes {@link ProgramOptions} from a {@link Notification} object, based on the
* {@link Notification.Type#PROGRAM_STATUS} type.
*/
static ProgramOptions fromNotification(Notification notification, Gson gson) {
Map<String, String> properties = notification.getProperties();
ProgramId programId = gson.fromJson(properties.get(ProgramOptionConstants.PROGRAM_RUN_ID), ProgramRunId.class).getParent();
String userArgumentsString = properties.get(ProgramOptionConstants.USER_OVERRIDES);
String systemArgumentsString = properties.get(ProgramOptionConstants.SYSTEM_OVERRIDES);
String debugString = properties.get(ProgramOptionConstants.DEBUG_ENABLED);
Type stringStringMap = new TypeToken<Map<String, String>>() {
}.getType();
boolean debug = Boolean.parseBoolean(debugString);
Map<String, String> userArguments = userArgumentsString == null ? Collections.emptyMap() : gson.fromJson(userArgumentsString, stringStringMap);
Map<String, String> systemArguments = systemArgumentsString == null ? Collections.emptyMap() : gson.fromJson(systemArgumentsString, stringStringMap);
return new SimpleProgramOptions(programId, new BasicArguments(systemArguments), new BasicArguments(userArguments), debug);
}
Aggregations