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 2020/04/29 10:44:26 UTC

[sling-org-apache-sling-installer-factory-feature] 07/08: Add feature region support

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-installer-factory-feature.git

commit 35fee328c31d0243fe14c6e4dca44a34c525667d
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Thu Apr 23 17:11:07 2020 +0200

    Add feature region support
---
 bnd.bnd                                            |   2 +
 pom.xml                                            |  30 +++---
 .../model/impl/FeatureModelInstallerPlugin.java    |  12 +--
 .../factory/model/impl/InstallContext.java         |  14 +--
 .../model/impl/InstallFeatureModelTask.java        | 119 ++++++++++-----------
 5 files changed, 74 insertions(+), 103 deletions(-)

diff --git a/bnd.bnd b/bnd.bnd
new file mode 100644
index 0000000..d2c832f
--- /dev/null
+++ b/bnd.bnd
@@ -0,0 +1,2 @@
+-includeresource: @org.apache.sling.feature.extension.apiregions-[0-9.]*.jar!/org/apache/sling/feature/extension/apiregions/launcher/LauncherProperties.*
+Conditional-Package: org.apache.sling.feature.extension.apiregions.api
diff --git a/pom.xml b/pom.xml
index fe8398e..76a1193 100644
--- a/pom.xml
+++ b/pom.xml
@@ -79,6 +79,12 @@
             <artifactId>osgi.core</artifactId>
         </dependency>
         <dependency>
+            <groupId>org.apache.geronimo.specs</groupId>
+            <artifactId>geronimo-json_1.1_spec</artifactId>
+            <version>1.2</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
             <groupId>org.slf4j</groupId>
             <artifactId>slf4j-api</artifactId>
         </dependency>
@@ -94,24 +100,6 @@
         </dependency>
         <dependency>
             <groupId>org.apache.sling</groupId>
-            <artifactId>org.apache.sling.jcr.api</artifactId>
-            <version>2.4.0</version>
-            <scope>provided</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.sling</groupId>
-            <artifactId>org.apache.sling.jcr.repoinit</artifactId>
-            <version>1.1.0</version>
-            <scope>provided</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.sling</groupId>
-            <artifactId>org.apache.sling.repoinit.parser</artifactId>
-            <version>1.1.0</version>
-            <scope>provided</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.sling</groupId>
             <artifactId>org.apache.sling.feature</artifactId>
             <version>1.1.8</version>
             <scope>provided</scope>
@@ -122,6 +110,12 @@
             <version>1.3.0</version>
             <scope>provided</scope>
         </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.feature.extension.apiregions</artifactId>
+            <version>1.1.4</version>
+            <scope>provided</scope>
+        </dependency>
    <!-- Testing -->
         <dependency>
             <groupId>junit</groupId>
diff --git a/src/main/java/org/apache/sling/installer/factory/model/impl/FeatureModelInstallerPlugin.java b/src/main/java/org/apache/sling/installer/factory/model/impl/FeatureModelInstallerPlugin.java
index fb34de2..3c1b870 100644
--- a/src/main/java/org/apache/sling/installer/factory/model/impl/FeatureModelInstallerPlugin.java
+++ b/src/main/java/org/apache/sling/installer/factory/model/impl/FeatureModelInstallerPlugin.java
@@ -94,15 +94,6 @@ public class FeatureModelInstallerPlugin implements InstallTaskFactory, Resource
     /** Logger. */
     private final Logger logger = LoggerFactory.getLogger(this.getClass());
 
-//    @Reference
-//    private SlingRepository repository;
-
-//    @Reference
-//    private JcrRepoInitOpsProcessor repoInitProcessor;
-
-//    @Reference
-//    private RepoInitParser repoInitParser;
-
     private final BundleContext bundleContext;
 
     private final ArtifactManager artifactManager;
@@ -234,8 +225,7 @@ public class FeatureModelInstallerPlugin implements InstallTaskFactory, Resource
         if (rsrc.getState() == ResourceState.UNINSTALL ) {
             return new UninstallFeatureModelTask(group, bundleContext);
         }
-        final InstallContext ctx = new InstallContext(//this.repository, this.repoInitProcessor, this.repoInitParser,
-                this.artifactManager, this.storageDirectory);
+        final InstallContext ctx = new InstallContext(this.artifactManager, this.storageDirectory);
         return new InstallFeatureModelTask(group,
                 ctx, this.bundleContext);
     }
diff --git a/src/main/java/org/apache/sling/installer/factory/model/impl/InstallContext.java b/src/main/java/org/apache/sling/installer/factory/model/impl/InstallContext.java
index 9f7f42f..8408f91 100644
--- a/src/main/java/org/apache/sling/installer/factory/model/impl/InstallContext.java
+++ b/src/main/java/org/apache/sling/installer/factory/model/impl/InstallContext.java
@@ -24,23 +24,11 @@ import org.apache.sling.feature.io.artifacts.ArtifactManager;
 
 public class InstallContext {
 
-//    public final SlingRepository repository;
-
-//    public final JcrRepoInitOpsProcessor repoInitProcessor;
-
-//    public final RepoInitParser repoInitParser;
-
     public final ArtifactManager artifactManager;
 
     public final File storageDirectory;
 
-    public InstallContext(//final SlingRepository repository,
-//            final JcrRepoInitOpsProcessor repoInitProcessor,
-//            final RepoInitParser repoInitParser,
-            final ArtifactManager artifactManager, final File storageDirectory) {
-//        this.repository = repository;
-//        this.repoInitProcessor = repoInitProcessor;
-//        this.repoInitParser = repoInitParser;
+    public InstallContext(final ArtifactManager artifactManager, final File storageDirectory) {
         this.artifactManager = artifactManager;
         this.storageDirectory = storageDirectory;
     }
diff --git a/src/main/java/org/apache/sling/installer/factory/model/impl/InstallFeatureModelTask.java b/src/main/java/org/apache/sling/installer/factory/model/impl/InstallFeatureModelTask.java
index efce876..f60c0cb 100644
--- a/src/main/java/org/apache/sling/installer/factory/model/impl/InstallFeatureModelTask.java
+++ b/src/main/java/org/apache/sling/installer/factory/model/impl/InstallFeatureModelTask.java
@@ -38,6 +38,8 @@ import org.apache.sling.feature.Configuration;
 import org.apache.sling.feature.Extension;
 import org.apache.sling.feature.ExtensionType;
 import org.apache.sling.feature.Feature;
+import org.apache.sling.feature.extension.apiregions.api.ApiRegions;
+import org.apache.sling.feature.extension.apiregions.launcher.LauncherProperties;
 import org.apache.sling.feature.io.archive.ArchiveReader;
 import org.apache.sling.feature.io.artifacts.ArtifactHandler;
 import org.apache.sling.feature.io.json.FeatureJSONReader;
@@ -54,6 +56,14 @@ import org.osgi.framework.BundleContext;
  */
 public class InstallFeatureModelTask extends AbstractFeatureModelTask {
 
+    private static final String PROP_idbsnver = "mapping.bundleid.bsnver";
+    private static final String PROP_bundleFeatures = "mapping.bundleid.features";
+    private static final String PROP_featureRegions = "mapping.featureid.regions";
+    private static final String PROP_regionPackage = "mapping.region.packages";
+
+    private static final String REGION_FACTORY_PID = "org.apache.sling.feature.apiregions.factory~";
+    private static final String REPOINIT_FACTORY_PID = "org.apache.sling.jcr.repoinit.RepositoryInitializer~";
+
     private final InstallContext installContext;
 
     public InstallFeatureModelTask(final TaskResourceGroup group,
@@ -62,7 +72,6 @@ public class InstallFeatureModelTask extends AbstractFeatureModelTask {
         this.installContext = installContext;
     }
 
-    @SuppressWarnings("deprecation")
     @Override
     public void execute(final InstallationContext ctx) {
         try {
@@ -74,49 +83,17 @@ public class InstallFeatureModelTask extends AbstractFeatureModelTask {
                 this.getResourceGroup().setFinishState(ResourceState.IGNORED);
             } else {
                 boolean success = false;
-                final Result result = this.transform(featureJson, resource);
+                final List<InstallableResource> result = this.transform(featureJson, resource);
                 if (result == null) {
                     ctx.log("Unable to install feature model resource {} : unable to create resources", resource);
                     this.getResourceGroup().setFinishState(ResourceState.IGNORED);
                 } else {
-                    // repo init first
-/*                    if (result.repoinit != null) {
-                        List<Operation> ops = null;
-                        try (final Reader r = new StringReader(result.repoinit)) {
-                            ops = this.installContext.repoInitParser.parse(r);
-                        } catch (final IOException | RepoInitParsingException e) {
-                            logger.error("Unable to parse repoinit text.", e);
-                            ctx.log("Unable to install feature model resource {} : unable parse repoinit text.",
-                                    resource);
-                            this.getResourceGroup().setFinishState(ResourceState.IGNORED);
-                            return;
-                        }
-
-                        // login admin is required for repo init
-                        Session session = null;
-                        try {
-                            session = this.installContext.repository.loginAdministrative(null);
-                            this.installContext.repoInitProcessor.apply(session, ops);
-                            session.save();
-                        } catch (final RepositoryException re) {
-                            logger.error("Unable to process repoinit text.", re);
-                            ctx.log("Unable to install feature model resource {} : unable to process repoinit text.",
-                                    resource);
-                            this.getResourceGroup().setFinishState(ResourceState.IGNORED);
-                            return;
-
-                        } finally {
-                            if (session != null) {
-                                session.logout();
-                            }
-                        }
-                    }*/
-                    if (!result.resources.isEmpty()) {
+                    if (!result.isEmpty()) {
                         final OsgiInstaller installer = this.getService(OsgiInstaller.class);
                         if (installer != null) {
                             installer.registerResources(
                                     getScheme(resource),
-                                    result.resources.toArray(new InstallableResource[result.resources.size()]));
+                                    result.toArray(new InstallableResource[result.size()]));
                         } else {
                             ctx.log("Unable to install feature model resource {} : unable to get OSGi installer",
                                     resource);
@@ -136,16 +113,11 @@ public class InstallFeatureModelTask extends AbstractFeatureModelTask {
         }
     }
 
-    public static final class Result {
-        public final List<InstallableResource> resources = new ArrayList<>();
-//        public String repoinit;
-    }
-
     private File getArtifactFile(final File baseDir, final ArtifactId id) {
         return new File(baseDir, id.toMvnId().replace('/', File.separatorChar));
     }
 
-    private Result transform(final String featureJson,
+    private List<InstallableResource> transform(final String featureJson,
             final TaskResource rsrc) {
         Feature feature = null;
         try (final Reader reader = new StringReader(featureJson)) {
@@ -157,8 +129,26 @@ public class InstallFeatureModelTask extends AbstractFeatureModelTask {
             return null;
         }
 
+        final List<InstallableResource> result = new ArrayList<>();
+        // configurations
+        for (final Configuration cfg : feature.getConfigurations()) {
+            result.add(new InstallableResource("/".concat(cfg.getPid()).concat(".config"), null,
+                    cfg.getConfigurationProperties(), null, InstallableResource.TYPE_CONFIG, null));
+        }
+
+        // repoinit
+        final Extension repoInit = feature.getExtensions().getByName(Extension.EXTENSION_NAME_REPOINIT);
+        if (repoInit != null && repoInit.getType() == ExtensionType.TEXT) {
+            final String configPid = REPOINIT_FACTORY_PID.concat(feature.getId().toMvnName().replace('-', '_'));
+            final Dictionary<String, Object> props = new Hashtable<>();
+            props.put("scripts", repoInit.getText());
+
+            result.add(new InstallableResource("/".concat(configPid).concat(".config"), null,
+                    props, null, InstallableResource.TYPE_CONFIG, null));
+        }
+
+        // extract artifacts
         if (this.installContext.storageDirectory != null) {
-            // extract artifacts
             final byte[] buffer = new byte[1024*1024*256];
 
             try ( final InputStream is = rsrc.getInputStream() ) {
@@ -184,13 +174,35 @@ public class InstallFeatureModelTask extends AbstractFeatureModelTask {
             }
         }
 
+        // api regions
+        final Extension regionExt = feature.getExtensions().getByName(ApiRegions.EXTENSION_NAME);
+        if ( regionExt != null ) {
+            try {
+                final ApiRegions regions = ApiRegions.parse(regionExt.getJSONStructure().asJsonArray());
+
+                final String configPid = REGION_FACTORY_PID.concat(feature.getId().toMvnName().replace('-', '_'));
+                final Dictionary<String, Object> props = new Hashtable<>();
+                props.put(PROP_idbsnver, LauncherProperties.getBundleIDtoBSNandVersionMap(feature, this.installContext.artifactManager));
+                props.put(PROP_bundleFeatures, LauncherProperties.getBundleIDtoFeaturesMap(feature));
+                props.put(PROP_featureRegions, LauncherProperties.getFeatureIDtoRegionsMap(regions));
+                props.put(PROP_regionPackage, LauncherProperties.getRegionNametoPackagesMap(regions));
 
-        final Result result = new Result();
+                result.add(new InstallableResource("/".concat(configPid).concat(".config"), null,
+                        props, null, InstallableResource.TYPE_CONFIG, null));
+            } catch (final IOException ioe) {
+                logger.warn("Unable to parse region information " + feature.getId().toMvnId(), ioe);
+                return null;
+            }
+        }
+
+        // bundles
         for (final Artifact bundle : feature.getBundles()) {
             if (!addArtifact(bundle, result)) {
                 return null;
             }
         }
+
+        // content packages
         final Extension ext = feature.getExtensions().getByName(Extension.EXTENSION_NAME_CONTENT_PACKAGES);
         if (ext != null && ext.getType() == ExtensionType.ARTIFACTS) {
             for (final Artifact artifact : ext.getArtifacts()) {
@@ -198,26 +210,11 @@ public class InstallFeatureModelTask extends AbstractFeatureModelTask {
             }
         }
 
-        for (final Configuration cfg : feature.getConfigurations()) {
-            result.resources.add(new InstallableResource("/".concat(cfg.getPid()).concat(".config"), null,
-                    cfg.getConfigurationProperties(), null, InstallableResource.TYPE_CONFIG, null));
-        }
-
-        final Extension repoInit = feature.getExtensions().getByName(Extension.EXTENSION_NAME_REPOINIT);
-        if (repoInit != null && repoInit.getType() == ExtensionType.TEXT) {
-//            result.repoinit = repoInit.getText();
-            final String configPid = "org.apache.sling.jcr.repoinit.RepositoryInitializer~".concat(feature.getId().toMvnName().replace('-', '_'));
-            final Dictionary<String, Object> props = new Hashtable<>();
-            props.put("scripts", repoInit.getText());
-
-            result.resources.add(new InstallableResource("/".concat(configPid).concat(".config"), null,
-                    props, null, InstallableResource.TYPE_CONFIG, null));
-        }
         return result;
     }
 
     private boolean addArtifact(final Artifact artifact,
-            final Result result) {
+            final List<InstallableResource> result) {
         File artifactFile = (this.installContext.storageDirectory == null ? null
                 : getArtifactFile(this.installContext.storageDirectory, artifact.getId()));
         ArtifactHandler handler;
@@ -250,7 +247,7 @@ public class InstallFeatureModelTask extends AbstractFeatureModelTask {
             }
             dict.put(InstallableResource.RESOURCE_URI_HINT, handler.getLocalURL().toString());
 
-            result.resources.add(new InstallableResource("/".concat(artifact.getId().toMvnName()), is, dict, digest,
+            result.add(new InstallableResource("/".concat(artifact.getId().toMvnName()), is, dict, digest,
                     InstallableResource.TYPE_FILE, null));
         } catch (final IOException ioe) {
             logger.warn("Unable to read artifact " + handler.getLocalURL(), ioe);