You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by si...@apache.org on 2019/06/24 23:43:17 UTC

[sling-org-apache-sling-feature-cpconverter] branch master updated: SLING-8528 - ACLs for Serviceusers on nodes with nodetypes registered via content-package may break startup in repoinit.

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

simonetripodi 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 f33f968  SLING-8528 - ACLs for Serviceusers on nodes with nodetypes registered via content-package may break startup in repoinit.
f33f968 is described below

commit f33f9680857d553d8c9c7a6d0f92322efde1fe78
Author: Simo Tripodi <st...@adobe.com>
AuthorDate: Tue Jun 25 01:43:10 2019 +0200

    SLING-8528 - ACLs for Serviceusers on nodes with nodetypes registered
    via content-package may break startup in repoinit.
---
 .../ContentPackage2FeatureModelConverter.java      | 12 +++++
 .../sling/feature/cpconverter/acl/AclManager.java  |  2 +
 .../feature/cpconverter/acl/DefaultAclManager.java | 27 ++++++++++
 .../vltpkg/BaseVaultPackageScanner.java            | 40 ++++++++++++--
 .../cpconverter/vltpkg/VaultPackageAssembler.java  | 35 ++++++------
 .../ContentPackage2FeatureModelConverterTest.java  | 38 +++++++++++++
 .../cpconverter/vltpkg/NodeTypesDetectionTest.java | 63 ++++++++++++++++++++++
 7 files changed, 198 insertions(+), 19 deletions(-)

diff --git a/src/main/java/org/apache/sling/feature/cpconverter/ContentPackage2FeatureModelConverter.java b/src/main/java/org/apache/sling/feature/cpconverter/ContentPackage2FeatureModelConverter.java
index 522598d..0769975 100644
--- a/src/main/java/org/apache/sling/feature/cpconverter/ContentPackage2FeatureModelConverter.java
+++ b/src/main/java/org/apache/sling/feature/cpconverter/ContentPackage2FeatureModelConverter.java
@@ -18,7 +18,9 @@ package org.apache.sling.feature.cpconverter;
 
 import static java.util.Objects.requireNonNull;
 
+import java.io.BufferedReader;
 import java.io.File;
+import java.io.InputStreamReader;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -290,4 +292,14 @@ public class ContentPackage2FeatureModelConverter extends BaseVaultPackageScanne
         entryHandler.handle(entryPath, archive, entry, this);
     }
 
+    @Override
+    protected void onCndEntry(String path, Archive archive, Entry entry) throws Exception {
+        try (BufferedReader reader = new BufferedReader(new InputStreamReader(archive.openInputStream(entry)))) {
+            String nodetypeRegistrationSentence;
+            while ((nodetypeRegistrationSentence = reader.readLine()) != null) {
+                aclManager.addNodetypeRegistrationSentence(nodetypeRegistrationSentence);
+            }
+        }
+    }
+
 }
diff --git a/src/main/java/org/apache/sling/feature/cpconverter/acl/AclManager.java b/src/main/java/org/apache/sling/feature/cpconverter/acl/AclManager.java
index a3feeb8..734ad7a 100644
--- a/src/main/java/org/apache/sling/feature/cpconverter/acl/AclManager.java
+++ b/src/main/java/org/apache/sling/feature/cpconverter/acl/AclManager.java
@@ -30,6 +30,8 @@ public interface AclManager {
 
     void addRepoinitExtension(VaultPackageAssembler packageAssembler, Feature feature);
 
+    void addNodetypeRegistrationSentence(String nodetypeRegistrationSentence);
+
     void reset();
 
 }
diff --git a/src/main/java/org/apache/sling/feature/cpconverter/acl/DefaultAclManager.java b/src/main/java/org/apache/sling/feature/cpconverter/acl/DefaultAclManager.java
index c4e2d7b..2e93d74 100644
--- a/src/main/java/org/apache/sling/feature/cpconverter/acl/DefaultAclManager.java
+++ b/src/main/java/org/apache/sling/feature/cpconverter/acl/DefaultAclManager.java
@@ -49,6 +49,8 @@ public final class DefaultAclManager implements AclManager {
 
     private final Map<String, List<Acl>> acls = new HashMap<>();
 
+    private List<String> nodetypeRegistrationSentences = new LinkedList<>();
+
     public boolean addSystemUser(String systemUser) {
         if (systemUser != null && !systemUser.isEmpty() && preProvidedSystemUsers.add(systemUser)) {
             return systemUsers.add(systemUser);
@@ -78,6 +80,23 @@ public final class DefaultAclManager implements AclManager {
         try {
             formatter = new Formatter();
 
+            if (!nodetypeRegistrationSentences.isEmpty()) {
+                formatter.format("register nodetypes%n")
+                         .format("<<===%n");
+
+                for (String nodetypeRegistrationSentence : nodetypeRegistrationSentences) {
+                    if (nodetypeRegistrationSentence.isEmpty()) {
+                        formatter.format("%n");
+                    } else {
+                        formatter.format("<< %s%n", nodetypeRegistrationSentence);
+                    }
+                }
+
+                formatter.format("===>>%n");
+            }
+
+            // system users
+
             for (String systemUser : systemUsers) {
                 List<Acl> authorizations = acls.remove(systemUser);
 
@@ -126,9 +145,17 @@ public final class DefaultAclManager implements AclManager {
         }
     }
 
+    @Override
+    public void addNodetypeRegistrationSentence(String nodetypeRegistrationSentence) {
+        if (nodetypeRegistrationSentence != null) {
+            nodetypeRegistrationSentences.add(nodetypeRegistrationSentence);
+        }
+    }
+
     public void reset() {
         systemUsers.clear();
         acls.clear();
+        nodetypeRegistrationSentences.clear();
     }
 
     private void addPaths(List<Acl> authorizations, VaultPackageAssembler packageAssembler, Formatter formatter) {
diff --git a/src/main/java/org/apache/sling/feature/cpconverter/vltpkg/BaseVaultPackageScanner.java b/src/main/java/org/apache/sling/feature/cpconverter/vltpkg/BaseVaultPackageScanner.java
index 5b67e06..396a730 100644
--- a/src/main/java/org/apache/sling/feature/cpconverter/vltpkg/BaseVaultPackageScanner.java
+++ b/src/main/java/org/apache/sling/feature/cpconverter/vltpkg/BaseVaultPackageScanner.java
@@ -16,13 +16,20 @@
  */
 package org.apache.sling.feature.cpconverter.vltpkg;
 
+import static org.apache.jackrabbit.vault.util.Constants.META_DIR;
+import static org.apache.jackrabbit.vault.util.Constants.NODETYPES_CND;
+import static org.apache.jackrabbit.vault.packaging.PackageProperties.NAME_CND_PATTERN;
 import static java.util.Objects.requireNonNull;
 
 import java.io.File;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 import org.apache.jackrabbit.vault.fs.io.Archive;
+import org.apache.jackrabbit.vault.fs.io.ImportOptions;
 import org.apache.jackrabbit.vault.fs.io.Archive.Entry;
 import org.apache.jackrabbit.vault.packaging.PackageManager;
+import org.apache.jackrabbit.vault.packaging.PackageProperties;
 import org.apache.jackrabbit.vault.packaging.VaultPackage;
 import org.apache.jackrabbit.vault.packaging.impl.PackageManagerImpl;
 import org.slf4j.Logger;
@@ -67,30 +74,53 @@ public abstract class BaseVaultPackageScanner {
     public final void traverse(VaultPackage vaultPackage) throws Exception {
         requireNonNull(vaultPackage, "Impossible to process a null vault package");
 
+        PackageProperties properties = vaultPackage.getProperties();
+        ImportOptions importOptions = new ImportOptions();
+        String cndPattern = properties.getProperty(NAME_CND_PATTERN);
+        if (cndPattern != null && !cndPattern.isEmpty()) {
+            importOptions.setCndPattern(cndPattern);
+        }
+
         Archive archive = vaultPackage.getArchive();
         try {
             archive.open(strictValidation);
 
+            String nodetypesPath = META_DIR + '/' + NODETYPES_CND;
+            Entry nodetypesEntry = archive.getEntry(nodetypesPath);
+            if (nodetypesEntry != null && !nodetypesEntry.isDirectory()) {
+                onCndEntry(nodetypesPath, archive, nodetypesEntry);
+            }
+
             Entry jcrRoot = archive.getJcrRoot();
-            traverse(null, archive, jcrRoot);
+            traverse(null, archive, jcrRoot, importOptions.getCndPattern());
         } finally {
             archive.close();
         }
     }
 
-    private void traverse(String path, Archive archive, Entry entry) throws Exception {
+    private void traverse(String path, Archive archive, Entry entry, Pattern cndPattern) throws Exception {
         String entryPath = newPath(path, entry.getName());
 
         if (entry.isDirectory()) {
             onDirectory(entryPath, archive, entry);
 
             for (Entry child : entry.getChildren()) {
-                traverse(entryPath, archive, child);
+                traverse(entryPath, archive, child, cndPattern);
             }
 
             return;
         }
 
+        Matcher cndMatcher = cndPattern.matcher(entryPath);
+        if (cndMatcher.matches()) {
+            logger.debug("Detected CND file {}, processing it...", entryPath);
+
+            onCndEntry(entryPath, archive, entry);
+
+            logger.debug("CND file {} processed.", entryPath);
+            return;
+        }
+
         logger.debug("Processing entry {}...", entryPath);
 
         onFile(entryPath, archive, entry);
@@ -114,4 +144,8 @@ public abstract class BaseVaultPackageScanner {
         // do nothing by default
     }
 
+    protected void onCndEntry(String path, Archive archive, Entry entry) throws Exception {
+        // do nothing by default
+    }
+
 }
diff --git a/src/main/java/org/apache/sling/feature/cpconverter/vltpkg/VaultPackageAssembler.java b/src/main/java/org/apache/sling/feature/cpconverter/vltpkg/VaultPackageAssembler.java
index b6cb964..803c420 100644
--- a/src/main/java/org/apache/sling/feature/cpconverter/vltpkg/VaultPackageAssembler.java
+++ b/src/main/java/org/apache/sling/feature/cpconverter/vltpkg/VaultPackageAssembler.java
@@ -16,6 +16,13 @@
  */
 package org.apache.sling.feature.cpconverter.vltpkg;
 
+import static org.apache.jackrabbit.vault.util.Constants.CONFIG_XML;
+import static org.apache.jackrabbit.vault.util.Constants.FILTER_XML;
+import static org.apache.jackrabbit.vault.util.Constants.META_DIR;
+import static org.apache.jackrabbit.vault.util.Constants.PACKAGE_DEFINITION_XML;
+import static org.apache.jackrabbit.vault.util.Constants.PROPERTIES_XML;
+import static org.apache.jackrabbit.vault.util.Constants.ROOT_DIR;
+import static org.apache.jackrabbit.vault.util.Constants.SETTINGS_XML;
 import static org.apache.sling.feature.cpconverter.ContentPackage2FeatureModelConverter.PACKAGE_CLASSIFIER;
 
 import java.io.File;
@@ -44,17 +51,9 @@ import org.codehaus.plexus.archiver.util.DefaultFileSet;
 
 public class VaultPackageAssembler implements EntryHandler {
 
-    private static final String JCR_ROOT_DIR_NAME = "jcr_root";
-
-    private static final String META_INF_VAULT_DIRECTORY = "META-INF/vault/";
-
-    private static final String VAULT_PROPERTIES_FILE = META_INF_VAULT_DIRECTORY + "properties.xml";
-
-    private static final String VAULT_FILTER_FILE = META_INF_VAULT_DIRECTORY + "filter.xml";
-
     private static final String NAME_PATH = "path";
 
-    private static final String[] INCLUDE_RESOURCES = { "definition/.content.xml", "config.xml", "settings.xml" };
+    private static final String[] INCLUDE_RESOURCES = { PACKAGE_DEFINITION_XML, CONFIG_XML, SETTINGS_XML };
 
     private static final File TMP_DIR = new File(System.getProperty("java.io.tmpdir"), "syntethic-content-packages");
 
@@ -77,7 +76,7 @@ public class VaultPackageAssembler implements EntryHandler {
     private static VaultPackageAssembler create(VaultPackage vaultPackage, WorkspaceFilter filter) {
         File storingDirectory = new File(TMP_DIR, vaultPackage.getFile().getName() + "-deflated");
         // avoid any possible Stream is not a content package. Missing 'jcr_root' error
-        File jcrRootDirectory = new File(storingDirectory, JCR_ROOT_DIR_NAME);
+        File jcrRootDirectory = new File(storingDirectory, ROOT_DIR);
         jcrRootDirectory.mkdirs();
 
         PackageProperties packageProperties = vaultPackage.getProperties();
@@ -166,8 +165,8 @@ public class VaultPackageAssembler implements EntryHandler {
     }
 
     public File getEntry(String path) {
-        if (!path.startsWith(JCR_ROOT_DIR_NAME)) {
-            path = JCR_ROOT_DIR_NAME + path;
+        if (!path.startsWith(ROOT_DIR)) {
+            path = ROOT_DIR + path;
         }
 
         return new File(storingDirectory, path);
@@ -180,15 +179,19 @@ public class VaultPackageAssembler implements EntryHandler {
     public File createPackage(File outputDirectory) throws IOException {
         // generate the Vault properties XML file
 
-        File xmlProperties = new File(storingDirectory, VAULT_PROPERTIES_FILE);
-        xmlProperties.getParentFile().mkdirs();
+        File metaDir = new File(storingDirectory, META_DIR);
+        if (!metaDir.exists()) {
+            metaDir.mkdirs();
+        }
+
+        File xmlProperties = new File(metaDir, PROPERTIES_XML);
 
         try (FileOutputStream fos = new FileOutputStream(xmlProperties)) {
             properties.storeToXML(fos, null);
         }
 
         // generate the Vault filter XML file
-        File xmlFilter = new File(storingDirectory, VAULT_FILTER_FILE);
+        File xmlFilter = new File(metaDir, FILTER_XML);
         try (InputStream input = filter.getSource();
                 FileOutputStream output = new FileOutputStream(xmlFilter)) {
             IOUtils.copy(input, output);
@@ -198,7 +201,7 @@ public class VaultPackageAssembler implements EntryHandler {
 
         for (String resource : INCLUDE_RESOURCES) {
             try (InputStream input = getClass().getResourceAsStream(resource)) {
-                addEntry(META_INF_VAULT_DIRECTORY + resource, input);
+                addEntry(ROOT_DIR + resource, input);
             }
         }
 
diff --git a/src/test/java/org/apache/sling/feature/cpconverter/ContentPackage2FeatureModelConverterTest.java b/src/test/java/org/apache/sling/feature/cpconverter/ContentPackage2FeatureModelConverterTest.java
index ea6e83e..be8d864 100644
--- a/src/test/java/org/apache/sling/feature/cpconverter/ContentPackage2FeatureModelConverterTest.java
+++ b/src/test/java/org/apache/sling/feature/cpconverter/ContentPackage2FeatureModelConverterTest.java
@@ -40,6 +40,7 @@ import org.apache.commons.io.FileUtils;
 import org.apache.jackrabbit.vault.packaging.CyclicDependencyException;
 import org.apache.jackrabbit.vault.packaging.VaultPackage;
 import org.apache.sling.feature.ArtifactId;
+import org.apache.sling.feature.Extension;
 import org.apache.sling.feature.Feature;
 import org.apache.sling.feature.cpconverter.acl.DefaultAclManager;
 import org.apache.sling.feature.cpconverter.artifacts.DefaultArtifactsDeployer;
@@ -346,6 +347,43 @@ public class ContentPackage2FeatureModelConverterTest {
         assertFalse(converter.isSubContentPackageIncluded("jcr_root/etc/packages/asd/test-content.zip"));
     }
 
+    @Test
+    public void verifyRepoinitContainsNodetypesRegistration() throws Exception {
+        File[] contentPackages = load(TEST_PACKAGES_INPUT[1]);
+
+        File outputDirectory = new File(System.getProperty("java.io.tmpdir"), getClass().getName() + '_' + System.currentTimeMillis());
+
+        converter.setFeaturesManager(new DefaultFeaturesManager(true, 5, outputDirectory, null, null))
+                 .setBundlesDeployer(new DefaultArtifactsDeployer(outputDirectory))
+                 .convert(contentPackages[0]);
+
+        File featureFile = new File(outputDirectory, "test_a.json");
+        try (Reader reader = new FileReader(featureFile)) {
+            Feature feature = FeatureJSONReader.read(reader, featureFile.getAbsolutePath());
+
+            Extension repoinitExtension = feature.getExtensions().getByName("repoinit");
+            assertNotNull(repoinitExtension);
+
+            String expected = "register nodetypes\n" +
+                    "<<===\n" +
+                    "<< <'sling'='http://sling.apache.org/jcr/sling/1.0'>\n" + 
+                    "<< <'nt'='http://www.jcp.org/jcr/nt/1.0'>\n" + 
+                    "<< <'rep'='internal'>\n" + 
+                    "\n" + 
+                    "<< [sling:Folder] > nt:folder\n" + 
+                    "<<   - * (undefined) multiple\n" + 
+                    "<<   - * (undefined)\n" + 
+                    "<<   + * (nt:base) = sling:Folder version\n" + 
+                    "\n" + 
+                    "<< [rep:RepoAccessControllable]\n" + 
+                    "<<   mixin\n" + 
+                    "<<   + rep:repoPolicy (rep:Policy) protected ignore\n" + 
+                    "\n===>>\n";
+            String actual = repoinitExtension.getText();
+            assertEquals(expected, actual);
+        }
+    }
+
     private File[] load(String...resources) {
         File[] loadedResources = new File[resources.length];
 
diff --git a/src/test/java/org/apache/sling/feature/cpconverter/vltpkg/NodeTypesDetectionTest.java b/src/test/java/org/apache/sling/feature/cpconverter/vltpkg/NodeTypesDetectionTest.java
new file mode 100644
index 0000000..767a60e
--- /dev/null
+++ b/src/test/java/org/apache/sling/feature/cpconverter/vltpkg/NodeTypesDetectionTest.java
@@ -0,0 +1,63 @@
+/*
+ * 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.feature.cpconverter.vltpkg;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.apache.commons.io.FileUtils.toFile;
+
+import java.io.File;
+import java.net.URL;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.apache.jackrabbit.vault.fs.io.Archive;
+import org.apache.jackrabbit.vault.fs.io.Archive.Entry;
+import org.apache.sling.feature.cpconverter.vltpkg.BaseVaultPackageScanner;
+import org.junit.Before;
+import org.junit.Test;
+
+public class NodeTypesDetectionTest {
+
+    private File packageFile;
+
+    @Before
+    public void setUp() {
+        URL packageURL = getClass().getResource("test_a-1.0.zip");
+        packageFile = toFile(packageURL);
+    }
+
+    @Test
+    public void detectMetaInfVaultNodetypesCdnFile() throws Exception {
+        final List<String> detectedCndFiles = new LinkedList<>();
+
+        new BaseVaultPackageScanner(true) {
+
+            @Override
+            protected void onCndEntry(String path, Archive archive, Entry entry) throws Exception {
+                detectedCndFiles.add(path);
+            }
+
+        }.traverse(packageFile, true);
+
+        assertFalse(detectedCndFiles.isEmpty());
+        assertEquals(1, detectedCndFiles.size());
+        assertTrue(detectedCndFiles.contains("META-INF/vault/nodetypes.cnd"));
+    }
+
+}