Search in sources :

Example 6 with CloseableClassLoader

use of co.cask.cdap.api.artifact.CloseableClassLoader in project cdap by caskdata.

the class DefaultArtifactManager method createAndGetClassLoader.

private CloseableClassLoader createAndGetClassLoader(HttpRequest httpRequest, ArtifactInfo artifactInfo, @Nullable ClassLoader parentClassLoader) throws IOException {
    HttpResponse httpResponse = remoteClient.execute(httpRequest);
    if (httpResponse.getResponseCode() == HttpResponseStatus.NOT_FOUND.getCode()) {
        throw new IOException("Could not get artifact detail, endpoint not found");
    }
    if (httpResponse.getResponseCode() == 200) {
        String path = httpResponse.getResponseBodyAsString();
        Location location = Locations.getLocationFromAbsolutePath(locationFactory, path);
        if (!location.exists()) {
            throw new IOException(String.format("Artifact Location does not exist %s for artifact %s version %s", path, artifactInfo.getName(), artifactInfo.getVersion()));
        }
        File unpackedDir = DirUtils.createTempDir(tmpDir);
        BundleJarUtil.unJar(location, unpackedDir);
        DirectoryClassLoader directoryClassLoader = new DirectoryClassLoader(unpackedDir, parentClassLoader == null ? bootstrapClassLoader : parentClassLoader);
        return new CloseableClassLoader(directoryClassLoader, new ClassLoaderCleanup(directoryClassLoader, unpackedDir));
    } else {
        throw new IOException(String.format("Exception while getting artifacts list %s", httpResponse.getResponseBodyAsString()));
    }
}
Also used : DirectoryClassLoader(co.cask.cdap.common.lang.DirectoryClassLoader) HttpResponse(co.cask.common.http.HttpResponse) IOException(java.io.IOException) CloseableClassLoader(co.cask.cdap.api.artifact.CloseableClassLoader) File(java.io.File) Location(org.apache.twill.filesystem.Location)

Example 7 with CloseableClassLoader

use of co.cask.cdap.api.artifact.CloseableClassLoader in project cdap by caskdata.

the class ArtifactInspector method inspectArtifact.

/**
 * Inspect the given artifact to determine the classes contained in the artifact.
 *
 * @param artifactId the id of the artifact to inspect
 * @param artifactFile the artifact file
 * @param parentClassLoader the parent classloader to use when inspecting plugins contained in the artifact.
 *                          For example, a ProgramClassLoader created from the artifact the input artifact extends
 * @return metadata about the classes contained in the artifact
 * @throws IOException if there was an exception opening the jar file
 * @throws InvalidArtifactException if the artifact is invalid. For example, if the application main class is not
 *                                  actually an Application.
 */
ArtifactClasses inspectArtifact(Id.Artifact artifactId, File artifactFile, @Nullable ClassLoader parentClassLoader) throws IOException, InvalidArtifactException {
    Path tmpDir = Paths.get(cConf.get(Constants.CFG_LOCAL_DATA_DIR), cConf.get(Constants.AppFabric.TEMP_DIR)).toAbsolutePath();
    Files.createDirectories(tmpDir);
    Location artifactLocation = Locations.toLocation(artifactFile);
    Path stageDir = Files.createTempDirectory(tmpDir, artifactFile.getName());
    try {
        File unpackedDir = BundleJarUtil.unJar(artifactLocation, Files.createTempDirectory(stageDir, "unpacked-").toFile());
        try (CloseableClassLoader artifactClassLoader = artifactClassLoaderFactory.createClassLoader(unpackedDir);
            PluginInstantiator pluginInstantiator = new PluginInstantiator(cConf, parentClassLoader == null ? artifactClassLoader : parentClassLoader, Files.createTempDirectory(stageDir, "plugins-").toFile(), false)) {
            pluginInstantiator.addArtifact(artifactLocation, artifactId.toArtifactId());
            ArtifactClasses.Builder builder = inspectApplications(artifactId, ArtifactClasses.builder(), artifactLocation, artifactClassLoader);
            return inspectPlugins(builder, artifactFile, artifactId.toArtifactId(), pluginInstantiator).build();
        }
    } catch (EOFException | ZipException e) {
        throw new InvalidArtifactException("Artifact " + artifactId + " is not a valid zip file.", e);
    } finally {
        try {
            DirUtils.deleteDirectoryContents(stageDir.toFile());
        } catch (IOException e) {
            LOG.warn("Exception raised while deleting directory {}", stageDir, e);
        }
    }
}
Also used : Path(java.nio.file.Path) ArtifactClasses(co.cask.cdap.api.artifact.ArtifactClasses) EOFException(java.io.EOFException) PluginInstantiator(co.cask.cdap.internal.app.runtime.plugin.PluginInstantiator) ZipException(java.util.zip.ZipException) CloseableClassLoader(co.cask.cdap.api.artifact.CloseableClassLoader) IOException(java.io.IOException) JarFile(java.util.jar.JarFile) File(java.io.File) InvalidArtifactException(co.cask.cdap.common.InvalidArtifactException) Location(org.apache.twill.filesystem.Location)

Example 8 with CloseableClassLoader

use of co.cask.cdap.api.artifact.CloseableClassLoader in project cdap by caskdata.

the class DefaultArtifactRepository method addArtifact.

@Override
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.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) CloseableClassLoader(co.cask.cdap.api.artifact.CloseableClassLoader)

Example 9 with CloseableClassLoader

use of co.cask.cdap.api.artifact.CloseableClassLoader in project cdap by caskdata.

the class AbstractArtifactManager method createClassLoader.

/**
 * Create a class loader with artifact jar unpacked contents and parent for this classloader is the supplied
 * parentClassLoader, if that parent classloader is null, bootstrap classloader is used as parent.
 * This is a closeable classloader, caller should call close when he is done using it, during close directory
 * cleanup will be performed.
 *
 * @param artifactInfo artifact info whose artifact will be unpacked to create classloader
 * @param parentClassLoader  optional parent classloader, if null bootstrap classloader will be used
 * @return CloseableClassLoader call close on this CloseableClassLoader for cleanup
 * @throws IOException if artifact is not found or there were any error while getting artifact
 */
@Override
public CloseableClassLoader createClassLoader(ArtifactInfo artifactInfo, @Nullable ClassLoader parentClassLoader) throws IOException {
    File unpackedDir = DirUtils.createTempDir(tmpDir);
    BundleJarUtil.unJar(getArtifactLocation(artifactInfo), unpackedDir);
    DirectoryClassLoader directoryClassLoader = new DirectoryClassLoader(unpackedDir, parentClassLoader == null ? bootstrapClassLoader : parentClassLoader, "lib");
    return new CloseableClassLoader(directoryClassLoader, new ClassLoaderCleanup(directoryClassLoader, unpackedDir));
}
Also used : DirectoryClassLoader(co.cask.cdap.common.lang.DirectoryClassLoader) CloseableClassLoader(co.cask.cdap.api.artifact.CloseableClassLoader) File(java.io.File)

Example 10 with CloseableClassLoader

use of co.cask.cdap.api.artifact.CloseableClassLoader in project cdap by caskdata.

the class ConfiguratorTest method testAppWithConfig.

@Test
public void testAppWithConfig() throws Exception {
    LocationFactory locationFactory = new LocalLocationFactory(TMP_FOLDER.newFolder());
    Location appJar = AppJarHelper.createDeploymentJar(locationFactory, ConfigTestApp.class);
    Id.Artifact artifactId = Id.Artifact.from(Id.Namespace.DEFAULT, ConfigTestApp.class.getSimpleName(), "1.0.0");
    CConfiguration cConf = CConfiguration.create();
    ArtifactRepository baseArtifactRepo = new DefaultArtifactRepository(conf, null, null, new DummyProgramRunnerFactory(), new DefaultImpersonator(cConf, null));
    ArtifactRepository artifactRepo = new AuthorizationArtifactRepository(baseArtifactRepo, authEnforcer, authenticationContext);
    ConfigTestApp.ConfigClass config = new ConfigTestApp.ConfigClass("myStream", "myTable");
    // Create a configurator that is testable. Provide it an application.
    try (CloseableClassLoader artifactClassLoader = artifactRepo.createArtifactClassLoader(appJar, new EntityImpersonator(artifactId.getNamespace().toEntityId(), new DefaultImpersonator(cConf, null)))) {
        Configurator configuratorWithConfig = new InMemoryConfigurator(conf, Id.Namespace.DEFAULT, artifactId, ConfigTestApp.class.getName(), artifactRepo, artifactClassLoader, null, null, new Gson().toJson(config));
        ListenableFuture<ConfigResponse> result = configuratorWithConfig.config();
        ConfigResponse response = result.get(10, TimeUnit.SECONDS);
        Assert.assertNotNull(response);
        ApplicationSpecificationAdapter adapter = ApplicationSpecificationAdapter.create(new ReflectionSchemaGenerator());
        ApplicationSpecification specification = adapter.fromJson(response.get());
        Assert.assertNotNull(specification);
        Assert.assertTrue(specification.getStreams().size() == 1);
        Assert.assertTrue(specification.getStreams().containsKey("myStream"));
        Assert.assertTrue(specification.getDatasets().size() == 1);
        Assert.assertTrue(specification.getDatasets().containsKey("myTable"));
        Configurator configuratorWithoutConfig = new InMemoryConfigurator(conf, Id.Namespace.DEFAULT, artifactId, ConfigTestApp.class.getName(), artifactRepo, artifactClassLoader, null, null, null);
        result = configuratorWithoutConfig.config();
        response = result.get(10, TimeUnit.SECONDS);
        Assert.assertNotNull(response);
        specification = adapter.fromJson(response.get());
        Assert.assertNotNull(specification);
        Assert.assertTrue(specification.getStreams().size() == 1);
        Assert.assertTrue(specification.getStreams().containsKey(ConfigTestApp.DEFAULT_STREAM));
        Assert.assertTrue(specification.getDatasets().size() == 1);
        Assert.assertTrue(specification.getDatasets().containsKey(ConfigTestApp.DEFAULT_TABLE));
        Assert.assertNotNull(specification.getProgramSchedules().get(ConfigTestApp.SCHEDULE_NAME));
        ProgramStatusTrigger trigger = (ProgramStatusTrigger) specification.getProgramSchedules().get(ConfigTestApp.SCHEDULE_NAME).getTrigger();
        Assert.assertEquals(trigger.getProgramId().getProgram(), ConfigTestApp.WORKFLOW_NAME);
    }
}
Also used : ApplicationSpecification(co.cask.cdap.api.app.ApplicationSpecification) Configurator(co.cask.cdap.app.deploy.Configurator) DefaultArtifactRepository(co.cask.cdap.internal.app.runtime.artifact.DefaultArtifactRepository) Gson(com.google.gson.Gson) ConfigResponse(co.cask.cdap.app.deploy.ConfigResponse) CloseableClassLoader(co.cask.cdap.api.artifact.CloseableClassLoader) ProgramStatusTrigger(co.cask.cdap.internal.app.runtime.schedule.trigger.ProgramStatusTrigger) LocalLocationFactory(org.apache.twill.filesystem.LocalLocationFactory) ConfigTestApp(co.cask.cdap.ConfigTestApp) AuthorizationArtifactRepository(co.cask.cdap.internal.app.runtime.artifact.AuthorizationArtifactRepository) DummyProgramRunnerFactory(co.cask.cdap.app.runtime.DummyProgramRunnerFactory) EntityImpersonator(co.cask.cdap.security.impersonation.EntityImpersonator) AuthorizationArtifactRepository(co.cask.cdap.internal.app.runtime.artifact.AuthorizationArtifactRepository) ArtifactRepository(co.cask.cdap.internal.app.runtime.artifact.ArtifactRepository) DefaultArtifactRepository(co.cask.cdap.internal.app.runtime.artifact.DefaultArtifactRepository) 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) Id(co.cask.cdap.common.id.Id) Location(org.apache.twill.filesystem.Location) Test(org.junit.Test)

Aggregations

CloseableClassLoader (co.cask.cdap.api.artifact.CloseableClassLoader)12 File (java.io.File)7 Location (org.apache.twill.filesystem.Location)7 EntityImpersonator (co.cask.cdap.security.impersonation.EntityImpersonator)6 IOException (java.io.IOException)5 ArtifactClasses (co.cask.cdap.api.artifact.ArtifactClasses)4 Id (co.cask.cdap.common.id.Id)4 DirectoryClassLoader (co.cask.cdap.common.lang.DirectoryClassLoader)4 DefaultImpersonator (co.cask.cdap.security.impersonation.DefaultImpersonator)4 Test (org.junit.Test)4 ReflectionSchemaGenerator (co.cask.cdap.internal.io.ReflectionSchemaGenerator)3 Closeable (java.io.Closeable)3 ApplicationSpecification (co.cask.cdap.api.app.ApplicationSpecification)2 ArtifactInfo (co.cask.cdap.api.artifact.ArtifactInfo)2 ConfigResponse (co.cask.cdap.app.deploy.ConfigResponse)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