use of co.cask.cdap.security.impersonation.EntityImpersonator in project cdap by caskdata.
the class ArtifactRepository method addArtifact.
/**
* Inspects and builds plugin and application information for the given artifact, adding an additional set of
* plugin classes to the plugins found through inspection. This method is used when all plugin classes
* cannot be derived by inspecting the artifact but need to be explicitly set. This is true for 3rd party plugins
* like jdbc drivers.
*
* @param artifactId the id of the artifact to inspect and store
* @param artifactFile the artifact to inspect and store
* @param parentArtifacts artifacts the given artifact extends.
* If null, the given artifact does not extend another artifact
* @param additionalPlugins the set of additional plugin classes to add to the plugins found through inspection.
* If null, no additional plugin classes will be added
* @param properties properties for the artifact
* @throws IOException if there was an exception reading from the artifact store
* @throws ArtifactRangeNotFoundException if none of the parent artifacts could be found
* @throws UnauthorizedException if the user is not authorized to add an artifact in the specified namespace. To add
* an artifact, a user must have {@link Action#WRITE} on the namespace in which
* the artifact is being added. If authorization is successful, and
* the artifact is added successfully, then the user gets all {@link Action privileges}
* on the added artifact.
*/
@VisibleForTesting
public ArtifactDetail addArtifact(final Id.Artifact artifactId, final File artifactFile, @Nullable Set<ArtifactRange> parentArtifacts, @Nullable Set<PluginClass> additionalPlugins, Map<String, String> properties) throws Exception {
if (additionalPlugins != null) {
validatePluginSet(additionalPlugins);
}
parentArtifacts = parentArtifacts == null ? Collections.<ArtifactRange>emptySet() : parentArtifacts;
CloseableClassLoader parentClassLoader = null;
EntityImpersonator entityImpersonator = new EntityImpersonator(artifactId.toEntityId(), impersonator);
if (!parentArtifacts.isEmpty()) {
validateParentSet(artifactId, parentArtifacts);
parentClassLoader = createParentClassLoader(artifactId, parentArtifacts, entityImpersonator);
}
try {
ArtifactClasses artifactClasses = inspectArtifact(artifactId, artifactFile, additionalPlugins, parentClassLoader);
ArtifactMeta meta = new ArtifactMeta(artifactClasses, parentArtifacts, properties);
ArtifactDetail artifactDetail = artifactStore.write(artifactId, meta, Files.newInputStreamSupplier(artifactFile), entityImpersonator);
ArtifactDescriptor descriptor = artifactDetail.getDescriptor();
// info hides some fields that are available in detail, such as the location of the artifact
ArtifactInfo artifactInfo = new ArtifactInfo(descriptor.getArtifactId(), artifactDetail.getMeta().getClasses(), artifactDetail.getMeta().getProperties());
// add system metadata for artifacts
writeSystemMetadata(artifactId.toEntityId(), artifactInfo);
return artifactDetail;
} finally {
Closeables.closeQuietly(parentClassLoader);
}
}
use of co.cask.cdap.security.impersonation.EntityImpersonator in project cdap by caskdata.
the class LocalArtifactLoaderStage method process.
/**
* Instantiates the Application class and calls configure() on it to generate the {@link ApplicationSpecification}.
*
* @param deploymentInfo information needed to deploy the application, such as the artifact to create it from
* and the application config to use.
*/
@Override
public void process(AppDeploymentInfo deploymentInfo) throws InterruptedException, ExecutionException, TimeoutException, IOException {
ArtifactId artifactId = deploymentInfo.getArtifactId();
Location artifactLocation = deploymentInfo.getArtifactLocation();
String appClassName = deploymentInfo.getAppClassName();
String appVersion = deploymentInfo.getApplicationVersion();
String configString = deploymentInfo.getConfigString();
EntityImpersonator classLoaderImpersonator = new EntityImpersonator(artifactId, impersonator);
ClassLoader artifactClassLoader = artifactRepository.createArtifactClassLoader(artifactLocation, classLoaderImpersonator);
getContext().setProperty(LocalApplicationManager.ARTIFACT_CLASSLOADER_KEY, artifactClassLoader);
InMemoryConfigurator inMemoryConfigurator = new InMemoryConfigurator(cConf, deploymentInfo.getNamespaceId().toId(), artifactId.toId(), appClassName, artifactRepository, artifactClassLoader, deploymentInfo.getApplicationName(), deploymentInfo.getApplicationVersion(), configString);
ListenableFuture<ConfigResponse> result = inMemoryConfigurator.config();
ConfigResponse response = result.get(120, TimeUnit.SECONDS);
if (response.getExitCode() != 0) {
throw new IllegalArgumentException("Failed to configure application: " + deploymentInfo);
}
ApplicationSpecification specification = adapter.fromJson(response.get());
ApplicationId applicationId;
if (appVersion == null) {
applicationId = deploymentInfo.getNamespaceId().app(specification.getName());
} else {
applicationId = deploymentInfo.getNamespaceId().app(specification.getName(), appVersion);
}
emit(new ApplicationDeployable(deploymentInfo.getArtifactId(), deploymentInfo.getArtifactLocation(), applicationId, specification, store.getApplication(applicationId), ApplicationDeployScope.USER, deploymentInfo.getOwnerPrincipal(), deploymentInfo.canUpdateSchedules()));
}
use of co.cask.cdap.security.impersonation.EntityImpersonator in project cdap by caskdata.
the class ArtifactInspectorTest method inspectAppsAndPlugins.
@Test
public void inspectAppsAndPlugins() throws Exception {
Manifest manifest = new Manifest();
manifest.getMainAttributes().put(ManifestFields.EXPORT_PACKAGE, InspectionApp.class.getPackage().getName());
File appFile = createJar(InspectionApp.class, new File(TMP_FOLDER.newFolder(), "InspectionApp-1.0.0.jar"), manifest);
Id.Artifact artifactId = Id.Artifact.from(Id.Namespace.DEFAULT, "InspectionApp", "1.0.0");
Location artifactLocation = Locations.toLocation(appFile);
try (CloseableClassLoader artifactClassLoader = classLoaderFactory.createClassLoader(artifactLocation, new EntityImpersonator(artifactId.toEntityId(), new DefaultImpersonator(CConfiguration.create(), null)))) {
ArtifactClasses classes = artifactInspector.inspectArtifact(artifactId, appFile, artifactClassLoader);
// check app classes
Set<ApplicationClass> expectedApps = ImmutableSet.of(new ApplicationClass(InspectionApp.class.getName(), "", new ReflectionSchemaGenerator(false).generate(InspectionApp.AConfig.class)));
Assert.assertEquals(expectedApps, classes.getApps());
// check plugin classes
PluginClass expectedPlugin = new PluginClass(InspectionApp.PLUGIN_TYPE, InspectionApp.PLUGIN_NAME, InspectionApp.PLUGIN_DESCRIPTION, InspectionApp.AppPlugin.class.getName(), "pluginConf", ImmutableMap.of("y", new PluginPropertyField("y", "", "double", true, true), "isSomething", new PluginPropertyField("isSomething", "", "boolean", true, false)));
Assert.assertEquals(ImmutableSet.of(expectedPlugin), classes.getPlugins());
}
}
use of co.cask.cdap.security.impersonation.EntityImpersonator in project cdap by caskdata.
the class ArtifactStore method deleteMeta.
private void deleteMeta(Table table, Id.Artifact artifactId, byte[] oldData) throws IOException {
// delete old artifact data
ArtifactCell artifactCell = new ArtifactCell(artifactId);
table.delete(artifactCell.rowkey, artifactCell.column);
// delete old plugins
final ArtifactData oldMeta = GSON.fromJson(Bytes.toString(oldData), ArtifactData.class);
byte[] artifactColumn = new ArtifactColumn(artifactId).getColumn();
for (PluginClass pluginClass : oldMeta.meta.getClasses().getPlugins()) {
// delete metadata for each artifact this plugin extends
for (ArtifactRange artifactRange : oldMeta.meta.getUsableBy()) {
// p:{namespace}:{type}:{name}
PluginKey pluginKey = new PluginKey(artifactRange.getNamespace(), artifactRange.getName(), pluginClass.getType(), pluginClass.getName());
table.delete(pluginKey.getRowKey(), artifactColumn);
}
}
// delete old appclass metadata
for (ApplicationClass appClass : oldMeta.meta.getClasses().getApps()) {
AppClassKey appClassKey = new AppClassKey(artifactId.getNamespace().toEntityId(), appClass.getClassName());
table.delete(appClassKey.getRowKey(), artifactColumn);
}
try {
new EntityImpersonator(artifactId.toEntityId(), impersonator).impersonate(new Callable<Void>() {
@Override
public Void call() throws Exception {
Locations.getLocationFromAbsolutePath(locationFactory, oldMeta.getLocationPath()).delete();
return null;
}
});
} catch (IOException ioe) {
throw ioe;
} catch (Exception e) {
// this should not happen
throw Throwables.propagate(e);
}
}
use of co.cask.cdap.security.impersonation.EntityImpersonator in project cdap by caskdata.
the class ConfiguratorTest method testInMemoryConfigurator.
@Test
public void testInMemoryConfigurator() throws Exception {
LocationFactory locationFactory = new LocalLocationFactory(TMP_FOLDER.newFolder());
Location appJar = AppJarHelper.createDeploymentJar(locationFactory, WordCountApp.class);
Id.Artifact artifactId = Id.Artifact.from(Id.Namespace.DEFAULT, WordCountApp.class.getSimpleName(), "1.0.0");
CConfiguration cConf = CConfiguration.create();
ArtifactRepository artifactRepo = new ArtifactRepository(conf, null, null, authorizer, new DummyProgramRunnerFactory(), new DefaultImpersonator(cConf, null), authEnforcer, authenticationContext);
// Create a configurator that is testable. Provide it a application.
try (CloseableClassLoader artifactClassLoader = artifactRepo.createArtifactClassLoader(appJar, new EntityImpersonator(artifactId.getNamespace().toEntityId(), new DefaultImpersonator(cConf, null)))) {
Configurator configurator = new InMemoryConfigurator(conf, Id.Namespace.DEFAULT, artifactId, WordCountApp.class.getName(), artifactRepo, artifactClassLoader, null, null, "");
// Extract response from the configurator.
ListenableFuture<ConfigResponse> result = configurator.config();
ConfigResponse response = result.get(10, TimeUnit.SECONDS);
Assert.assertNotNull(response);
// Deserialize the JSON spec back into Application object.
ApplicationSpecificationAdapter adapter = ApplicationSpecificationAdapter.create(new ReflectionSchemaGenerator());
ApplicationSpecification specification = adapter.fromJson(response.get());
Assert.assertNotNull(specification);
// Simple checks.
Assert.assertTrue(specification.getName().equals("WordCountApp"));
// # of flows.
Assert.assertTrue(specification.getFlows().size() == 1);
}
}
Aggregations