use of co.cask.cdap.api.app.ApplicationSpecification in project cdap by caskdata.
the class WorkflowProgramRunner method run.
@Override
public ProgramController run(final Program program, final ProgramOptions options) {
// Extract and verify options
ApplicationSpecification appSpec = program.getApplicationSpecification();
Preconditions.checkNotNull(appSpec, "Missing application specification.");
ProgramType processorType = program.getType();
Preconditions.checkNotNull(processorType, "Missing processor type.");
Preconditions.checkArgument(processorType == ProgramType.WORKFLOW, "Only WORKFLOW process type is supported.");
WorkflowSpecification workflowSpec = appSpec.getWorkflows().get(program.getName());
Preconditions.checkNotNull(workflowSpec, "Missing WorkflowSpecification for %s", program.getName());
final RunId runId = ProgramRunners.getRunId(options);
// Setup dataset framework context, if required
if (datasetFramework instanceof ProgramContextAware) {
ProgramId programId = program.getId();
((ProgramContextAware) datasetFramework).setContext(new BasicProgramContext(programId.run(runId)));
}
// List of all Closeable resources that needs to be cleanup
final List<Closeable> closeables = new ArrayList<>();
try {
PluginInstantiator pluginInstantiator = createPluginInstantiator(options, program.getClassLoader());
if (pluginInstantiator != null) {
closeables.add(pluginInstantiator);
}
WorkflowDriver driver = new WorkflowDriver(program, options, workflowSpec, programRunnerFactory, metricsCollectionService, datasetFramework, discoveryServiceClient, txClient, runtimeStore, cConf, pluginInstantiator, secureStore, secureStoreManager, messagingService, programStateWriter);
// Controller needs to be created before starting the driver so that the state change of the driver
// service can be fully captured by the controller.
ProgramController controller = new WorkflowProgramController(program.getId().run(runId), driver);
driver.start();
return controller;
} catch (Exception e) {
closeAllQuietly(closeables);
throw Throwables.propagate(e);
}
}
use of co.cask.cdap.api.app.ApplicationSpecification in project cdap by caskdata.
the class ApplicationLifecycleService method deleteApp.
// deletes without performs checks that no programs are running
/**
* Delete the specified application without performing checks that its programs are stopped.
*
* @param appId the id of the application to delete
* @param spec the spec of the application to delete
* @throws Exception
*/
private void deleteApp(final ApplicationId appId, ApplicationSpecification spec) throws Exception {
// Delete the schedules
scheduler.deleteSchedules(appId);
for (WorkflowSpecification workflowSpec : spec.getWorkflows().values()) {
scheduler.modifySchedulesTriggeredByDeletedProgram(appId.workflow(workflowSpec.getName()));
}
deleteMetrics(appId);
// Delete all preferences of the application and of all its programs
deletePreferences(appId);
// Delete all streams and queues state of each flow
for (final FlowSpecification flowSpecification : spec.getFlows().values()) {
FlowUtils.clearDeletedFlow(impersonator, queueAdmin, streamConsumerFactory, appId.flow(flowSpecification.getName()), flowSpecification);
}
ApplicationSpecification appSpec = store.getApplication(appId);
deleteAppMetadata(appId, appSpec);
deleteRouteConfig(appId, appSpec);
store.deleteWorkflowStats(appId);
store.removeApplication(appId);
try {
// delete the owner as it has already been determined that this is the only version of the app
ownerAdmin.delete(appId);
} catch (Exception e) {
LOG.warn("Failed to delete app owner principal for application {} if one existed while deleting the " + "application.", appId);
}
try {
usageRegistry.unregister(appId);
} catch (Exception e) {
LOG.warn("Failed to unregister usage of app: {}", appId, e);
}
}
use of co.cask.cdap.api.app.ApplicationSpecification in project cdap by caskdata.
the class ApplicationLifecycleService method getPlugins.
/**
* Get detail about the plugin in the specified application
*
* @param appId the id of the application
* @return list of plugins in the application
* @throws ApplicationNotFoundException if the specified application does not exist
*/
public List<PluginInstanceDetail> getPlugins(ApplicationId appId) throws ApplicationNotFoundException {
ApplicationSpecification appSpec = store.getApplication(appId);
if (appSpec == null) {
throw new ApplicationNotFoundException(appId);
}
List<PluginInstanceDetail> pluginInstanceDetails = new ArrayList<>();
for (Map.Entry<String, Plugin> entry : appSpec.getPlugins().entrySet()) {
pluginInstanceDetails.add(new PluginInstanceDetail(entry.getKey(), entry.getValue()));
}
return pluginInstanceDetails;
}
use of co.cask.cdap.api.app.ApplicationSpecification in project cdap by caskdata.
the class ApplicationLifecycleService method updateApp.
/**
* Update an existing application. An application's configuration and artifact version can be updated.
*
* @param appId the id of the application to update
* @param appRequest the request to update the application, including new config and artifact
* @param programTerminator a program terminator that will stop programs that are removed when updating an app.
* For example, if an update removes a flow, the terminator defines how to stop that flow.
* @return information about the deployed application
* @throws ApplicationNotFoundException if the specified application does not exist
* @throws ArtifactNotFoundException if the requested artifact does not exist
* @throws InvalidArtifactException if the specified artifact is invalid. For example, if the artifact name changed,
* if the version is an invalid version, or the artifact contains no app classes
* @throws Exception if there was an exception during the deployment pipeline. This exception will often wrap
* the actual exception
*/
public ApplicationWithPrograms updateApp(ApplicationId appId, AppRequest appRequest, ProgramTerminator programTerminator) throws Exception {
// Check if the current user has admin privileges on it before updating.
authorizationEnforcer.enforce(appId, authenticationContext.getPrincipal(), Action.ADMIN);
// check that app exists
ApplicationSpecification currentSpec = store.getApplication(appId);
if (currentSpec == null) {
throw new ApplicationNotFoundException(appId);
}
ArtifactId currentArtifact = currentSpec.getArtifactId();
// if no artifact is given, use the current one.
ArtifactId newArtifactId = currentArtifact;
// otherwise, check requested artifact is valid and use it
ArtifactSummary requestedArtifact = appRequest.getArtifact();
if (requestedArtifact != null) {
// cannot change artifact name, only artifact version.
if (!currentArtifact.getName().equals(requestedArtifact.getName())) {
throw new InvalidArtifactException(String.format(" Only artifact version updates are allowed. Cannot change from artifact '%s' to '%s'.", currentArtifact.getName(), requestedArtifact.getName()));
}
if (!currentArtifact.getScope().equals(requestedArtifact.getScope())) {
throw new InvalidArtifactException("Only artifact version updates are allowed. " + "Cannot change from a non-system artifact to a system artifact or vice versa.");
}
// check requested artifact version is valid
ArtifactVersion requestedVersion = new ArtifactVersion(requestedArtifact.getVersion());
if (requestedVersion.getVersion() == null) {
throw new InvalidArtifactException(String.format("Requested artifact version '%s' is invalid", requestedArtifact.getVersion()));
}
newArtifactId = new ArtifactId(currentArtifact.getName(), requestedVersion, currentArtifact.getScope());
}
// ownerAdmin.getImpersonationPrincipal will give the owner which will be impersonated for the application
// irrespective of the version
SecurityUtil.verifyOwnerPrincipal(appId, appRequest.getOwnerPrincipal(), ownerAdmin);
Object requestedConfigObj = appRequest.getConfig();
// if config is null, use the previous config. Shouldn't use a static GSON since the request Config object can
// be a user class, otherwise there will be ClassLoader leakage.
String requestedConfigStr = requestedConfigObj == null ? currentSpec.getConfiguration() : new Gson().toJson(requestedConfigObj);
Id.Artifact artifactId = Id.Artifact.fromEntityId(Artifacts.toArtifactId(appId.getParent(), newArtifactId));
return deployApp(appId.getParent(), appId.getApplication(), null, artifactId, requestedConfigStr, programTerminator, ownerAdmin.getOwner(appId), appRequest.canUpdateSchedules());
}
use of co.cask.cdap.api.app.ApplicationSpecification in project cdap by caskdata.
the class ApplicationLifecycleService method removeApplication.
/**
* Delete an application specified by appId.
*
* @param appId the {@link ApplicationId} of the application to be removed
* @throws Exception
*/
public void removeApplication(final ApplicationId appId) throws Exception {
// enforce ADMIN privileges on the app
authorizationEnforcer.enforce(appId, authenticationContext.getPrincipal(), Action.ADMIN);
ensureNoRunningPrograms(appId);
ApplicationSpecification spec = store.getApplication(appId);
if (spec == null) {
throw new NotFoundException(Id.Application.fromEntityId(appId));
}
removeAppInternal(appId, spec);
}
Aggregations