You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by an...@apache.org on 2021/08/03 13:05:43 UTC
[sling-org-apache-sling-feature-cpconverter] 01/01: SLING-10692 :
VaultPackageAssembler.mergeFilters drops propertyFilterSets SLING-10694 :
CPConverter drops mode from filters SLING-10699 : Incomplete path
conversion in VaultPackageAssembler.toRepositoryPaths
This is an automated email from the ASF dual-hosted git repository.
angela pushed a commit to branch SLING-10692
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-feature-cpconverter.git
commit 297967274e6e40fcd829efec335a5f72fc6b1f21
Author: angela <an...@adobe.com>
AuthorDate: Tue Aug 3 15:05:21 2021 +0200
SLING-10692 : VaultPackageAssembler.mergeFilters drops propertyFilterSets
SLING-10694 : CPConverter drops mode from filters
SLING-10699 : Incomplete path conversion in VaultPackageAssembler.toRepositoryPaths
---
.../cpconverter/vltpkg/VaultPackageAssembler.java | 68 +++++++--
.../ConverterUserAndPermissionTest.java | 161 ++++++++++++++++++---
.../vltpkg/VaultPackageAssemblerTest.java | 60 ++++++--
.../cpconverter/demo-cp-single-user-root.zip | Bin 0 -> 15692 bytes
.../cpconverter/demo-cp-with-importmode.zip | Bin 0 -> 15802 bytes
5 files changed, 242 insertions(+), 47 deletions(-)
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 3961aff..42b1d1e 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
@@ -49,8 +49,10 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
+import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Properties;
@@ -202,9 +204,16 @@ public class VaultPackageAssembler implements EntryHandler {
}
public void mergeFilters(@NotNull WorkspaceFilter filter) {
+ Map<String, PathFilterSet> propFilterSets = extractPropertyFilters(filter);
+ // copy over all node-filters together if the corresponding property-filters if existing.
for (PathFilterSet pathFilterSet : filter.getFilterSets()) {
if (!OSGI_BUNDLE_PATTERN.matcher(pathFilterSet.getRoot()).matches()) {
- this.filter.add(pathFilterSet);
+ PathFilterSet propSet = propFilterSets.remove(pathFilterSet.getRoot());
+ if (propSet != null) {
+ this.filter.add(pathFilterSet, propSet);
+ } else {
+ this.filter.add(pathFilterSet);
+ }
}
}
}
@@ -351,7 +360,15 @@ public class VaultPackageAssembler implements EntryHandler {
private static @NotNull Set<String> toRepositoryPaths(@NotNull Set<String> paths) {
return paths.stream().map(s -> {
if (s.startsWith("/jcr_root")) {
- return s.substring("/jcr_root".length());
+ String path = PlatformNameFormat.getRepositoryPath(s.substring("/jcr_root".length()));
+ if (path.endsWith("/.content.xml")) {
+ return path.substring(0, path.lastIndexOf("/.content.xml"));
+ } else if (path.endsWith(".xml")) {
+ // remove .xml extension from policy-nodes
+ return path.substring(0, path.lastIndexOf(".xml"));
+ } else {
+ return path;
+ }
} else {
return s;
}
@@ -361,11 +378,9 @@ public class VaultPackageAssembler implements EntryHandler {
private static @NotNull WorkspaceFilter createAdjustedFilter(@NotNull WorkspaceFilter base, @NotNull Set<String> filteredPaths, @NotNull Set<String> cpPaths) throws IOException {
try {
DefaultWorkspaceFilter dwf = new DefaultWorkspaceFilter();
- for (PathFilterSet pfs : base.getPropertyFilterSets()) {
- processPathFilterSet(pfs, dwf, true, filteredPaths, cpPaths);
- }
+ Map<String, PathFilterSet> propFilters = extractPropertyFilters(base);
for (PathFilterSet pfs : base.getFilterSets()) {
- processPathFilterSet(pfs, dwf, false, filteredPaths, cpPaths);
+ processPathFilterSet(pfs, propFilters, dwf, filteredPaths, cpPaths);
}
return dwf;
} catch (ConfigurationException e) {
@@ -373,18 +388,33 @@ public class VaultPackageAssembler implements EntryHandler {
}
}
- private static void processPathFilterSet(@NotNull PathFilterSet pfs, @NotNull DefaultWorkspaceFilter newFilter,
- boolean isPropertyFilterSet, @NotNull Set<String> filteredPaths,
+ private static void processPathFilterSet(@NotNull PathFilterSet pfs, @NotNull Map<String, PathFilterSet> propFilters,
+ @NotNull DefaultWorkspaceFilter newFilter, @NotNull Set<String> filteredPaths,
@NotNull Set<String> cpPaths) throws ConfigurationException {
if (cpPaths.stream().noneMatch(pfs::covers)) {
// the given filterset no longer covers any of the paths included in the converted content package
- // -> save to no longer include it in the new workspace filter.
+ // -> ok to no longer include it in the new workspace filter.
return;
}
+ // create a new node path-filter-set (and if existing the corresponding property filter)
+ PathFilterSet nodeFilterSet = copyPathFilterSet(pfs, filteredPaths);
+ PathFilterSet propPfs = propFilters.remove(pfs.getRoot());
+ if (propPfs != null) {
+ // note: no need to add additional exclude entries for property-filters
+ PathFilterSet propFilterSet = copyPathFilterSet(propPfs, Collections.emptySet());
+ newFilter.add(nodeFilterSet, propFilterSet);
+ } else {
+ newFilter.add(nodeFilterSet);
+ }
+ }
+
+ @NotNull
+ private static PathFilterSet copyPathFilterSet(@NotNull PathFilterSet pfs, @NotNull Set<String> filteredPaths) throws ConfigurationException {
// create a new path-filter-set
PathFilterSet filterSet = new PathFilterSet(pfs.getRoot());
filterSet.setType(pfs.getType());
+ filterSet.setImportMode(pfs.getImportMode());
// copy all entries to the new path-filter-set
for (FilterSet.Entry<PathFilter> entry : pfs.getEntries()) {
@@ -401,11 +431,21 @@ public class VaultPackageAssembler implements EntryHandler {
filterSet.addExclude(new DefaultPathFilter(path));
}
}
- if (isPropertyFilterSet) {
- newFilter.addPropertyFilterSet(filterSet);
- } else {
- newFilter.add(filterSet);
- }
+ return filterSet;
+ }
+
+ /**
+ * Extract all property-filters and remember them for later as DefaultWorkspaceFilter.addPropertyFilterSet
+ * is deprecated in favor of DefaultWorkspaceFilter.add(PathFilterSet nodeFilter, PathFilterSet propFilter).
+ * The map created then allows to process property-filters together with node filters.
+ *
+ * @param base The filter from which to extract property-filters
+ * @return A map of path (the root) to the corresponding property-pathfilterset.
+ */
+ private static Map<String, PathFilterSet> extractPropertyFilters(@NotNull WorkspaceFilter base) {
+ Map<String, PathFilterSet> propFilters = new LinkedHashMap<>();
+ base.getPropertyFilterSets().forEach(pathFilterSet -> propFilters.put(pathFilterSet.getRoot(), pathFilterSet));
+ return propFilters;
}
private static void addDirectory(@NotNull final JarOutputStream jos, @NotNull final File dir, final int prefixLength) throws IOException {
diff --git a/src/test/java/org/apache/sling/feature/cpconverter/ConverterUserAndPermissionTest.java b/src/test/java/org/apache/sling/feature/cpconverter/ConverterUserAndPermissionTest.java
index 178f492..21777c1 100644
--- a/src/test/java/org/apache/sling/feature/cpconverter/ConverterUserAndPermissionTest.java
+++ b/src/test/java/org/apache/sling/feature/cpconverter/ConverterUserAndPermissionTest.java
@@ -18,7 +18,12 @@ package org.apache.sling.feature.cpconverter;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
-import org.apache.jackrabbit.vault.packaging.PackageType;
+import org.apache.jackrabbit.vault.fs.api.FilterSet;
+import org.apache.jackrabbit.vault.fs.api.ImportMode;
+import org.apache.jackrabbit.vault.fs.api.PathFilter;
+import org.apache.jackrabbit.vault.fs.api.PathFilterSet;
+import org.apache.jackrabbit.vault.fs.api.WorkspaceFilter;
+import org.apache.jackrabbit.vault.fs.config.DefaultWorkspaceFilter;
import org.apache.sling.feature.Extension;
import org.apache.sling.feature.Feature;
import org.apache.sling.feature.cpconverter.ContentPackage2FeatureModelConverter.PackagePolicy;
@@ -49,10 +54,8 @@ import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import java.io.File;
-import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
-import java.io.InputStreamReader;
import java.io.StringReader;
import java.net.URL;
import java.nio.charset.StandardCharsets;
@@ -71,6 +74,7 @@ import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
@RunWith(Parameterized.class)
public class ConverterUserAndPermissionTest extends AbstractConverterTest {
@@ -225,6 +229,109 @@ public class ConverterUserAndPermissionTest extends AbstractConverterTest {
verifyRepoInit();
}
+ @Test
+ public void testConvertPackageWithImportModes() throws Exception {
+ URL packageUrl = getClass().getResource("demo-cp-with-importmode.zip");
+ File packageFile = FileUtils.toFile(packageUrl);
+ converter.convert(packageFile);
+
+ File converted = new File(outputDirectory, "my_packages/demo-cp/0.0.0/demo-cp-0.0.0-cp2fm-converted.zip");
+
+ Set<String> notExpected = new HashSet<>(COMMON_NOT_EXPECTED_PATHS);
+ notExpected.add("jcr_root/apps/demo-cp/.content.xml");
+
+ Set<String> expected = new HashSet<>(COMMON_EXPECTED_PATHS);
+ expected.add("jcr_root/apps/.content.xml");
+
+ verifyContentPackage(converted, notExpected, expected);
+ assertExpectedPolicies(converted);
+ WorkspaceFilter filter = verifyWorkspaceFilter(converted, false);
+ verifyRepoInit();
+
+ assertEquals(ImportMode.MERGE, filter.getImportMode("/demo-cp"));
+ assertEquals(ImportMode.UPDATE, filter.getImportMode("/home/groups/demo-cp"));
+ assertEquals(ImportMode.REPLACE, filter.getImportMode("/home/users/demo-cp"));
+ }
+
+ @Test
+ public void testConvertPackageWithPropertyFilterSetEntry() throws Exception {
+ URL packageUrl = getClass().getResource("demo-cp-with-importmode.zip");
+ File packageFile = FileUtils.toFile(packageUrl);
+ converter.convert(packageFile);
+
+ File converted = new File(outputDirectory, "my_packages/demo-cp/0.0.0/demo-cp-0.0.0-cp2fm-converted.zip");
+ WorkspaceFilter filter = verifyWorkspaceFilter(converted, false);
+
+ // verify that the 'matchProperties=true' exclude entry with /home/groups/demo-cp was properly converted
+ // and is still present in the adjusted filter.
+ List<PathFilterSet> propertyFilters = filter.getPropertyFilterSets();
+ assertNotNull(propertyFilters);
+ assertEquals(3, propertyFilters.size());
+ // there is only a single exclude entry matching properties with /home/groups/demo-cp
+ // the other filters don't have any property-entries
+ for (PathFilterSet filterSet : propertyFilters) {
+ List<FilterSet.Entry<PathFilter>> entries = filterSet.getEntries();
+ int expectedSize = ("/home/groups/demo-cp".equals(filterSet.getRoot())) ? 1 : 0;
+ assertEquals(expectedSize, entries.size());
+ }
+
+ // verify that the node-filtersets got updated with additional excludes for paths filtered out
+ List<PathFilterSet> nodeFilters = filter.getFilterSets();
+ assertEquals(3, nodeFilters.size());
+ for (PathFilterSet filterSet : nodeFilters) {
+ List<FilterSet.Entry<PathFilter>> entries = filterSet.getEntries();
+ switch (filterSet.getRoot()) {
+ case "/demo-cp":
+ assertEquals(0, entries.size());
+ break;
+ case "/home/groups/demo-cp":
+ assertEquals(1, entries.size());
+ assertFalse(filterSet.contains(filterSet.getRoot() + "/rep:policy"));
+ assertEquals(0, entries.stream().filter(FilterSet.Entry::isInclude).count());
+ break;
+ case "/home/users/demo-cp":
+ assertEquals(3, entries.size());
+ assertFalse(filterSet.contains(filterSet.getRoot() + "/rep:policy"));
+ assertEquals(1, entries.stream().filter(FilterSet.Entry::isInclude).count());
+ break;
+ default:
+ fail("unexpected path "+ filterSet.getRoot());
+ }
+ }
+ }
+
+ @Test
+ public void testConvertPackageWithSingleUserRoot() throws Exception {
+ URL packageUrl = getClass().getResource("demo-cp-single-user-root.zip");
+ File packageFile = FileUtils.toFile(packageUrl);
+ converter.convert(packageFile);
+
+ File converted = new File(outputDirectory, "my_packages/demo-cp/0.0.0/demo-cp-0.0.0-cp2fm-converted.zip");
+
+ Set<String> notExpected = new HashSet<>(COMMON_NOT_EXPECTED_PATHS);
+ notExpected.add("jcr_root/apps/demo-cp/.content.xml");
+
+ Set<String> expected = new HashSet<>(COMMON_EXPECTED_PATHS);
+ expected.add("jcr_root/apps/.content.xml");
+
+ verifyContentPackage(converted, notExpected, expected);
+ assertExpectedPolicies(converted);
+ verifyRepoInit();
+
+ WorkspaceFilter filter = getWorkspaceFilter(converted);
+ assertEquals(ImportMode.MERGE, filter.getImportMode("/home"));
+
+ List<PathFilterSet> filterSets = filter.getFilterSets();
+ assertEquals(2, filterSets.size());
+ assertNotNull(filter.getCoveringFilterSet("/demo-cp"));
+ PathFilterSet homeFilter = filter.getCoveringFilterSet("/home");
+ assertNotNull(homeFilter);
+ // 11 excludes must have been added for paths that got moved to repo-init
+ List<FilterSet.Entry<PathFilter>> entries = homeFilter.getEntries();
+ assertEquals(11, entries.size());
+ assertFalse(entries.stream().anyMatch(FilterSet.Entry::isInclude));
+ }
+
private static void assertExpectedPolicies(@NotNull File converted ) throws IOException {
assertPolicy(converted, "jcr_root/demo-cp/_rep_policy.xml", "cp-serviceuser-1", "cp-user1", "cp-group1");
assertPolicy(converted, "jcr_root/home/groups/demo-cp/EsYrXeBdSRkna2kqbxjl/_rep_policy.xml", null, "cp-group1");
@@ -297,26 +404,40 @@ public class ConverterUserAndPermissionTest extends AbstractConverterTest {
}
}
- private static void verifyWorkspaceFilter(@NotNull File contentPackage, boolean isContentOnly) throws IOException {
+ private static WorkspaceFilter verifyWorkspaceFilter(@NotNull File contentPackage, boolean isContentOnly) throws Exception {
+ DefaultWorkspaceFilter filter = getWorkspaceFilter(contentPackage);
+ if (!isContentOnly) {
+ assertFalse(filter.contains("/apps/demo-cp"));
+ }
+ assertFalse(filter.covers("/home/users/system"));
+ assertFalse(filter.covers("/home/users/system/demo-cp"));
+ assertFalse(filter.covers("/home/users/system/cq:services/demo-cp"));
+
+ assertTrue(filter.covers("/demo-cp"));
+ assertTrue(filter.covers("/home/users/demo-cp"));
+ assertTrue(filter.covers("/home/groups/demo-cp"));
+
+ // verify that explicit excludes have been added for filter roots that contain mixed content
+ PathFilterSet filterSet = filter.getCoveringFilterSet("/home/groups/demo-cp");
+ assertNotNull(filterSet);
+ assertEquals(1, filterSet.getEntries().stream().filter(pathFilterEntry -> !pathFilterEntry.isInclude() &&
+ pathFilterEntry.getFilter().matches("/home/groups/demo-cp/rep:policy")).count());
+
+ filterSet = filter.getCoveringFilterSet("/home/users/demo-cp");
+ assertNotNull(filterSet);
+ assertEquals(1, filterSet.getEntries().stream().filter(pathFilterEntry -> !pathFilterEntry.isInclude() &&
+ pathFilterEntry.getFilter().matches("/home/users/demo-cp/rep:policy")).count());
+ return filter;
+ }
+
+ private static DefaultWorkspaceFilter getWorkspaceFilter(@NotNull File contentPackage) throws Exception {
+ DefaultWorkspaceFilter filter;
try (ZipFile zipFile = new ZipFile(contentPackage)) {
+ filter = new DefaultWorkspaceFilter();
ZipEntry entry = zipFile.getEntry("META-INF/vault/filter.xml");
assertNotNull(entry);
- String filter = IOUtils.toString(new InputStreamReader(zipFile.getInputStream(entry)));
-
- if (!isContentOnly) {
- assertFalse(filter.contains("/apps/demo-cp"));
- }
- assertFalse(filter.contains("/home/users/system"));
- assertFalse(filter.contains("/home/users/system/demo-cp"));
- assertFalse(filter.contains("/home/users/system/cq:services/demo-cp"));
-
- assertTrue(filter.contains("<filter root=\"/demo-cp\"/>"));
- assertTrue(filter.contains("<filter root=\"/home/users/demo-cp\">"));
- assertTrue(filter.contains("<filter root=\"/home/groups/demo-cp\">"));
-
- // verify that explicit excludes have been added for filter roots that contain mixed content
- assertTrue(filter.contains("<exclude pattern=\"/home/groups/demo-cp/_rep_policy.xml\"/>"));
- assertTrue(filter.contains("<exclude pattern=\"/home/users/demo-cp/_rep_policy.xml\"/>"));
+ filter.load(zipFile.getInputStream(entry));
}
+ return filter;
}
}
diff --git a/src/test/java/org/apache/sling/feature/cpconverter/vltpkg/VaultPackageAssemblerTest.java b/src/test/java/org/apache/sling/feature/cpconverter/vltpkg/VaultPackageAssemblerTest.java
index 76b6ffc..efc96f5 100644
--- a/src/test/java/org/apache/sling/feature/cpconverter/vltpkg/VaultPackageAssemblerTest.java
+++ b/src/test/java/org/apache/sling/feature/cpconverter/vltpkg/VaultPackageAssemblerTest.java
@@ -16,20 +16,11 @@
*/
package org.apache.sling.feature.cpconverter.vltpkg;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.net.URL;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipFile;
-import java.util.zip.ZipInputStream;
-
import org.apache.commons.io.FileUtils;
+import org.apache.jackrabbit.vault.fs.api.ImportMode;
+import org.apache.jackrabbit.vault.fs.api.PathFilterSet;
+import org.apache.jackrabbit.vault.fs.config.DefaultWorkspaceFilter;
+import org.apache.jackrabbit.vault.fs.filter.DefaultPathFilter;
import org.apache.jackrabbit.vault.packaging.PackageId;
import org.apache.jackrabbit.vault.packaging.VaultPackage;
import org.apache.jackrabbit.vault.packaging.impl.PackageManagerImpl;
@@ -40,6 +31,20 @@ import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
@RunWith(Parameterized.class)
public class VaultPackageAssemblerTest {
@@ -107,6 +112,35 @@ public class VaultPackageAssemblerTest {
assertTrue("Storing Directory for Vault Package does not exist", storingDirectory.exists());
}
+ @Test
+ public void testMergeFiltersWithPropertyFilterSet() throws Exception {
+ PathFilterSet nodeFilter = new PathFilterSet();
+ nodeFilter.setRoot("/test");
+ nodeFilter.setImportMode(ImportMode.MERGE);
+ nodeFilter.addExclude(new DefaultPathFilter(".*/pattern"));
+ nodeFilter.addInclude(new DefaultPathFilter("/test/content/subtree"));
+
+ PathFilterSet propFilter = new PathFilterSet();
+ propFilter.setRoot("/test");
+ propFilter.addExclude(new DefaultPathFilter(".*/excludedProperty"));
+
+ DefaultWorkspaceFilter toMerge = new DefaultWorkspaceFilter();
+ toMerge.add(nodeFilter, propFilter);
+
+ List<PathFilterSet> before = new ArrayList<>(assembler.getFilter().getFilterSets());
+ List<PathFilterSet> beforeProperties = new ArrayList<>(assembler.getFilter().getPropertyFilterSets());
+
+ assembler.mergeFilters(toMerge);
+
+ List<PathFilterSet> after = assembler.getFilter().getFilterSets();
+ assertEquals(before.size()+1, after.size());
+ assertTrue(after.contains(nodeFilter));
+
+ List<PathFilterSet> afterProperties = assembler.getFilter().getPropertyFilterSets();
+ assertEquals(beforeProperties.size()+1, afterProperties.size());
+ assertTrue(afterProperties.contains(propFilter));
+ }
+
@Parameters
public static Collection<Object[]> data() throws Exception {
return Arrays.asList(new Object[][] {
diff --git a/src/test/resources/org/apache/sling/feature/cpconverter/demo-cp-single-user-root.zip b/src/test/resources/org/apache/sling/feature/cpconverter/demo-cp-single-user-root.zip
new file mode 100644
index 0000000..bf4ceda
Binary files /dev/null and b/src/test/resources/org/apache/sling/feature/cpconverter/demo-cp-single-user-root.zip differ
diff --git a/src/test/resources/org/apache/sling/feature/cpconverter/demo-cp-with-importmode.zip b/src/test/resources/org/apache/sling/feature/cpconverter/demo-cp-with-importmode.zip
new file mode 100644
index 0000000..a0e2af5
Binary files /dev/null and b/src/test/resources/org/apache/sling/feature/cpconverter/demo-cp-with-importmode.zip differ