diff --git a/pom.xml b/pom.xml index f6ae19f..e4e81ce 100644 --- a/pom.xml +++ b/pom.xml @@ -211,7 +211,7 @@ org.mockito mockito-core - 2.23.0 + 4.8.0 test diff --git a/src/main/java/org/apache/sling/feature/extension/content/ContentHandler.java b/src/main/java/org/apache/sling/feature/extension/content/ContentHandler.java index 80e2553..7815993 100644 --- a/src/main/java/org/apache/sling/feature/extension/content/ContentHandler.java +++ b/src/main/java/org/apache/sling/feature/extension/content/ContentHandler.java @@ -18,6 +18,7 @@ import java.io.ByteArrayOutputStream; import java.io.File; +import java.io.IOException; import java.net.URL; import java.nio.file.Paths; import java.util.ArrayList; @@ -29,6 +30,7 @@ import java.util.TreeMap; import org.apache.jackrabbit.vault.fs.io.ImportOptions; +import org.apache.jackrabbit.vault.packaging.PackageException; import org.apache.jackrabbit.vault.packaging.PackageExistsException; import org.apache.jackrabbit.vault.packaging.PackageId; import org.apache.jackrabbit.vault.packaging.registry.ExecutionPlanBuilder; @@ -48,13 +50,15 @@ import org.apache.sling.feature.launcher.spi.extensions.ExtensionHandler; public class ContentHandler implements ExtensionHandler { + static final String SKIP_EXECUTIONPLANS_MSG = "ContentHandler set up to skip building of executionplans - only configuring FSPackageRegistry"; public static final String PACKAGEREGISTRY_HOME = "packageregistry.home"; + public static final String SKIP_EXECUTIONPLANS_PROP = "skipexecutionplans"; private static final String REPOSITORY_HOME = "repository.home"; private static final String REGISTRY_FOLDER = "packageregistry"; - private static ExecutionPlanBuilder buildExecutionPlan(Collection artifacts, Set satisfiedPackages, LauncherPrepareContext prepareContext, File registryHome) throws Exception { + static ExecutionPlanBuilder buildExecutionPlan(Collection artifacts, Set satisfiedPackages, LauncherPrepareContext prepareContext, File registryHome) throws IOException, PackageException { List packageReferences = new ArrayList<>(); @@ -97,42 +101,61 @@ public boolean handle(ExtensionContext context, Extension extension) throws Exce File registryHome = getRegistryHomeDir(context); if (extension.getType() == ExtensionType.ARTIFACTS && extension.getName().equals(Extension.EXTENSION_NAME_CONTENT_PACKAGES)) { - Map> orderedArtifacts = new TreeMap<>(); - for (final Artifact a : extension.getArtifacts()) { - int order; - // content-packages without explicit start-order to be installed last - if (a.getMetadata().get(Artifact.KEY_START_ORDER) != null) { - order = a.getStartOrder(); - } else { - order = Integer.MAX_VALUE; + if(skipBuildExecutionPlans()){ + context.getLogger().info(SKIP_EXECUTIONPLANS_MSG); + } else { + List executionPlans = new ArrayList<>(); + Map> orderedArtifacts = getOrderedArtifacts(extension); + Set satisfiedPackages = new HashSet<>(); + for (Collection artifacts : orderedArtifacts.values()) { + ExecutionPlanBuilder builder = buildExecutionPlan(artifacts, satisfiedPackages, context, registryHome); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + builder.save(baos); + executionPlans.add(baos.toString("UTF-8")); } - orderedArtifacts.computeIfAbsent(order, id -> new ArrayList<>()).add(a); + configurePackageInit(context, registryHome, executionPlans); } - List executionPlans = new ArrayList<>(); - Set satisfiedPackages = new HashSet<>(); - for (Object key : orderedArtifacts.keySet()) { - Collection artifacts = orderedArtifacts.get(key); - ExecutionPlanBuilder builder = buildExecutionPlan(artifacts, satisfiedPackages, context, registryHome); - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - builder.save(baos); - executionPlans.add(baos.toString("UTF-8")); - } - // Workaround for too bold relocation mechanism - corresponding details at https://issues.apache.org/jira/browse/MSHADE-156 - final Configuration initcfg = new Configuration("org.apache.sling.jcr.packageinit.impl.ExecutionPlanRepoInitializer"); - initcfg.getProperties().put("executionplans", executionPlans.toArray(new String[executionPlans.size()])); - initcfg.getProperties().put("statusfilepath", registryHome.getAbsolutePath() + "/executedplans.file"); - context.addConfiguration(initcfg.getPid(), null, initcfg.getProperties()); - // Workaround for too bold relocation mechanism - corresponding details at https://issues.apache.org/jira/browse/MSHADE-156 - final Configuration registrycfg = new Configuration("org.UNSHADE.apache.jackrabbit.vault.packaging.registry.impl.FSPackageRegistry"); - registrycfg.getProperties().put("homePath", registryHome.getPath()); - context.addConfiguration(registrycfg.getPid(), null, registrycfg.getProperties()); - + configureFSRegistry(context, registryHome); return true; } else { return false; } } + private Map> getOrderedArtifacts(Extension extension) { + Map> orderedArtifacts = new TreeMap<>(); + for (final Artifact a : extension.getArtifacts()) { + int order; + // content-packages without explicit start-order to be installed last + if (a.getMetadata().get(Artifact.KEY_START_ORDER) != null) { + order = a.getStartOrder(); + } else { + order = Integer.MAX_VALUE; + } + orderedArtifacts.computeIfAbsent(order, id -> new ArrayList<>()).add(a); + } + return orderedArtifacts; + } + + private void configureFSRegistry(ExtensionContext context, File registryHome) { + // Workaround for too bold relocation mechanism - corresponding details at https://issues.apache.org/jira/browse/MSHADE-156 + final Configuration registrycfg = new Configuration("org.UNSHADE.apache.jackrabbit.vault.packaging.registry.impl.FSPackageRegistry"); + registrycfg.getProperties().put("homePath", registryHome.getPath()); + context.addConfiguration(registrycfg.getPid(), null, registrycfg.getProperties()); + } + + private void configurePackageInit(ExtensionContext context, File registryHome, List executionPlans) { + // Workaround for too bold relocation mechanism - corresponding details at https://issues.apache.org/jira/browse/MSHADE-156 + final Configuration initcfg = new Configuration("org.apache.sling.jcr.packageinit.impl.ExecutionPlanRepoInitializer"); + initcfg.getProperties().put("executionplans", executionPlans.toArray(new String[executionPlans.size()])); + initcfg.getProperties().put("statusfilepath", registryHome.getAbsolutePath() + "/executedplans.file"); + context.addConfiguration(initcfg.getPid(), null, initcfg.getProperties()); + } + + private boolean skipBuildExecutionPlans() { + return Boolean.getBoolean(SKIP_EXECUTIONPLANS_PROP); + } + private File getRegistryHomeDir(ExtensionContext context) { //read repository- home from framework properties (throw exception if repo.home not set) String registryPath = System.getProperty(PACKAGEREGISTRY_HOME); diff --git a/src/test/java/org/apache/sling/feature/extension/content/ContentHandlerTest.java b/src/test/java/org/apache/sling/feature/extension/content/ContentHandlerTest.java index 64ae766..986dffd 100644 --- a/src/test/java/org/apache/sling/feature/extension/content/ContentHandlerTest.java +++ b/src/test/java/org/apache/sling/feature/extension/content/ContentHandlerTest.java @@ -20,6 +20,8 @@ import static org.junit.Assert.assertFalse; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -34,6 +36,7 @@ import org.apache.sling.feature.ExtensionState; import org.apache.sling.feature.ExtensionType; import org.apache.sling.feature.launcher.spi.extensions.ExtensionContext; +import org.junit.Assert; import org.junit.Before; import org.junit.Rule; import org.junit.Test; @@ -43,6 +46,8 @@ import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; +import org.slf4j.Logger; + @RunWith(MockitoJUnitRunner.class) public class ContentHandlerTest { @@ -148,4 +153,28 @@ public void testMultipleStartOrders() throws Exception { assertEquals(expected_1, executionplans[1]); assertFalse(dictIt.hasNext()); } + + @Test + public void testSkipBuilding() throws Exception { + ContentHandler ch = spy(new ContentHandler()); + System.setProperty(ContentHandler.PACKAGEREGISTRY_HOME, testFolder.getRoot().toString()); + System.setProperty(ContentHandler.SKIP_EXECUTIONPLANS_PROP, "true"); + Extension ext = new Extension(ExtensionType.ARTIFACTS, "content-packages", ExtensionState.OPTIONAL); + + Artifact artifact_a = new Artifact(TEST_PACKAGE_AID_A_10); + Artifact artifact_b = new Artifact(TEST_PACKAGE_AID_B_10); + Artifact artifact_c = new Artifact(TEST_PACKAGE_AID_C_10); + ext.getArtifacts().add(artifact_a); + ext.getArtifacts().add(artifact_b); + ext.getArtifacts().add(artifact_c); + + Logger log = mock(Logger.class); + when(extensionContext.getLogger()).thenReturn(log); + + ch.handle(extensionContext, ext); + ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(String.class); + verify(log).info(argumentCaptor.capture()); + Assert.assertEquals(ContentHandler.SKIP_EXECUTIONPLANS_MSG, argumentCaptor.getValue()); + } + }