Search in sources :

Example 76 with ArtifactRange

use of io.cdap.cdap.api.artifact.ArtifactRange in project cdap by cdapio.

the class ArtifactConfigReaderTest method testRead.

@Test
public void testRead() throws IOException, InvalidArtifactException {
    ArtifactConfig validConfig = new ArtifactConfig(ImmutableSet.of(new ArtifactRange(NamespaceId.SYSTEM.getNamespace(), "a", new ArtifactVersion("1.0.0"), new ArtifactVersion("2.0.0")), new ArtifactRange(NamespaceId.DEFAULT.getNamespace(), "b", new ArtifactVersion("1.0.0"), new ArtifactVersion("2.0.0"))), ImmutableSet.of(PluginClass.builder().setName("name").setType("type").setDescription("desc").setClassName("classname").setProperties(ImmutableMap.of("x", new PluginPropertyField("x", "some field", "int", true, false), "y", new PluginPropertyField("y", "some other field", "string", false, false))).build()), ImmutableMap.of("k1", "v1", "k2", "v2"));
    File configFile = new File(tmpFolder.newFolder(), "r1-1.0.0.json");
    try (BufferedWriter writer = Files.newWriter(configFile, Charsets.UTF_8)) {
        writer.write(validConfig.toString());
    }
    Assert.assertEquals(validConfig, configReader.read(Id.Namespace.DEFAULT, configFile));
}
Also used : ArtifactVersion(io.cdap.cdap.api.artifact.ArtifactVersion) ArtifactRange(io.cdap.cdap.api.artifact.ArtifactRange) PluginPropertyField(io.cdap.cdap.api.plugin.PluginPropertyField) File(java.io.File) BufferedWriter(java.io.BufferedWriter) Test(org.junit.Test)

Example 77 with ArtifactRange

use of io.cdap.cdap.api.artifact.ArtifactRange in project cdap by cdapio.

the class ArtifactConfigReaderTest method testInvalidParentNamespace.

@Test(expected = InvalidArtifactException.class)
public void testInvalidParentNamespace() throws IOException, InvalidArtifactException {
    ArtifactConfig badConfig = new ArtifactConfig(ImmutableSet.of(new ArtifactRange(NamespaceId.DEFAULT.getNamespace(), "b", new ArtifactVersion("1.0.0"), new ArtifactVersion("2.0.0"))), ImmutableSet.<PluginClass>of(), ImmutableMap.<String, String>of());
    File configFile = new File(tmpFolder.newFolder(), "r1-1.0.0.json");
    try (BufferedWriter writer = Files.newWriter(configFile, Charsets.UTF_8)) {
        writer.write(badConfig.toString());
    }
    configReader.read(Id.Namespace.SYSTEM, configFile);
}
Also used : ArtifactVersion(io.cdap.cdap.api.artifact.ArtifactVersion) ArtifactRange(io.cdap.cdap.api.artifact.ArtifactRange) File(java.io.File) BufferedWriter(java.io.BufferedWriter) Test(org.junit.Test)

Example 78 with ArtifactRange

use of io.cdap.cdap.api.artifact.ArtifactRange in project cdap by cdapio.

the class ArtifactStore method writeMeta.

// write a new artifact snapshot and clean up the old snapshot data
private void writeMeta(StructuredTableContext context, Id.Artifact artifactId, ArtifactData data) throws IOException {
    // write to artifact data table
    StructuredTable artifactDataTable = getTable(context, StoreDefinition.ArtifactStore.ARTIFACT_DATA_TABLE);
    ArtifactCell artifactCell = new ArtifactCell(artifactId);
    artifactDataTable.upsert(concatFields(artifactCell.keys, Collections.singleton(Fields.stringField(StoreDefinition.ArtifactStore.ARTIFACT_DATA_FIELD, GSON.toJson(data)))));
    ArtifactClasses classes = data.meta.getClasses();
    Location artifactLocation = Locations.getLocationFromAbsolutePath(locationFactory, data.getLocationPath());
    // write appClass metadata
    StructuredTable appTable = getTable(context, StoreDefinition.ArtifactStore.APP_DATA_TABLE);
    ArtifactCell artifactkeys = new ArtifactCell(artifactId);
    for (ApplicationClass appClass : classes.getApps()) {
        // a:{namespace}:{classname}
        AppClassKey appClassKey = new AppClassKey(artifactId.getNamespace().toEntityId(), appClass.getClassName());
        Field<String> appDataField = Fields.stringField(StoreDefinition.ArtifactStore.APP_DATA_FIELD, GSON.toJson(new AppData(appClass, artifactLocation)));
        appTable.upsert(concatFields(appClassKey.keys, artifactkeys.keys, Collections.singleton(appDataField)));
    }
    // write pluginClass metadata, we loop twice to only access to one table at a time to prevent deadlock
    StructuredTable pluginTable = getTable(context, StoreDefinition.ArtifactStore.PLUGIN_DATA_TABLE);
    for (PluginClass pluginClass : classes.getPlugins()) {
        // write metadata for each artifact this plugin extends
        for (ArtifactRange artifactRange : data.meta.getUsableBy()) {
            PluginKeyPrefix pluginKey = new PluginKeyPrefix(artifactRange.getNamespace(), artifactRange.getName(), pluginClass.getType(), pluginClass.getName());
            Field<String> pluginDataField = Fields.stringField(StoreDefinition.ArtifactStore.PLUGIN_DATA_FIELD, GSON.toJson(new PluginData(pluginClass, artifactLocation, artifactRange)));
            pluginTable.upsert(concatFields(pluginKey.keys, artifactkeys.keys, Collections.singleton(pluginDataField)));
        }
    }
    // write universal plugin class metadata
    StructuredTable uniPluginTable = getTable(context, StoreDefinition.ArtifactStore.UNIV_PLUGIN_DATA_TABLE);
    for (PluginClass pluginClass : classes.getPlugins()) {
        // by any other artifact in the same namespace.
        if (data.meta.getUsableBy().isEmpty()) {
            // Write a special entry for plugin that doesn't have parent, which means any artifact can use it
            UniversalPluginKeyPrefix pluginKey = new UniversalPluginKeyPrefix(artifactId.getNamespace().getId(), pluginClass.getType(), pluginClass.getName());
            Field<String> pluginDataField = Fields.stringField(StoreDefinition.ArtifactStore.PLUGIN_DATA_FIELD, GSON.toJson(new PluginData(pluginClass, artifactLocation, null)));
            uniPluginTable.upsert(concatFields(pluginKey.keys, artifactkeys.keys, Collections.singleton(pluginDataField)));
        }
    }
}
Also used : StructuredTable(io.cdap.cdap.spi.data.StructuredTable) ArtifactRange(io.cdap.cdap.api.artifact.ArtifactRange) ApplicationClass(io.cdap.cdap.api.artifact.ApplicationClass) ArtifactClasses(io.cdap.cdap.api.artifact.ArtifactClasses) PluginClass(io.cdap.cdap.api.plugin.PluginClass) Location(org.apache.twill.filesystem.Location)

Example 79 with ArtifactRange

use of io.cdap.cdap.api.artifact.ArtifactRange in project cdap by cdapio.

the class DefaultArtifactRepository method shouldUpdateSytemArtifact.

private boolean shouldUpdateSytemArtifact(ArtifactDetail currentArtifactDetail, SystemArtifactInfo systemArtifactInfo) {
    if (!currentArtifactDetail.getDescriptor().getArtifactId().getVersion().isSnapshot()) {
        // if it's not a snapshot, don't bother trying to update it since artifacts are immutable
        return false;
    }
    // For snapshots check if it's different. Artifact update is disruptive, so we spend some cycles
    // to check if it's really needed
    Set<ArtifactRange> parents = systemArtifactInfo.getConfig().getParents();
    if (!Objects.equals(parents, currentArtifactDetail.getMeta().getUsableBy())) {
        return true;
    }
    if (!Objects.equals(systemArtifactInfo.getConfig().getProperties(), currentArtifactDetail.getMeta().getProperties())) {
        return true;
    }
    Set<PluginClass> additionalPlugins = systemArtifactInfo.getConfig().getPlugins();
    if (additionalPlugins != null && !currentArtifactDetail.getMeta().getClasses().getPlugins().containsAll(additionalPlugins)) {
        return true;
    }
    try (InputStream stream1 = currentArtifactDetail.getDescriptor().getLocation().getInputStream();
        InputStream stream2 = new FileInputStream(systemArtifactInfo.getArtifactFile())) {
        return !IOUtils.contentEquals(stream1, stream2);
    } catch (IOException e) {
        // In case of any IO problems, jsut update it
        return true;
    }
}
Also used : FileInputStream(java.io.FileInputStream) InputStream(java.io.InputStream) ArtifactRange(io.cdap.cdap.api.artifact.ArtifactRange) IOException(java.io.IOException) PluginClass(io.cdap.cdap.api.plugin.PluginClass) FileInputStream(java.io.FileInputStream)

Example 80 with ArtifactRange

use of io.cdap.cdap.api.artifact.ArtifactRange in project cdap by cdapio.

the class DefaultArtifactRepository method getParentArtifactDescriptors.

/**
 * Get {@link ArtifactDescriptor} of parent and grandparent (if any) artifacts for the given artifact.
 *
 * @param artifactId the id of the artifact for which to find its parent and grandparent {@link ArtifactDescriptor}
 * @param parentArtifacts the ranges of parents to find
 * @return {@link ArtifactDescriptor} of parent and grandparent (if any) artifacts, in that specific order
 * @throws ArtifactRangeNotFoundException if none of the parents could be found
 * @throws InvalidArtifactException       if one of the parents also has parents
 */
private List<ArtifactDescriptor> getParentArtifactDescriptors(Id.Artifact artifactId, Set<ArtifactRange> parentArtifacts) throws ArtifactRangeNotFoundException, InvalidArtifactException {
    List<ArtifactDetail> parents = new ArrayList<>();
    for (ArtifactRange parentRange : parentArtifacts) {
        parents.addAll(artifactStore.getArtifacts(parentRange, Integer.MAX_VALUE, ArtifactSortOrder.UNORDERED));
    }
    if (parents.isEmpty()) {
        throw new ArtifactRangeNotFoundException(String.format("Artifact %s extends artifacts '%s' that do not exist", artifactId, Joiner.on('/').join(parentArtifacts)));
    }
    ArtifactDescriptor parentArtifact = null;
    ArtifactDescriptor grandparentArtifact = null;
    // complicated dependency trees that are hard to manage.
    for (ArtifactDetail parent : parents) {
        Set<ArtifactRange> grandparentRanges = parent.getMeta().getUsableBy();
        for (ArtifactRange grandparentRange : grandparentRanges) {
            // if the parent as the child as a parent (cyclic dependency)
            if (grandparentRange.getNamespace().equals(artifactId.getNamespace().getId()) && grandparentRange.getName().equals(artifactId.getName()) && grandparentRange.versionIsInRange(artifactId.getVersion())) {
                throw new InvalidArtifactException(String.format("Invalid artifact '%s': cyclic dependency. Parent '%s' has artifact '%s' as a parent.", artifactId, parent.getDescriptor().getArtifactId(), artifactId));
            }
            List<ArtifactDetail> grandparents = artifactStore.getArtifacts(grandparentRange, Integer.MAX_VALUE, ArtifactSortOrder.UNORDERED);
            // check that no grandparent has parents
            for (ArtifactDetail grandparent : grandparents) {
                Set<ArtifactRange> greatGrandparents = grandparent.getMeta().getUsableBy();
                if (!greatGrandparents.isEmpty()) {
                    throw new InvalidArtifactException(String.format("Invalid artifact '%s'. Grandparents of artifacts cannot have parents. Grandparent '%s' has parents.", artifactId, grandparent.getDescriptor().getArtifactId()));
                }
                // assumes any grandparent will do
                if (parentArtifact == null && grandparentArtifact == null) {
                    grandparentArtifact = grandparent.getDescriptor();
                }
            }
        }
        // assumes any parent will do
        if (parentArtifact == null) {
            parentArtifact = parent.getDescriptor();
        }
    }
    List<ArtifactDescriptor> parentArtifactList = new ArrayList<>();
    parentArtifactList.add(parentArtifact);
    if (grandparentArtifact != null) {
        parentArtifactList.add(grandparentArtifact);
    }
    return parentArtifactList;
}
Also used : ArtifactRangeNotFoundException(io.cdap.cdap.common.ArtifactRangeNotFoundException) ArrayList(java.util.ArrayList) ArtifactRange(io.cdap.cdap.api.artifact.ArtifactRange) InvalidArtifactException(io.cdap.cdap.common.InvalidArtifactException)

Aggregations

ArtifactRange (io.cdap.cdap.api.artifact.ArtifactRange)107 ArtifactVersion (io.cdap.cdap.api.artifact.ArtifactVersion)77 Test (org.junit.Test)68 NamespaceId (io.cdap.cdap.proto.id.NamespaceId)54 PluginClass (io.cdap.cdap.api.plugin.PluginClass)42 Id (io.cdap.cdap.common.id.Id)40 ArtifactId (io.cdap.cdap.proto.id.ArtifactId)36 File (java.io.File)28 HashSet (java.util.HashSet)21 ImmutableSet (com.google.common.collect.ImmutableSet)20 ArtifactNotFoundException (io.cdap.cdap.common.ArtifactNotFoundException)20 Set (java.util.Set)20 Manifest (java.util.jar.Manifest)20 ArtifactId (io.cdap.cdap.api.artifact.ArtifactId)16 PluginNotExistsException (io.cdap.cdap.internal.app.runtime.plugin.PluginNotExistsException)14 PluginId (io.cdap.cdap.proto.id.PluginId)14 ApplicationClass (io.cdap.cdap.api.artifact.ApplicationClass)12 PluginPropertyField (io.cdap.cdap.api.plugin.PluginPropertyField)12 IOException (java.io.IOException)12 ArtifactDetail (io.cdap.cdap.internal.app.runtime.artifact.ArtifactDetail)10