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/06/09 12:30:20 UTC
[sling-org-apache-sling-feature-cpconverter] 01/01: SLING-10468 :
Converted content package is missing some .content.xml
This is an automated email from the ASF dual-hosted git repository.
angela pushed a commit to branch SLING-10468
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-feature-cpconverter.git
commit d0dddcbc46bec71a74dc38b7f5516ab3f78e30b9
Author: angela <an...@adobe.com>
AuthorDate: Wed Jun 9 14:30:01 2021 +0200
SLING-10468 : Converted content package is missing some .content.xml
---
.../handlers/AbstractUserEntryHandler.java | 30 +++++-
.../cpconverter/handlers/AbstractUserParser.java | 7 +-
.../cpconverter/handlers/UsersEntryHandler.java | 10 +-
.../ContentPackage2FeatureModelConverterTest.java | 107 +++++++++++++++------
.../feature/cpconverter/handlers/TestUtils.java | 13 +--
.../apache/sling/feature/cpconverter/demo-cp.zip | Bin 0 -> 16491 bytes
6 files changed, 121 insertions(+), 46 deletions(-)
diff --git a/src/main/java/org/apache/sling/feature/cpconverter/handlers/AbstractUserEntryHandler.java b/src/main/java/org/apache/sling/feature/cpconverter/handlers/AbstractUserEntryHandler.java
index cc2eb1c..6dfdb5f 100644
--- a/src/main/java/org/apache/sling/feature/cpconverter/handlers/AbstractUserEntryHandler.java
+++ b/src/main/java/org/apache/sling/feature/cpconverter/handlers/AbstractUserEntryHandler.java
@@ -16,18 +16,29 @@
*/
package org.apache.sling.feature.cpconverter.handlers;
+import org.apache.commons.io.IOUtils;
import org.apache.jackrabbit.vault.fs.io.Archive;
import org.apache.jackrabbit.vault.fs.io.Archive.Entry;
import org.apache.jackrabbit.vault.util.PlatformNameFormat;
import org.apache.sling.feature.cpconverter.ContentPackage2FeatureModelConverter;
import org.apache.sling.feature.cpconverter.shared.RepoPath;
+import org.apache.sling.feature.cpconverter.vltpkg.VaultPackageAssembler;
import org.jetbrains.annotations.NotNull;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.sax.SAXTransformerFactory;
+import java.io.ByteArrayInputStream;
import java.io.InputStream;
+import java.io.OutputStream;
import java.util.regex.Matcher;
abstract class AbstractUserEntryHandler extends AbstractRegexEntryHandler {
+ private final SAXTransformerFactory saxTransformerFactory = (SAXTransformerFactory) TransformerFactory.newInstance();
+
+ // FIXME: use first segment of 'systemUserRelPath' config value instead of hardcoding
+ private static final String SYSTEM_USER_SEGMENT = "/system/";
+
AbstractUserEntryHandler(@NotNull String rexex) {
super(rexex);
}
@@ -37,14 +48,23 @@ abstract class AbstractUserEntryHandler extends AbstractRegexEntryHandler {
throws Exception {
Matcher matcher = getPattern().matcher(path);
if (matcher.matches()) {
- path = matcher.group(1);
-
- RepoPath originalPath = new RepoPath(PlatformNameFormat.getRepositoryPath(path));
+ RepoPath originalPath = new RepoPath(PlatformNameFormat.getRepositoryPath(matcher.group(1)));
RepoPath intermediatePath = originalPath.getParent();
+ byte[] tmp = IOUtils.toByteArray((archive.openInputStream(entry)));
AbstractUserParser parser = createParser(converter, originalPath, intermediatePath);
- try (InputStream input = archive.openInputStream(entry)) {
- parser.parse(input);
+ boolean converted = parser.parse(new ByteArrayInputStream(tmp));
+ if (!converted && !path.contains(SYSTEM_USER_SEGMENT)) {
+ // write back regular users, groups and their intermediate folders that did not get converted into
+ // repo-init statements to the content package
+ VaultPackageAssembler assembler = converter.getMainPackageAssembler();
+ // FIXME: assembler is null when handler is called from RecollectorVaultPackageScanner (???)
+ if (assembler != null) {
+ try (InputStream input = new ByteArrayInputStream(tmp);
+ OutputStream output = assembler.createEntry(path)){
+ IOUtils.copy(input, output);
+ }
+ }
}
}
}
diff --git a/src/main/java/org/apache/sling/feature/cpconverter/handlers/AbstractUserParser.java b/src/main/java/org/apache/sling/feature/cpconverter/handlers/AbstractUserParser.java
index 354e9fa..338d3f8 100644
--- a/src/main/java/org/apache/sling/feature/cpconverter/handlers/AbstractUserParser.java
+++ b/src/main/java/org/apache/sling/feature/cpconverter/handlers/AbstractUserParser.java
@@ -22,7 +22,7 @@ import org.apache.sling.feature.cpconverter.shared.RepoPath;
import org.jetbrains.annotations.NotNull;
import org.xml.sax.Attributes;
-abstract class AbstractUserParser extends AbstractJcrNodeParser<Void> {
+abstract class AbstractUserParser extends AbstractJcrNodeParser<Boolean> {
private static final String REP_AUTHORIZABLE_ID = "rep:authorizableId";
@@ -54,8 +54,9 @@ abstract class AbstractUserParser extends AbstractJcrNodeParser<Void> {
}
@Override
- protected Void getParsingResult() {
- return null;
+ protected Boolean getParsingResult() {
+ // false for all intermediate paths, regular users and groups
+ return false;
}
abstract void handleUser(@NotNull String id, @NotNull Attributes attributes);
diff --git a/src/main/java/org/apache/sling/feature/cpconverter/handlers/UsersEntryHandler.java b/src/main/java/org/apache/sling/feature/cpconverter/handlers/UsersEntryHandler.java
index c55f9f7..e1090ed 100644
--- a/src/main/java/org/apache/sling/feature/cpconverter/handlers/UsersEntryHandler.java
+++ b/src/main/java/org/apache/sling/feature/cpconverter/handlers/UsersEntryHandler.java
@@ -47,6 +47,8 @@ public final class UsersEntryHandler extends AbstractUserEntryHandler {
private static final String REP_SYSTEM_USER = "rep:SystemUser";
private static final String REP_USER = "rep:User";
+
+ private boolean isSystemUser = false;
/**
* @param converter - the converter to use.
@@ -64,8 +66,14 @@ public final class UsersEntryHandler extends AbstractUserEntryHandler {
converter.getAclManager().addUser(new User(id, path, intermediatePath, disabledReason));
} else {
converter.getAclManager().addSystemUser(new SystemUser(id, path, intermediatePath, disabledReason));
+ isSystemUser = true;
}
}
- }
+ @Override
+ protected Boolean getParsingResult() {
+ // intermediate paths and regular users are never handled by repo-init
+ return isSystemUser;
+ }
+ }
}
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 36b0d32..32a39b6 100644
--- a/src/test/java/org/apache/sling/feature/cpconverter/ContentPackage2FeatureModelConverterTest.java
+++ b/src/test/java/org/apache/sling/feature/cpconverter/ContentPackage2FeatureModelConverterTest.java
@@ -71,6 +71,7 @@ import org.apache.sling.feature.cpconverter.handlers.DefaultEntryHandlersManager
import org.apache.sling.feature.cpconverter.handlers.EntryHandlersManager;
import org.apache.sling.feature.cpconverter.vltpkg.DefaultPackagesEventsEmitter;
import org.apache.sling.feature.io.json.FeatureJSONReader;
+import org.jetbrains.annotations.NotNull;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -81,11 +82,11 @@ public class ContentPackage2FeatureModelConverterTest {
* Test package A-1.0. Depends on B and C-1.X
* Test package B-1.0. Depends on C
*/
- private static String[] TEST_PACKAGES_INPUT = { "test_c-1.0.zip", "test_a-1.0.zip", "test_b-1.0.zip" };
+ private static final String[] TEST_PACKAGES_INPUT = { "test_c-1.0.zip", "test_a-1.0.zip", "test_b-1.0.zip" };
- private static String[] TEST_PACKAGES_OUTPUT = { "my_packages:test_c:1.0", "my_packages:test_b:1.0", "my_packages:test_a:1.0" };
+ private static final String[] TEST_PACKAGES_OUTPUT = { "my_packages:test_c:1.0", "my_packages:test_b:1.0", "my_packages:test_a:1.0" };
- private static String[] TEST_PACKAGES_CYCLIC_DEPENDENCY = { "test_d-1.0.zip",
+ private static final String[] TEST_PACKAGES_CYCLIC_DEPENDENCY = { "test_d-1.0.zip",
"test_c-1.0.zip",
"test_a-1.0.zip",
"test_b-1.0.zip",
@@ -156,8 +157,8 @@ public class ContentPackage2FeatureModelConverterTest {
verifyFeatureFile(outputDirectory,
"asd.retail.all.json",
"asd.sample:asd.retail.all:slingosgifeature:0.0.1",
- Arrays.asList("org.apache.felix:org.apache.felix.framework:6.0.1"),
- Arrays.asList("org.apache.sling.commons.log.LogManager.factory.config~asd-retail"),
+ Collections.singletonList("org.apache.felix:org.apache.felix.framework:6.0.1"),
+ Collections.singletonList("org.apache.sling.commons.log.LogManager.factory.config~asd-retail"),
Arrays.asList("asd.sample:asd.retail.apps:zip:cp2fm-converted:0.0.1",
"asd.sample:Asd.Retail.ui.content:zip:cp2fm-converted:0.0.1",
"asd:Asd.Retail.config:zip:cp2fm-converted:0.0.1",
@@ -165,14 +166,14 @@ public class ContentPackage2FeatureModelConverterTest {
verifyFeatureFile(outputDirectory,
"asd.retail.all-author.json",
"asd.sample:asd.retail.all:slingosgifeature:author:0.0.1",
- Arrays.asList("org.apache.sling:org.apache.sling.api:2.20.0"),
+ Collections.singletonList("org.apache.sling:org.apache.sling.api:2.20.0"),
Collections.emptyList(),
Collections.emptyList());
verifyFeatureFile(outputDirectory,
"asd.retail.all-publish.json",
"asd.sample:asd.retail.all:slingosgifeature:publish:0.0.1",
- Arrays.asList("org.apache.sling:org.apache.sling.models.api:1.3.8"),
- Arrays.asList("org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.amended~asd-retail"),
+ Collections.singletonList("org.apache.sling:org.apache.sling.models.api:1.3.8"),
+ Collections.singletonList("org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.amended~asd-retail"),
Collections.emptyList());
// verify the runmode.mapper integrity
@@ -237,21 +238,20 @@ public class ContentPackage2FeatureModelConverterTest {
verifyFeatureFile(outputDirectory,
"asd.retail.all.json",
"asd.sample:asd.retail.all:slingosgifeature:0.0.1",
- Arrays.asList("org.apache.felix:org.apache.felix.framework:6.0.1"),
- Arrays.asList("org.apache.sling.commons.log.LogManager.factory.config~asd-retail"),
- Arrays.asList("asd.sample:asd.retail.apps:zip:cp2fm-converted:0.0.1",
- "asd:Asd.Retail.config:zip:cp2fm-converted:0.0.1"));
+ Collections.singletonList("org.apache.felix:org.apache.felix.framework:6.0.1"),
+ Collections.singletonList("org.apache.sling.commons.log.LogManager.factory.config~asd-retail"),
+ Arrays.asList("asd.sample:asd.retail.apps:zip:cp2fm-converted:0.0.1", "asd:Asd.Retail.config:zip:cp2fm-converted:0.0.1"));
verifyFeatureFile(outputDirectory,
"asd.retail.all-author.json",
"asd.sample:asd.retail.all:slingosgifeature:author:0.0.1",
- Arrays.asList("org.apache.sling:org.apache.sling.api:2.20.0"),
+ Collections.singletonList("org.apache.sling:org.apache.sling.api:2.20.0"),
Collections.emptyList(),
Collections.emptyList());
verifyFeatureFile(outputDirectory,
"asd.retail.all-publish.json",
"asd.sample:asd.retail.all:slingosgifeature:publish:0.0.1",
- Arrays.asList("org.apache.sling:org.apache.sling.models.api:1.3.8"),
- Arrays.asList("org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.amended~asd-retail"),
+ Collections.singletonList("org.apache.sling:org.apache.sling.models.api:1.3.8"),
+ Collections.singletonList("org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.amended~asd-retail"),
Collections.emptyList());
// verify the runmode.mapper integrity
@@ -309,21 +309,21 @@ public class ContentPackage2FeatureModelConverterTest {
verifyFeatureFile(outputDirectory,
"asd.retail.all.json",
"asd.sample:asd.retail.all:slingosgifeature:0.0.1",
- Arrays.asList("org.apache.felix:org.apache.felix.framework:6.0.1"),
- Arrays.asList("org.apache.sling.commons.log.LogManager.factory.config~asd-retail"),
+ Collections.singletonList("org.apache.felix:org.apache.felix.framework:6.0.1"),
+ Collections.singletonList("org.apache.sling.commons.log.LogManager.factory.config~asd-retail"),
Arrays.asList("asd.sample:asd.retail.apps:zip:cp2fm-converted:0.0.1",
"asd:Asd.Retail.config:zip:cp2fm-converted:0.0.1"));
verifyFeatureFile(outputDirectory,
"asd.retail.all-author.json",
"asd.sample:asd.retail.all:slingosgifeature:author:0.0.1",
- Arrays.asList("org.apache.sling:org.apache.sling.api:2.20.0"),
+ Collections.singletonList("org.apache.sling:org.apache.sling.api:2.20.0"),
Collections.emptyList(),
Collections.emptyList());
verifyFeatureFile(outputDirectory,
"asd.retail.all-publish.json",
"asd.sample:asd.retail.all:slingosgifeature:publish:0.0.1",
- Arrays.asList("org.apache.sling:org.apache.sling.models.api:1.3.8"),
- Arrays.asList("org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.amended~asd-retail"),
+ Collections.singletonList("org.apache.sling:org.apache.sling.models.api:1.3.8"),
+ Collections.singletonList("org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.amended~asd-retail"),
Collections.emptyList());
// verify the runmode.mapper integrity
@@ -584,10 +584,16 @@ public class ContentPackage2FeatureModelConverterTest {
}
private void verifyContentPackage(File contentPackage, String...expectedEntries) throws Exception {
+ verifyContentPackage(contentPackage, Collections.emptySet(), expectedEntries);
+ }
+
+ private void verifyContentPackage(File contentPackage, @NotNull Set<String> notExpected, String...expectedEntries) throws Exception {
try (ZipFile zipFile = new ZipFile(contentPackage)) {
for (String expectedEntry : expectedEntries) {
- assertNotNull("Expected entry not found: " + expectedEntry + " in file " + contentPackage,
- zipFile.getEntry(expectedEntry));
+ assertNotNull("Expected entry not found: " + expectedEntry + " in file " + contentPackage, zipFile.getEntry(expectedEntry));
+ }
+ for (String notExpectedEntry : notExpected) {
+ assertNull("Not expected entry found: " + notExpectedEntry + " in file " + contentPackage, zipFile.getEntry(notExpectedEntry));
}
}
}
@@ -750,7 +756,7 @@ public class ContentPackage2FeatureModelConverterTest {
try {
converter.setBundlesDeployer(new LocalMavenRepositoryArtifactsDeployer(outDir))
.setFeaturesManager(new DefaultFeaturesManager(false, 5, outDir, null, null, null, new DefaultAclManager())
- .setAPIRegions(Arrays.asList("a.b.c")))
+ .setAPIRegions(Collections.singletonList("a.b.c")))
.setEmitter(DefaultPackagesEventsEmitter.open(outDir))
.convert(cpFile);
@@ -798,8 +804,8 @@ public class ContentPackage2FeatureModelConverterTest {
verifyFeatureFile(outputDirectory,
"asd.retail.all.json",
"${project.groupId}:${project.artifactId}:slingosgifeature:asd.test.all-1.0.0:${project.version}",
- Arrays.asList("org.apache.felix:org.apache.felix.framework:6.0.1"),
- Arrays.asList("org.apache.sling.commons.log.LogManager.factory.config~asd-retail"),
+ Collections.singletonList("org.apache.felix:org.apache.felix.framework:6.0.1"),
+ Collections.singletonList("org.apache.sling.commons.log.LogManager.factory.config~asd-retail"),
Arrays.asList("asd.sample:asd.retail.apps:zip:cp2fm-converted:0.0.1",
"asd.sample:Asd.Retail.ui.content:zip:cp2fm-converted:0.0.1",
"asd:Asd.Retail.config:zip:cp2fm-converted:0.0.1",
@@ -807,14 +813,14 @@ public class ContentPackage2FeatureModelConverterTest {
verifyFeatureFile(outputDirectory,
"asd.retail.all-author.json",
"${project.groupId}:${project.artifactId}:slingosgifeature:asd.test.all-1.0.0-author:${project.version}",
- Arrays.asList("org.apache.sling:org.apache.sling.api:2.20.0"),
+ Collections.singletonList("org.apache.sling:org.apache.sling.api:2.20.0"),
Collections.emptyList(),
Collections.emptyList());
verifyFeatureFile(outputDirectory,
"asd.retail.all-publish.json",
"${project.groupId}:${project.artifactId}:slingosgifeature:asd.test.all-1.0.0-publish:${project.version}",
- Arrays.asList("org.apache.sling:org.apache.sling.models.api:1.3.8"),
- Arrays.asList("org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.amended~asd-retail"),
+ Collections.singletonList("org.apache.sling:org.apache.sling.models.api:1.3.8"),
+ Collections.singletonList("org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.amended~asd-retail"),
Collections.emptyList());
verifyContentPackage(new File(outputDirectory, "asd/sample/asd.retail.all/0.0.1/asd.retail.all-0.0.1-cp2fm-converted.zip"),
@@ -978,4 +984,49 @@ public class ContentPackage2FeatureModelConverterTest {
return loadedResources;
}
+ @Test
+ public void testConvertPackageWithUsersGroupsAndServiceUsers() throws Exception {
+ URL packageUrl = getClass().getResource("demo-cp.zip");
+ File packageFile = FileUtils.toFile(packageUrl);
+ 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(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<>();
+ notExpected.add("jcr_root/apps/demo-cp/.content.xml");
+ notExpected.add("jcr_root/home/users/demo-cp/_rep_policy.xml");
+ notExpected.add("jcr_root/home/groups/demo-cp/_rep_policy.xml");
+ notExpected.add("jcr_root/home/users/system/.content.xml");
+ notExpected.add("jcr_root/home/users/system/_cq_services/.content.xml");
+ notExpected.add("jcr_root/home/users/system/_cq_services/demo-cp/.content.xml");
+ notExpected.add("jcr_root/home/users/system/_cq_services/demo-cp/qStDu7IQBLa95gURmer1/.content.xml");
+ notExpected.add("jcr_root/home/users/system/_cq_services/demo-cp/qStDu7IQBLa95gURmer1/_rep_principalPolicy.xml");
+ verifyContentPackage(converted,
+ notExpected,
+ "META-INF/vault/properties.xml",
+ "META-INF/vault/config.xml",
+ "META-INF/vault/filter.xml",
+ "jcr_root/.content.xml",
+ "jcr_root/demo-cp/.content.xml",
+ "jcr_root/demo-cp/_rep_policy.xml",
+ "jcr_root/apps/.content.xml",
+ "jcr_root/home/.content.xml",
+ "jcr_root/home/users/demo-cp/.content.xml",
+ "jcr_root/home/users/demo-cp/XPXhA_RKMFRKNO8ViIhn/.content.xml",
+ "jcr_root/home/users/demo-cp/XPXhA_RKMFRKNO8ViIhn/_rep_policy.xml",
+ "jcr_root/home/groups/.content.xml",
+ "jcr_root/home/groups/demo-cp/.content.xml",
+ "jcr_root/home/groups/demo-cp/EsYrXeBdSRkna2kqbxjl/.content.xml",
+ "jcr_root/home/groups/demo-cp/EsYrXeBdSRkna2kqbxjl/_rep_policy.xml"
+ );
+
+ } finally {
+ deleteDirTree(outputDirectory);
+ }
+ }
+
}
diff --git a/src/test/java/org/apache/sling/feature/cpconverter/handlers/TestUtils.java b/src/test/java/org/apache/sling/feature/cpconverter/handlers/TestUtils.java
index a532490..f470427 100644
--- a/src/test/java/org/apache/sling/feature/cpconverter/handlers/TestUtils.java
+++ b/src/test/java/org/apache/sling/feature/cpconverter/handlers/TestUtils.java
@@ -26,15 +26,13 @@ import org.apache.sling.feature.cpconverter.features.DefaultFeaturesManager;
import org.apache.sling.feature.cpconverter.features.FeaturesManager;
import org.apache.sling.feature.cpconverter.vltpkg.VaultPackageAssembler;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.io.ByteArrayOutputStream;
import java.io.File;
-import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
-import java.security.acl.Acl;
import java.util.Collections;
import static org.mockito.ArgumentMatchers.anyString;
@@ -49,17 +47,14 @@ class TestUtils {
private TestUtils() {}
static Extension createRepoInitExtension(@NotNull EntryHandler handler, @NotNull AclManager aclManager, @NotNull String path, @NotNull InputStream is) throws Exception {
- return createRepoInitExtension(handler, aclManager, path, is, null);
+ return createRepoInitExtension(handler, aclManager, path, is, new ByteArrayOutputStream());
}
- static Extension createRepoInitExtension(@NotNull EntryHandler handler, @NotNull AclManager aclManager, @NotNull String path, @NotNull InputStream is, @Nullable OutputStream out) throws Exception {
+ static Extension createRepoInitExtension(@NotNull EntryHandler handler, @NotNull AclManager aclManager, @NotNull String path, @NotNull InputStream is, @NotNull OutputStream out) throws Exception {
Archive archive = mock(Archive.class);
Archive.Entry entry = mock(Archive.Entry.class);
VaultPackageAssembler packageAssembler = mock(VaultPackageAssembler.class);
- if (out != null) {
- when(packageAssembler.createEntry(anyString())).thenReturn(out);
- }
-
+ when(packageAssembler.createEntry(anyString())).thenReturn(out);
when(archive.openInputStream(entry)).thenReturn(is);
Feature feature = new Feature(new ArtifactId("org.apache.sling", "org.apache.sling.cp2fm", "0.0.1", null, null));
diff --git a/src/test/resources/org/apache/sling/feature/cpconverter/demo-cp.zip b/src/test/resources/org/apache/sling/feature/cpconverter/demo-cp.zip
new file mode 100644
index 0000000..8143f45
Binary files /dev/null and b/src/test/resources/org/apache/sling/feature/cpconverter/demo-cp.zip differ