You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by pa...@apache.org on 2021/07/02 20:33:06 UTC

[sling-org-apache-sling-feature-cpconverter] branch master updated: Issue/sling 10469#2 (#96)

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

pauls 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 6b7f5c0  Issue/sling 10469#2 (#96)
6b7f5c0 is described below

commit 6b7f5c0f21d1b924ce599753c50d83b6e2351925
Author: Dominik Süß <su...@adobe.com>
AuthorDate: Fri Jul 2 22:33:00 2021 +0200

    Issue/sling 10469#2 (#96)
    
    * SLING-10469 - detecting dir folder and substructure belonging to nt file of a configuration and ignore in Handler ot prevent leftover in converted package
---
 .../AbstractConfigurationEntryHandler.java         |  82 +++++++++++----------
 .../ContentPackage2FeatureModelConverterTest.java  |  28 +++++++
 .../handlers/ConfigurationEntryHandlerTest.java    |   3 +
 .../.content.xml                                   |  25 +++++++
 .../feature/cpconverter/test_generated_package.zip | Bin 0 -> 6519 bytes
 5 files changed, 100 insertions(+), 38 deletions(-)

diff --git a/src/main/java/org/apache/sling/feature/cpconverter/handlers/AbstractConfigurationEntryHandler.java b/src/main/java/org/apache/sling/feature/cpconverter/handlers/AbstractConfigurationEntryHandler.java
index 2d10caf..8b02197 100644
--- a/src/main/java/org/apache/sling/feature/cpconverter/handlers/AbstractConfigurationEntryHandler.java
+++ b/src/main/java/org/apache/sling/feature/cpconverter/handlers/AbstractConfigurationEntryHandler.java
@@ -31,9 +31,10 @@ import org.jetbrains.annotations.Nullable;
 abstract class AbstractConfigurationEntryHandler extends AbstractRegexEntryHandler {
 
     private boolean enforceConfigurationBelowConfigFolder;
-
+    
+    // SLING-10469 - regexp to catch configs and poetential sibling .dir folders that would carry the node properties from an export that would need to be ignored as well
     public AbstractConfigurationEntryHandler(@NotNull String extension) {
-        super("/jcr_root/(?:apps|libs)/.+/(?<foldername>config|install)(\\.(?<runmode>[^/]+))?/(?<pid>.*)\\." + extension);
+        super("/jcr_root/(?:apps|libs)/.+/(?<foldername>config|install)(\\.(?<runmode>[^/]+))?(.*)/(?<pid>[^\\/]*)\\." + extension + ("(?<dir>.dir(/\\.content\\.xml)?)?$"));
     }
 
     void setEnforceConfgurationBelowConfigFolder(boolean enforceConfigurationBelowConfigFolder) {
@@ -48,47 +49,52 @@ abstract class AbstractConfigurationEntryHandler extends AbstractRegexEntryHandl
         String runMode;
         // we are pretty sure it matches, here
         if (matcher.matches()) {
-            String pid = matcher.group("pid");
-
-            int idx = pid.lastIndexOf('/');
-            if (idx != -1) {
-                pid = pid.substring(idx + 1);
-            }
-            String factoryPid = null;
-            String id;
-            int n = pid.indexOf('~');
-            if (n == -1) {
-                n = pid.indexOf('-');
-            }
-            if (n > 0) {
-                factoryPid = pid.substring(0, n);
-                id = factoryPid.concat("~").concat(pid.substring(n + 1));
+            if (matcher.group("dir") != null) {
+                // SLING-10469  - preventing invalid results as the corresponding configuration will be stripped from the resulting package causing the constraints of nt:file not to be satisfied (missing binary)
+                logger.info("{} is only a dir folder next to config - removing.", path);
             } else {
-                id = pid;
-            }
-    
-            logger.info("Processing configuration '{}'.", id);
+                String pid = matcher.group("pid");
     
-            Dictionary<String, Object> configurationProperties;
-            try (InputStream input = Objects.requireNonNull(archive.openInputStream(entry))) {
-                configurationProperties = parseConfiguration(id, input);
-            }
+                int idx = pid.lastIndexOf('/');
+                if (idx != -1) {
+                    pid = pid.substring(idx + 1);
+                }
+                String factoryPid = null;
+                String id;
+                int n = pid.indexOf('~');
+                if (n == -1) {
+                    n = pid.indexOf('-');
+                }
+                if (n > 0) {
+                    factoryPid = pid.substring(0, n);
+                    id = factoryPid.concat("~").concat(pid.substring(n + 1));
+                } else {
+                    id = pid;
+                }
+        
+                logger.info("Processing configuration '{}'.", id);
+        
+                Dictionary<String, Object> configurationProperties;
+                try (InputStream input = Objects.requireNonNull(archive.openInputStream(entry))) {
+                    configurationProperties = parseConfiguration(id, input);
+                }
     
-            if (configurationProperties == null) {
-                logger.info("{} entry does not contain a valid OSGi configuration, treating it as a regular resource", path);
-                converter.getMainPackageAssembler().addEntry(path, archive, entry);
-                return;
-            }
+                if (configurationProperties == null) {
+                    logger.info("{} entry does not contain a valid OSGi configuration, treating it as a regular resource", path);
+                    converter.getMainPackageAssembler().addEntry(path, archive, entry);
+                    return;
+                }
 
-            if (enforceConfigurationBelowConfigFolder && !"config".equals(matcher.group("foldername"))) {
-                throw new IllegalStateException("OSGi configuration are only considered if placed below a folder called 'config', but the configuration at '"+ path + "' is placed outside!");
+                if (enforceConfigurationBelowConfigFolder && !"config".equals(matcher.group("foldername"))) {
+                    throw new IllegalStateException("OSGi configuration are only considered if placed below a folder called 'config', but the configuration at '"+ path + "' is placed outside!");
+                }
+                
+                // there is a specified RunMode
+                runMode = matcher.group("runmode");
+    
+                FeaturesManager featuresManager = Objects.requireNonNull(converter.getFeaturesManager());
+                featuresManager.addConfiguration(runMode, id, path, configurationProperties);
             }
-
-            // there is a specified RunMode
-            runMode = matcher.group("runmode");
-
-            FeaturesManager featuresManager = Objects.requireNonNull(converter.getFeaturesManager());
-            featuresManager.addConfiguration(runMode, id, path, configurationProperties);
         } else {
             throw new IllegalStateException("Something went terribly wrong: pattern '"
                                             + getPattern().pattern()
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 1f82f3a..3c93c86 100644
--- a/src/test/java/org/apache/sling/feature/cpconverter/ContentPackage2FeatureModelConverterTest.java
+++ b/src/test/java/org/apache/sling/feature/cpconverter/ContentPackage2FeatureModelConverterTest.java
@@ -59,6 +59,7 @@ import org.apache.jackrabbit.vault.util.Constants;
 import org.apache.sling.feature.ArtifactId;
 import org.apache.sling.feature.Artifacts;
 import org.apache.sling.feature.Configuration;
+import org.apache.sling.feature.Configurations;
 import org.apache.sling.feature.Extension;
 import org.apache.sling.feature.ExtensionType;
 import org.apache.sling.feature.Feature;
@@ -881,6 +882,33 @@ public class ContentPackage2FeatureModelConverterTest extends AbstractConverterT
         }
     }
 
+    // make sure processed configs don't leave behind dir nodes generated by serialization of nt:file
+    @Test
+    public void filteredOutConfigDirFolder() throws Exception {
+        File[] contentPackages = load("test_generated_package.zip");
+        File outputDirectory = new File(System.getProperty("java.io.tmpdir"), getClass().getName() + '_' + System.currentTimeMillis());
+        try {
+            converter.setFeaturesManager(new DefaultFeaturesManager(true, 5, outputDirectory, null, null, null, new DefaultAclManager()))
+                    .setBundlesDeployer(new LocalMavenRepositoryArtifactsDeployer(outputDirectory))
+                    .setEmitter(DefaultPackagesEventsEmitter.open(outputDirectory))
+                    .convert(contentPackages);
+
+            
+            Feature feature = getFeature(outputDirectory, "test_generated_package.json");
+            Configurations confs = feature.getConfigurations();
+            assertNotNull(confs.getConfiguration("org.apache.sling.installer.provider.jcr.impl.JcrInstaller"));
+
+            File contentPackage = new File(outputDirectory, "test/test_generated_package/0.0.0/test_generated_package-0.0.0-cp2fm-converted.zip");
+            try (ZipFile zipFile = new ZipFile(contentPackage)) {
+                    assertNull("Dir folder not correctly stripped at: {}",
+                                  zipFile.getEntry("jcr_root/apps/system/config/org.apache.sling.installer.provider.jcr.impl.JcrInstaller.cfg.json.dir/.content.xml"));
+            }
+        }
+        finally {
+            deleteDirTree(outputDirectory);
+        }
+    }
+
     private File[] load(String...resources) {
         File[] loadedResources = new File[resources.length];
 
diff --git a/src/test/java/org/apache/sling/feature/cpconverter/handlers/ConfigurationEntryHandlerTest.java b/src/test/java/org/apache/sling/feature/cpconverter/handlers/ConfigurationEntryHandlerTest.java
index e72f22a..dcf357c 100644
--- a/src/test/java/org/apache/sling/feature/cpconverter/handlers/ConfigurationEntryHandlerTest.java
+++ b/src/test/java/org/apache/sling/feature/cpconverter/handlers/ConfigurationEntryHandlerTest.java
@@ -206,6 +206,9 @@ public class ConfigurationEntryHandlerTest {
         return Arrays.asList(new Object[][] {
             { path + EXPECTED_PID + ".empty.cfg", 1, 2, 0, new PropertiesConfigurationEntryHandler(), null, false},
             { path + EXPECTED_PID + ".cfg", 1, 2, 1, new PropertiesConfigurationEntryHandler(), null, false},
+            { path + EXPECTED_PID + ".cfg.dir", 0, 0, 0, new PropertiesConfigurationEntryHandler(), null, false},
+            { path + EXPECTED_PID + ".cfg.dir/.content.xml", 0, 0, 0, new PropertiesConfigurationEntryHandler(), null, false},
+
 
             { path + EXPECTED_PID + ".empty.cfg.json", 1, 2, 0, new JsonConfigurationEntryHandler(), null, true },
             { path + EXPECTED_PID + ".cfg.json", 1, 2, 3, new JsonConfigurationEntryHandler(), null, true },
diff --git a/src/test/resources/org/apache/sling/feature/cpconverter/handlers/jcr_root/apps/asd/config/org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.cfg.dir/.content.xml b/src/test/resources/org/apache/sling/feature/cpconverter/handlers/jcr_root/apps/asd/config/org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.cfg.dir/.content.xml
new file mode 100644
index 0000000..b345b5b
--- /dev/null
+++ b/src/test/resources/org/apache/sling/feature/cpconverter/handlers/jcr_root/apps/asd/config/org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.cfg.dir/.content.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+-->
+<jcr:root xmlns:jcr="http://www.jcp.org/jcr/1.0" xmlns:nt="http://www.jcp.org/jcr/nt/1.0"
+    jcr:primaryType="nt:file">
+    <jcr:content
+        jcr:encoding="UTF-8"
+        jcr:lastModifiedBy="sling-jcr-install"
+        jcr:mimeType="text/plain"
+        jcr:primaryType="nt:resource"/>
+</jcr:root>
\ No newline at end of file
diff --git a/src/test/resources/org/apache/sling/feature/cpconverter/test_generated_package.zip b/src/test/resources/org/apache/sling/feature/cpconverter/test_generated_package.zip
new file mode 100644
index 0000000..b89a7e7
Binary files /dev/null and b/src/test/resources/org/apache/sling/feature/cpconverter/test_generated_package.zip differ