You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by cs...@apache.org on 2019/08/02 08:49:45 UTC

[sling-org-apache-sling-distribution-journal] 01/01: GRANITE-26607 - Add package extraction logic

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

cschneider pushed a commit to branch GRANITE-26607
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-distribution-journal.git

commit 2689fad704cf69bcbed855b297313125e76149c5
Author: Christian Schneider <cs...@adobe.com>
AuthorDate: Fri Aug 2 10:49:06 2019 +0200

    GRANITE-26607 - Add package extraction logic
---
 .../impl/subscriber/ContentPackageExtractor.java   | 101 +++++++++++++++++++++
 .../impl/subscriber/DistributionSubscriber.java    |   8 ++
 .../journal/impl/subscriber/PackageHandling.java   |  23 +++++
 .../impl/subscriber/SubscriberConfiguration.java   |   3 +
 4 files changed, 135 insertions(+)

diff --git a/src/main/java/org/apache/sling/distribution/journal/impl/subscriber/ContentPackageExtractor.java b/src/main/java/org/apache/sling/distribution/journal/impl/subscriber/ContentPackageExtractor.java
new file mode 100644
index 0000000..3a9a215
--- /dev/null
+++ b/src/main/java/org/apache/sling/distribution/journal/impl/subscriber/ContentPackageExtractor.java
@@ -0,0 +1,101 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.distribution.journal.impl.subscriber;
+
+import static java.util.Objects.requireNonNull;
+
+import java.util.List;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.nodetype.NodeType;
+
+import org.apache.jackrabbit.vault.fs.io.ImportOptions;
+import org.apache.jackrabbit.vault.packaging.JcrPackage;
+import org.apache.jackrabbit.vault.packaging.JcrPackageManager;
+import org.apache.jackrabbit.vault.packaging.Packaging;
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ResourceResolver;
+import org.osgi.service.component.annotations.Component;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Hook that can be added to a DistributionPackageBuilder.
+ * Each distribution package is inspected for possible content packages in /etc/packages.
+ * Such content packages are installed via the Packaging service.
+ */
+@Component
+public class ContentPackageExtractor {
+    private static final String PACKAGE_BASE_PATH = "/etc/packages/";
+
+    private Logger log = LoggerFactory.getLogger(this.getClass());
+
+    private Packaging packageService;
+    private PackageHandling packageHandling;
+    
+    public ContentPackageExtractor(Packaging packageService, PackageHandling packageHandling) {
+        this.packageService = packageService;
+        this.packageHandling = packageHandling;
+    }
+    
+    public void handle(ResourceResolver resourceResolver, List<String> paths) {
+        requireNonNull(resourceResolver, "Must provide resourceResolver");
+        if (packageHandling == PackageHandling.Off) {
+            return;
+        }
+        log.info("Scanning imported nodes for packages to install.");
+        for (String path : paths) {
+            try {
+                Resource resource = resourceResolver.getResource(path);
+                if (resource != null) {
+                    Node node = resource.adaptTo(Node.class);
+                    if (isContentPackage(path, node)) {
+                        installPackage(path, node);
+                    }
+                }
+            } catch (RepositoryException e) {
+                log.warn("Error trying check if {} contains a content package to extract.", path, e);
+            }
+        }
+    }
+
+    private boolean isContentPackage(String path, Node node) throws RepositoryException {
+        return path.startsWith(PACKAGE_BASE_PATH) && node.isNodeType(NodeType.NT_FILE);
+    }
+
+    private void installPackage(String path, Node node) {
+        try {
+            log.info("Content package received at {}. Starting import.\n", path);
+            Session session = node.getSession();
+            JcrPackageManager packMgr = packageService.getPackageManager(session);
+            JcrPackage pack = packMgr.open(node);
+            ImportOptions opts = new ImportOptions();
+            if (packageHandling == PackageHandling.Extract) {
+                pack.extract(opts);
+            } else {
+                pack.install(opts);
+            }
+        } catch (Exception e) {
+            log.warn("Error trying to extracting content package on path {}.", path, e);
+        }
+    }
+
+}
diff --git a/src/main/java/org/apache/sling/distribution/journal/impl/subscriber/DistributionSubscriber.java b/src/main/java/org/apache/sling/distribution/journal/impl/subscriber/DistributionSubscriber.java
index aad12aa..3a63f20 100644
--- a/src/main/java/org/apache/sling/distribution/journal/impl/subscriber/DistributionSubscriber.java
+++ b/src/main/java/org/apache/sling/distribution/journal/impl/subscriber/DistributionSubscriber.java
@@ -68,6 +68,7 @@ import org.apache.sling.distribution.journal.messages.Messages.PackageStatusMess
 import org.apache.commons.io.IOUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.jackrabbit.commons.jackrabbit.SimpleReferenceBinary;
+import org.apache.jackrabbit.vault.packaging.Packaging;
 import org.apache.sling.api.resource.LoginException;
 import org.apache.sling.api.resource.PersistenceException;
 import org.apache.sling.api.resource.Resource;
@@ -164,6 +165,9 @@ public class DistributionSubscriber implements DistributionAgent {
     @Reference
     private ServiceUserMapped mappedUser;
 
+    @Reference
+    private Packaging packaging;
+    
     private ServiceRegistration<DistributionAgent> componentReg;
 
     private final PackageRetries packageRetries = new PackageRetries();
@@ -206,6 +210,8 @@ public class DistributionSubscriber implements DistributionAgent {
 
     private volatile Thread queueProcessor;
     
+    private ContentPackageExtractor extractor;
+    
     @Activate
     public void activate(SubscriberConfiguration config, BundleContext context, Map<String, Object> properties) {
 
@@ -312,6 +318,7 @@ public class DistributionSubscriber implements DistributionAgent {
         LOG.info(msg);
         Dictionary<String, Object> props = createServiceProps(config);
         componentReg = context.registerService(DistributionAgent.class, this, props);
+        extractor = new ContentPackageExtractor(packaging, config.packageHandling());
     }
 
     private Set<String> getNotEmpty(String[] agentNames) {
@@ -639,6 +646,7 @@ public class DistributionSubscriber implements DistributionAgent {
         try {
             pkgStream = pkgStream(resolver, pkgMsg);
             packageBuilder.installPackage(resolver, pkgStream);
+            extractor.handle(resolver, pkgMsg.getPathsList());
         } finally {
             IOUtils.closeQuietly(pkgStream);
         }
diff --git a/src/main/java/org/apache/sling/distribution/journal/impl/subscriber/PackageHandling.java b/src/main/java/org/apache/sling/distribution/journal/impl/subscriber/PackageHandling.java
new file mode 100644
index 0000000..0be7ca8
--- /dev/null
+++ b/src/main/java/org/apache/sling/distribution/journal/impl/subscriber/PackageHandling.java
@@ -0,0 +1,23 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.distribution.journal.impl.subscriber;
+
+public enum PackageHandling {
+    Off, Extract, Install;
+}
diff --git a/src/main/java/org/apache/sling/distribution/journal/impl/subscriber/SubscriberConfiguration.java b/src/main/java/org/apache/sling/distribution/journal/impl/subscriber/SubscriberConfiguration.java
index c52ba3f..41c9e58 100644
--- a/src/main/java/org/apache/sling/distribution/journal/impl/subscriber/SubscriberConfiguration.java
+++ b/src/main/java/org/apache/sling/distribution/journal/impl/subscriber/SubscriberConfiguration.java
@@ -49,4 +49,7 @@ public @interface SubscriberConfiguration {
     @AttributeDefinition(name = "maxRetries", description = "The max number of attempts to import a package before moving the package to an error queue. If set to a negative value, the number of attempts is infinite. Default is -1 (infinite attempts).")
     int maxRetries() default -1;
 
+    @AttributeDefinition(name = "packageHandling", description = "Defines if content packages in /etc/packages should be processed (Extract, Install, Off).")
+    PackageHandling packageHandling() default PackageHandling.Off;
+    
 }