You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by cz...@apache.org on 2021/12/15 12:44:05 UTC

[sling-org-apache-sling-feature-cpconverter] branch master updated: SLING-11003 : Provide option to store bundle symbolic name and version in metadata

This is an automated email from the ASF dual-hosted git repository.

cziegeler pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-feature-cpconverter.git


The following commit(s) were added to refs/heads/master by this push:
     new 8b7dd81  SLING-11003 : Provide option to store bundle symbolic name and version in metadata
8b7dd81 is described below

commit 8b7dd81932403987d274d6480df1e701e00c6a99
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Wed Dec 15 13:43:58 2021 +0100

    SLING-11003 : Provide option to store bundle symbolic name and version in metadata
---
 .../features/DefaultFeaturesManager.java           | 11 ++++---
 .../cpconverter/features/FeaturesManager.java      |  3 +-
 .../cpconverter/handlers/BundleEntryHandler.java   | 35 +++++++++++++++-------
 .../handlers/SlingInitialContentBundleHandler.java |  5 ++--
 .../BundleEntryHandleSlingInitialContentTest.java  | 34 ++++++++++++++++++---
 .../handlers/BundleEntryHandlerGAVTest.java        | 29 ++++++++++++++++--
 .../handlers/GavDeclarationsInBundleTest.java      |  2 +-
 7 files changed, 92 insertions(+), 27 deletions(-)

diff --git a/src/main/java/org/apache/sling/feature/cpconverter/features/DefaultFeaturesManager.java b/src/main/java/org/apache/sling/feature/cpconverter/features/DefaultFeaturesManager.java
index 2a2d016..c29a9fb 100644
--- a/src/main/java/org/apache/sling/feature/cpconverter/features/DefaultFeaturesManager.java
+++ b/src/main/java/org/apache/sling/feature/cpconverter/features/DefaultFeaturesManager.java
@@ -186,19 +186,18 @@ public class DefaultFeaturesManager implements FeaturesManager, PackagesEventsEm
 
     @Override
     public void addArtifact(@Nullable String runMode, @NotNull ArtifactId id) {
-        addArtifact(runMode, id, null);
+        requireNonNull(id, "Artifact can not be attached to a feature without specifying a valid ArtifactId.");
+        addArtifact(runMode, new Artifact(id), null);
     }
 
     @Override
-    public void addArtifact(@Nullable String runMode, @NotNull ArtifactId id, @Nullable Integer startOrder) {
-        requireNonNull(id, "Artifact can not be attached to a feature without specifying a valid ArtifactId.");
-
-        Artifact artifact = new Artifact(id);
+    public void addArtifact(@Nullable String runMode, @NotNull Artifact artifact, @Nullable Integer startOrder) {
+        requireNonNull(artifact, "Null artifact can not be attached to a feature.");
 
         Feature feature = getRunMode(runMode);
         Artifacts artifacts;
 
-        if (ZIP_TYPE.equals(id.getType())) {
+        if (ZIP_TYPE.equals(artifact.getId().getType())) {
             Extensions extensions = feature.getExtensions();
             Extension extension = extensions.getByName(CONTENT_PACKAGES);
 
diff --git a/src/main/java/org/apache/sling/feature/cpconverter/features/FeaturesManager.java b/src/main/java/org/apache/sling/feature/cpconverter/features/FeaturesManager.java
index 4bb25a7..13e0377 100644
--- a/src/main/java/org/apache/sling/feature/cpconverter/features/FeaturesManager.java
+++ b/src/main/java/org/apache/sling/feature/cpconverter/features/FeaturesManager.java
@@ -20,6 +20,7 @@ import java.io.IOException;
 import java.util.Dictionary;
 import java.util.Map;
 
+import org.apache.sling.feature.Artifact;
 import org.apache.sling.feature.ArtifactId;
 import org.apache.sling.feature.Configuration;
 import org.apache.sling.feature.Feature;
@@ -37,7 +38,7 @@ public interface FeaturesManager {
 
     void addArtifact(@Nullable String runMode, @NotNull ArtifactId id);
 
-    void addArtifact(@Nullable String runMode, @NotNull ArtifactId id, @Nullable Integer startOrder);
+    void addArtifact(@Nullable String runMode, @NotNull Artifact artifact, @Nullable Integer startOrder);
 
     void addAPIRegionExport(@Nullable String runMode, @NotNull String exportedPackage);
 
diff --git a/src/main/java/org/apache/sling/feature/cpconverter/handlers/BundleEntryHandler.java b/src/main/java/org/apache/sling/feature/cpconverter/handlers/BundleEntryHandler.java
index 248b97e..e6ff430 100644
--- a/src/main/java/org/apache/sling/feature/cpconverter/handlers/BundleEntryHandler.java
+++ b/src/main/java/org/apache/sling/feature/cpconverter/handlers/BundleEntryHandler.java
@@ -73,6 +73,7 @@ import org.apache.sling.contentparser.api.ParserOptions;
 import org.apache.sling.contentparser.json.JSONParserFeature;
 import org.apache.sling.contentparser.json.JSONParserOptions;
 import org.apache.sling.contentparser.json.internal.JSONContentParser;
+import org.apache.sling.feature.Artifact;
 import org.apache.sling.feature.ArtifactId;
 import org.apache.sling.feature.cpconverter.ContentPackage2FeatureModelConverter;
 import org.apache.sling.feature.cpconverter.ConverterException;
@@ -188,9 +189,10 @@ public class BundleEntryHandler extends AbstractRegexEntryHandler {
         throws ConverterException, IOException {
         try (JarFile jarFile = new JarFile(originalBundleFile.toFile())) {
             // first extract bundle metadata from JAR input stream
-            ArtifactId id = extractArtifactId(bundleName, jarFile);
+            Artifact artifact = extractFeatureArtifact(bundleName, jarFile);
+            ArtifactId id = artifact.getId();
 
-            try (InputStream strippedBundleInput = extractSlingInitialContent(path, originalBundleFile, id, jarFile, converter, runMode)) {
+            try (InputStream strippedBundleInput = extractSlingInitialContent(path, originalBundleFile, artifact, jarFile, converter, runMode)) {
                 if (strippedBundleInput != null && slingInitialContentPolicy == SlingInitialContentPolicy.EXTRACT_AND_REMOVE) {
                     id = id.changeVersion(id.getVersion() + "-" + ContentPackage2FeatureModelConverter.PACKAGE_CLASSIFIER);
                     Objects.requireNonNull(converter.getArtifactsDeployer()).deploy(new InputStreamArtifactWriter(strippedBundleInput), id);
@@ -200,7 +202,8 @@ public class BundleEntryHandler extends AbstractRegexEntryHandler {
                     }
                 }
             }
-            Objects.requireNonNull(converter.getFeaturesManager()).addArtifact(runMode, id, startLevel);
+            artifact = artifact.copy(id);
+            Objects.requireNonNull(converter.getFeaturesManager()).addArtifact(runMode, artifact, startLevel);
             String exportHeader = Objects.requireNonNull(jarFile.getManifest()).getMainAttributes().getValue(Constants.EXPORT_PACKAGE);
             if (exportHeader != null) {
                 for (Clause clause : Parser.parseHeader(exportHeader)) {
@@ -214,7 +217,7 @@ public class BundleEntryHandler extends AbstractRegexEntryHandler {
         return new Version(originalVersion.getMajor(), originalVersion.getMinor(), originalVersion.getMicro(), originalVersion.getQualifier() + "_" + ContentPackage2FeatureModelConverter.PACKAGE_CLASSIFIER);
     }
 
-    @Nullable InputStream extractSlingInitialContent(@NotNull String path, @NotNull Path bundlePath, @NotNull ArtifactId bundleArtifactId, @NotNull JarFile jarFile, @NotNull ContentPackage2FeatureModelConverter converter, @Nullable String runMode) throws IOException, ConverterException {
+    @Nullable InputStream extractSlingInitialContent(@NotNull String path, @NotNull Path bundlePath, @NotNull Artifact bundleArtifact, @NotNull JarFile jarFile, @NotNull ContentPackage2FeatureModelConverter converter, @Nullable String runMode) throws IOException, ConverterException {
         if (slingInitialContentPolicy == SlingInitialContentPolicy.KEEP) {
             return null;
         }
@@ -224,7 +227,7 @@ public class BundleEntryHandler extends AbstractRegexEntryHandler {
         if (pathEntries == null) {
             return null;
         }
-        logger.info("Extracting Sling-Initial-Content from '{}'", bundleArtifactId);
+        logger.info("Extracting Sling-Initial-Content from '{}'", bundleArtifact.getId());
         Collection<PathEntry> pathEntryList = new ArrayList<>();
         pathEntries.forEachRemaining(pathEntryList::add);
 
@@ -246,7 +249,7 @@ public class BundleEntryHandler extends AbstractRegexEntryHandler {
                 JarEntry jarEntry = e.nextElement();
                 if (!jarEntry.isDirectory()) {
                     try (InputStream input = jarFile.getInputStream(jarEntry)) {
-                        if (!extractSlingInitialContent(jarEntry, input, bundleArtifactId, pathEntryList, packageAssemblers, namespaceRegistry, converter)) {
+                        if (!extractSlingInitialContent(jarEntry, input, bundleArtifact, pathEntryList, packageAssemblers, namespaceRegistry, converter)) {
                             // skip manifest, as already written in the constructor (as first entry)
                             if (jarEntry.getName().equals(JarFile.MANIFEST_NAME)) {
                                 continue;
@@ -276,7 +279,7 @@ public class BundleEntryHandler extends AbstractRegexEntryHandler {
      * @return {@code true} in case the given entry was part of the initial content otherwise {@code false}
      * @throws Exception 
      */
-    boolean extractSlingInitialContent(@NotNull JarEntry jarEntry, @NotNull InputStream bundleFileInputStream, @NotNull ArtifactId bundleArtifactId, @NotNull Collection<PathEntry> pathEntries, @NotNull Map<PackageType, VaultPackageAssembler> packageAssemblers, @NotNull JcrNamespaceRegistry nsRegistry, @NotNull ContentPackage2FeatureModelConverter converter) throws IOException, ConverterException {
+    boolean extractSlingInitialContent(@NotNull JarEntry jarEntry, @NotNull InputStream bundleFileInputStream, @NotNull Artifact bundleArtifact, @NotNull Collection<PathEntry> pathEntries, @NotNull Map<PackageType, VaultPackageAssembler> packageAssemblers, @NotNull JcrNamespaceRegistry nsRegistry, @NotNull ContentPackage2FeatureModelConverter converter) throws IOException, ConverterException {
         final String entryName = jarEntry.getName();
         // check if current JAR entry is initial content
         Optional<PathEntry> pathEntry = pathEntries.stream().filter(p -> entryName.startsWith(p.getPath())).findFirst();
@@ -313,7 +316,7 @@ public class BundleEntryHandler extends AbstractRegexEntryHandler {
             try (Archive virtualArchive = SingleFileArchive.fromPathOrInputStream(tmpDocViewInputFile, bundleFileInputStream, 
                     () -> Files.createTempFile(converter.getTempDirectory().toPath(), "initial-content", Text.getName(jarEntry.getName())), contentPackageEntryPath)) {
                 // in which content package should this end up?
-                VaultPackageAssembler packageAssembler = initPackageAssemblerForPath(bundleArtifactId, repositoryPath, pathEntry.get(), packageAssemblers, converter);
+                VaultPackageAssembler packageAssembler = initPackageAssemblerForPath(bundleArtifact.getId(), repositoryPath, pathEntry.get(), packageAssemblers, converter);
                 if (tmpDocViewInputFile != null) {
                     packageAssembler.addEntry(contentPackageEntryPath, tmpDocViewInputFile.toFile());
                 } else {
@@ -436,7 +439,7 @@ public class BundleEntryHandler extends AbstractRegexEntryHandler {
         }
     }
 
-    protected @NotNull ArtifactId extractArtifactId(@NotNull String bundleName, @NotNull JarFile jarFile) throws IOException {
+    protected @NotNull Artifact extractFeatureArtifact(@NotNull String bundleName, @NotNull JarFile jarFile) throws IOException {
         String artifactId = null;
         String version = null;
         String groupId = null;
@@ -514,7 +517,19 @@ public class BundleEntryHandler extends AbstractRegexEntryHandler {
             version = osgiVersion.getMajor() + "." + osgiVersion.getMinor() + "." + osgiVersion.getMicro() + (osgiVersion.getQualifier().isEmpty() ? "" : "-" + osgiVersion.getQualifier());
         }
 
-        return new ArtifactId(groupId, artifactId, version, classifier, JAR_TYPE);
+        // create artifact and store symbolic name and version in metadata
+        final Artifact result = new Artifact(new ArtifactId(groupId, artifactId, version, classifier, JAR_TYPE));
+        setMetadataFromManifest(jarFile.getManifest(), Constants.BUNDLE_VERSION, result);
+        setMetadataFromManifest(jarFile.getManifest(), Constants.BUNDLE_SYMBOLICNAME, result);
+
+        return result;
+    }
+
+    private static void setMetadataFromManifest(@NotNull Manifest manifest, @NotNull String name, @NotNull Artifact artifact) {
+        String value = manifest.getMainAttributes().getValue(name);
+        if (value != null) {
+            artifact.getMetadata().put(name, value);
+        }
     }
 
     private static @NotNull String getCheckedProperty(@NotNull Manifest manifest, @NotNull String name) {
diff --git a/src/main/java/org/apache/sling/feature/cpconverter/handlers/SlingInitialContentBundleHandler.java b/src/main/java/org/apache/sling/feature/cpconverter/handlers/SlingInitialContentBundleHandler.java
index 829b89d..64330d0 100644
--- a/src/main/java/org/apache/sling/feature/cpconverter/handlers/SlingInitialContentBundleHandler.java
+++ b/src/main/java/org/apache/sling/feature/cpconverter/handlers/SlingInitialContentBundleHandler.java
@@ -17,6 +17,7 @@
 package org.apache.sling.feature.cpconverter.handlers;
 
 import org.apache.jackrabbit.vault.packaging.PackageType;
+import org.apache.sling.feature.Artifact;
 import org.apache.sling.feature.ArtifactId;
 import org.apache.sling.feature.cpconverter.ContentPackage2FeatureModelConverter;
 import org.apache.sling.feature.cpconverter.ConverterException;
@@ -43,9 +44,9 @@ public class SlingInitialContentBundleHandler extends BundleEntryHandler {
     void processBundleInputStream(@NotNull String path, @NotNull Path originalBundleFile, @NotNull String bundleName, @Nullable String runMode, @Nullable Integer startLevel, @NotNull ContentPackage2FeatureModelConverter converter) throws IOException, ConverterException {
         try (JarFile jarFile = new JarFile(originalBundleFile.toFile())) {
             // first extract bundle metadata from JAR input stream
-            ArtifactId id = extractArtifactId(bundleName, jarFile);
+            Artifact artifact = extractFeatureArtifact(bundleName, jarFile);
 
-            try (InputStream ignored = extractSlingInitialContent(path, originalBundleFile, id, jarFile, converter, runMode)) {}
+            try (InputStream ignored = extractSlingInitialContent(path, originalBundleFile, artifact, jarFile, converter, runMode)) {}
         }
     }
 
diff --git a/src/test/java/org/apache/sling/feature/cpconverter/handlers/BundleEntryHandleSlingInitialContentTest.java b/src/test/java/org/apache/sling/feature/cpconverter/handlers/BundleEntryHandleSlingInitialContentTest.java
index 0a124be..1c72c82 100644
--- a/src/test/java/org/apache/sling/feature/cpconverter/handlers/BundleEntryHandleSlingInitialContentTest.java
+++ b/src/test/java/org/apache/sling/feature/cpconverter/handlers/BundleEntryHandleSlingInitialContentTest.java
@@ -35,6 +35,7 @@ import org.apache.jackrabbit.vault.packaging.PackageId;
 import org.apache.jackrabbit.vault.packaging.PackageProperties;
 import org.apache.jackrabbit.vault.packaging.VaultPackage;
 import org.apache.jackrabbit.vault.packaging.impl.PackageManagerImpl;
+import org.apache.sling.feature.Artifact;
 import org.apache.sling.feature.ArtifactId;
 import org.apache.sling.feature.Configuration;
 import org.apache.sling.feature.cpconverter.ContentPackage2FeatureModelConverter.SlingInitialContentPolicy;
@@ -104,7 +105,13 @@ public class BundleEntryHandleSlingInitialContentTest extends AbstractBundleEntr
         // verify nothing else has been deployed
         assertEquals(2, targetFolder.list().length);
         // verify changed id
-        Mockito.verify(featuresManager).addArtifact(null, ArtifactId.fromMvnId("io.wcm:io.wcm.handler.media:1.11.6-cp2fm-converted"), null);
+        ArgumentCaptor<Artifact> captor = ArgumentCaptor.forClass(Artifact.class);
+        Mockito.verify(featuresManager).addArtifact(Mockito.isNull(), captor.capture(), Mockito.isNull());
+        final Artifact result = captor.getValue();
+        assertNotNull(result);
+        assertEquals(ArtifactId.fromMvnId("io.wcm:io.wcm.handler.media:1.11.6-cp2fm-converted"), result.getId());
+        assertEquals("io.wcm.handler.media", result.getMetadata().get(Constants.BUNDLE_SYMBOLICNAME));
+        assertEquals("1.11.6", result.getMetadata().get(Constants.BUNDLE_VERSION));
     }
 
 
@@ -153,7 +160,13 @@ public class BundleEntryHandleSlingInitialContentTest extends AbstractBundleEntr
         // verify nothing else has been deployed
         assertEquals(2, targetFolder.list().length);
         // verify changed id
-        Mockito.verify(featuresManager).addArtifact(null, ArtifactId.fromMvnId("com.mysite:mysite.core:1.0.0-SNAPSHOT-cp2fm-converted"), null);
+        ArgumentCaptor<Artifact> captor = ArgumentCaptor.forClass(Artifact.class);
+        Mockito.verify(featuresManager).addArtifact(Mockito.isNull(), captor.capture(), Mockito.isNull());
+        final Artifact result = captor.getValue();
+        assertNotNull(result);
+        assertEquals(ArtifactId.fromMvnId("com.mysite:mysite.core:1.0.0-SNAPSHOT-cp2fm-converted"), result.getId());
+        assertEquals("mysite.core", result.getMetadata().get(Constants.BUNDLE_SYMBOLICNAME));
+        assertEquals("1.0.0.SNAPSHOT", result.getMetadata().get(Constants.BUNDLE_VERSION));
     }
 
     @Test
@@ -172,7 +185,14 @@ public class BundleEntryHandleSlingInitialContentTest extends AbstractBundleEntr
         handler.setSlingInitialContentPolicy(SlingInitialContentPolicy.EXTRACT_AND_REMOVE);
         handler.handle("/jcr_root/apps/gav/install/composum-nodes-config-2.5.3.jar", archive, entry, converter);
         // modified bundle
-        Mockito.verify(featuresManager).addArtifact(null, ArtifactId.fromMvnId("com.composum.nodes:composum-nodes-config:2.5.3-cp2fm-converted"), null);
+        ArgumentCaptor<Artifact> captor = ArgumentCaptor.forClass(Artifact.class);
+        Mockito.verify(featuresManager).addArtifact(Mockito.isNull(), captor.capture(), Mockito.isNull());
+        final Artifact result = captor.getValue();
+        assertNotNull(result);
+        assertEquals(ArtifactId.fromMvnId("com.composum.nodes:composum-nodes-config:2.5.3-cp2fm-converted"), result.getId());
+        assertEquals("com.composum.nodes.config", result.getMetadata().get(Constants.BUNDLE_SYMBOLICNAME));
+        assertEquals("2.5.3", result.getMetadata().get(Constants.BUNDLE_VERSION));
+
         // need to use ArgumentCaptur to properly compare string arrays
         Mockito.verify(featuresManager).addConfiguration(ArgumentMatchers.isNull(), cfgCaptor.capture(), ArgumentMatchers.eq("/jcr_root/libs/composum/nodes/install/org.apache.sling.jcr.base.internal.LoginAdminWhitelist.fragment-composum_core_v2.config"), dictionaryCaptor.capture());
         assertEquals("composum_core", dictionaryCaptor.getValue().get("whitelist.name"));
@@ -199,7 +219,13 @@ public class BundleEntryHandleSlingInitialContentTest extends AbstractBundleEntr
         handler.setSlingInitialContentPolicy(SlingInitialContentPolicy.EXTRACT_AND_KEEP);
         handler.handle("/jcr_root/apps/gav/install/composum-nodes-config-2.5.3.jar", archive, entry, converter);
         // original bundle
-        Mockito.verify(featuresManager).addArtifact(null, ArtifactId.fromMvnId("com.composum.nodes:composum-nodes-config:2.5.3"), null);
+        ArgumentCaptor<Artifact> captor = ArgumentCaptor.forClass(Artifact.class);
+        Mockito.verify(featuresManager).addArtifact(Mockito.isNull(), captor.capture(), Mockito.isNull());
+        final Artifact result = captor.getValue();
+        assertNotNull(result);
+        assertEquals(ArtifactId.fromMvnId("com.composum.nodes:composum-nodes-config:2.5.3"), result.getId());
+        assertEquals("com.composum.nodes.config", result.getMetadata().get(Constants.BUNDLE_SYMBOLICNAME));
+        assertEquals("2.5.3", result.getMetadata().get(Constants.BUNDLE_VERSION));
         // need to use ArgumentCaptur to properly compare string arrays
         Mockito.verify(featuresManager).addConfiguration(ArgumentMatchers.isNull(),
              cfgCaptor.capture(),
diff --git a/src/test/java/org/apache/sling/feature/cpconverter/handlers/BundleEntryHandlerGAVTest.java b/src/test/java/org/apache/sling/feature/cpconverter/handlers/BundleEntryHandlerGAVTest.java
index a0414ca..820e737 100644
--- a/src/test/java/org/apache/sling/feature/cpconverter/handlers/BundleEntryHandlerGAVTest.java
+++ b/src/test/java/org/apache/sling/feature/cpconverter/handlers/BundleEntryHandlerGAVTest.java
@@ -16,15 +16,20 @@
  */
 package org.apache.sling.feature.cpconverter.handlers;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertThrows;
 import static org.mockito.Mockito.when;
 
+import org.apache.sling.feature.Artifact;
 import org.apache.sling.feature.ArtifactId;
 import org.apache.sling.feature.cpconverter.ConverterException;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
 import org.mockito.Mockito;
 import org.mockito.junit.MockitoJUnitRunner;
+import org.osgi.framework.Constants;
 
 @RunWith(MockitoJUnitRunner.class)
 public class BundleEntryHandlerGAVTest extends AbstractBundleEntryHandlerTest {
@@ -33,21 +38,39 @@ public class BundleEntryHandlerGAVTest extends AbstractBundleEntryHandlerTest {
     public void testGAV() throws Exception {
         setUpArchive("/jcr_root/apps/gav/install/core-1.0.0-SNAPSHOT.jar", "core-1.0.0-SNAPSHOT.jar");
         handler.handle("/jcr_root/apps/gav/install/core-1.0.0-SNAPSHOT.jar", archive, entry, converter);
-        Mockito.verify(featuresManager).addArtifact(null, ArtifactId.fromMvnId("com.madplanet.sling.cp2sf:core:1.0.0-SNAPSHOT"), null);
+        ArgumentCaptor<Artifact> captor = ArgumentCaptor.forClass(Artifact.class);
+        Mockito.verify(featuresManager).addArtifact(Mockito.isNull(), captor.capture(), Mockito.isNull());
+        final Artifact result = captor.getValue();
+        assertNotNull(result);
+        assertEquals(ArtifactId.fromMvnId("com.madplanet.sling.cp2sf:core:1.0.0-SNAPSHOT"), result.getId());
+        assertEquals("com.madplanet.sling.cp2sf.core", result.getMetadata().get(Constants.BUNDLE_SYMBOLICNAME));
+        assertEquals("1.0.0.SNAPSHOT", result.getMetadata().get(Constants.BUNDLE_VERSION));
     }
 
     @Test
     public void testGAVwithPom() throws Exception{
         setUpArchive("/jcr_root/apps/gav/install/org.osgi.service.jdbc-1.0.0.jar", "org.osgi.service.jdbc-1.0.0.jar");
         handler.handle("/jcr_root/apps/gav/install/org.osgi.service.jdbc-1.0.0.jar", archive, entry, converter);
-        Mockito.verify(featuresManager).addArtifact(null, ArtifactId.fromMvnId("org.osgi:org.osgi.service.jdbc:1.0.0"), null);
+        ArgumentCaptor<Artifact> captor = ArgumentCaptor.forClass(Artifact.class);
+        Mockito.verify(featuresManager).addArtifact(Mockito.isNull(), captor.capture(), Mockito.isNull());
+        final Artifact result = captor.getValue();
+        assertNotNull(result);
+        assertEquals(ArtifactId.fromMvnId("org.osgi:org.osgi.service.jdbc:1.0.0"), result.getId());
+        assertEquals("org.osgi.service.jdbc", result.getMetadata().get(Constants.BUNDLE_SYMBOLICNAME));
+        assertEquals("1.0.0.201505202023", result.getMetadata().get(Constants.BUNDLE_VERSION));
     }
 
     @Test
     public void testNoGAV() throws Exception {
         setUpArchive("/jcr_root/apps/gav/install/org.osgi.service.jdbc-1.0.0-nogav.jar", "org.osgi.service.jdbc-1.0.0-nogav.jar");
         handler.handle("/jcr_root/apps/gav/install/org.osgi.service.jdbc-1.0.0-nogav.jar", archive, entry, converter);
-        Mockito.verify(featuresManager).addArtifact(null, ArtifactId.fromMvnId("org.osgi.service:jdbc:1.0.0-201505202023"), null);
+        ArgumentCaptor<Artifact> captor = ArgumentCaptor.forClass(Artifact.class);
+        Mockito.verify(featuresManager).addArtifact(Mockito.isNull(), captor.capture(), Mockito.isNull());
+        final Artifact result = captor.getValue();
+        assertNotNull(result);
+        assertEquals(ArtifactId.fromMvnId("org.osgi.service:jdbc:1.0.0-201505202023"), result.getId());
+        assertEquals("org.osgi.service.jdbc", result.getMetadata().get(Constants.BUNDLE_SYMBOLICNAME));
+        assertEquals("1.0.0.201505202023", result.getMetadata().get(Constants.BUNDLE_VERSION));
     }
 
     @Test
diff --git a/src/test/java/org/apache/sling/feature/cpconverter/handlers/GavDeclarationsInBundleTest.java b/src/test/java/org/apache/sling/feature/cpconverter/handlers/GavDeclarationsInBundleTest.java
index 237f51a..ebd9afc 100644
--- a/src/test/java/org/apache/sling/feature/cpconverter/handlers/GavDeclarationsInBundleTest.java
+++ b/src/test/java/org/apache/sling/feature/cpconverter/handlers/GavDeclarationsInBundleTest.java
@@ -56,7 +56,7 @@ public class GavDeclarationsInBundleTest {
         BundleEntryHandler bundleEntryHandler = new BundleEntryHandler();
 
         try (JarFile jarFile = new JarFile(new File(getClass().getResource(resourceName).toURI()))) {
-            ArtifactId artifactId = bundleEntryHandler.extractArtifactId(bundleName, jarFile);
+            ArtifactId artifactId = bundleEntryHandler.extractFeatureArtifact(bundleName, jarFile).getId();
             assertEquals(new ArtifactId(expectedGroupId, expectedArtifactId, expectedVersion, expectedClassifier, "jar"), artifactId);
         }
     }