Search in sources :

Example 1 with EntityImpersonator

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);
    }
}
Also used : ArtifactInfo(co.cask.cdap.api.artifact.ArtifactInfo) ArtifactClasses(co.cask.cdap.api.artifact.ArtifactClasses) EntityImpersonator(co.cask.cdap.security.impersonation.EntityImpersonator) ArtifactRange(co.cask.cdap.api.artifact.ArtifactRange) CloseableClassLoader(co.cask.cdap.api.artifact.CloseableClassLoader) VisibleForTesting(com.google.common.annotations.VisibleForTesting)

Example 2 with EntityImpersonator

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()));
}
Also used : ApplicationSpecification(co.cask.cdap.api.app.ApplicationSpecification) ArtifactId(co.cask.cdap.proto.id.ArtifactId) EntityImpersonator(co.cask.cdap.security.impersonation.EntityImpersonator) ConfigResponse(co.cask.cdap.app.deploy.ConfigResponse) ApplicationId(co.cask.cdap.proto.id.ApplicationId) InMemoryConfigurator(co.cask.cdap.internal.app.deploy.InMemoryConfigurator) Location(org.apache.twill.filesystem.Location)

Example 3 with EntityImpersonator

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());
    }
}
Also used : EntityImpersonator(co.cask.cdap.security.impersonation.EntityImpersonator) ApplicationClass(co.cask.cdap.api.artifact.ApplicationClass) CloseableClassLoader(co.cask.cdap.api.artifact.CloseableClassLoader) Manifest(java.util.jar.Manifest) ReflectionSchemaGenerator(co.cask.cdap.internal.io.ReflectionSchemaGenerator) DefaultImpersonator(co.cask.cdap.security.impersonation.DefaultImpersonator) PluginPropertyField(co.cask.cdap.api.plugin.PluginPropertyField) ArtifactClasses(co.cask.cdap.api.artifact.ArtifactClasses) Id(co.cask.cdap.proto.Id) PluginClass(co.cask.cdap.api.plugin.PluginClass) File(java.io.File) Location(org.apache.twill.filesystem.Location) InspectionApp(co.cask.cdap.internal.app.runtime.artifact.app.inspection.InspectionApp) Test(org.junit.Test)

Example 4 with EntityImpersonator

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);
    }
}
Also used : EntityImpersonator(co.cask.cdap.security.impersonation.EntityImpersonator) ArtifactRange(co.cask.cdap.api.artifact.ArtifactRange) ApplicationClass(co.cask.cdap.api.artifact.ApplicationClass) IOException(java.io.IOException) TransactionFailureException(org.apache.tephra.TransactionFailureException) ArtifactNotFoundException(co.cask.cdap.common.ArtifactNotFoundException) ArtifactAlreadyExistsException(co.cask.cdap.common.ArtifactAlreadyExistsException) TransactionConflictException(org.apache.tephra.TransactionConflictException) PluginNotExistsException(co.cask.cdap.internal.app.runtime.plugin.PluginNotExistsException) ArtifactRangeNotFoundException(co.cask.cdap.common.ArtifactRangeNotFoundException) DatasetManagementException(co.cask.cdap.api.dataset.DatasetManagementException) IOException(java.io.IOException) PluginClass(co.cask.cdap.api.plugin.PluginClass)

Example 5 with EntityImpersonator

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);
    }
}
Also used : ApplicationSpecification(co.cask.cdap.api.app.ApplicationSpecification) DummyProgramRunnerFactory(co.cask.cdap.app.runtime.DummyProgramRunnerFactory) Configurator(co.cask.cdap.app.deploy.Configurator) EntityImpersonator(co.cask.cdap.security.impersonation.EntityImpersonator) ArtifactRepository(co.cask.cdap.internal.app.runtime.artifact.ArtifactRepository) ConfigResponse(co.cask.cdap.app.deploy.ConfigResponse) CloseableClassLoader(co.cask.cdap.api.artifact.CloseableClassLoader) ReflectionSchemaGenerator(co.cask.cdap.internal.io.ReflectionSchemaGenerator) CConfiguration(co.cask.cdap.common.conf.CConfiguration) DefaultImpersonator(co.cask.cdap.security.impersonation.DefaultImpersonator) LocalLocationFactory(org.apache.twill.filesystem.LocalLocationFactory) LocationFactory(org.apache.twill.filesystem.LocationFactory) ApplicationSpecificationAdapter(co.cask.cdap.internal.app.ApplicationSpecificationAdapter) WordCountApp(co.cask.cdap.WordCountApp) Id(co.cask.cdap.proto.Id) LocalLocationFactory(org.apache.twill.filesystem.LocalLocationFactory) Location(org.apache.twill.filesystem.Location) Test(org.junit.Test)

Aggregations

EntityImpersonator (co.cask.cdap.security.impersonation.EntityImpersonator)7 CloseableClassLoader (co.cask.cdap.api.artifact.CloseableClassLoader)5 Location (org.apache.twill.filesystem.Location)5 Id (co.cask.cdap.proto.Id)4 DefaultImpersonator (co.cask.cdap.security.impersonation.DefaultImpersonator)4 Test (org.junit.Test)4 ApplicationSpecification (co.cask.cdap.api.app.ApplicationSpecification)3 ConfigResponse (co.cask.cdap.app.deploy.ConfigResponse)3 ReflectionSchemaGenerator (co.cask.cdap.internal.io.ReflectionSchemaGenerator)3 ApplicationClass (co.cask.cdap.api.artifact.ApplicationClass)2 ArtifactClasses (co.cask.cdap.api.artifact.ArtifactClasses)2 ArtifactRange (co.cask.cdap.api.artifact.ArtifactRange)2 PluginClass (co.cask.cdap.api.plugin.PluginClass)2 Configurator (co.cask.cdap.app.deploy.Configurator)2 DummyProgramRunnerFactory (co.cask.cdap.app.runtime.DummyProgramRunnerFactory)2 CConfiguration (co.cask.cdap.common.conf.CConfiguration)2 ApplicationSpecificationAdapter (co.cask.cdap.internal.app.ApplicationSpecificationAdapter)2 ArtifactRepository (co.cask.cdap.internal.app.runtime.artifact.ArtifactRepository)2 File (java.io.File)2 Manifest (java.util.jar.Manifest)2