Skip to content

Commit

Permalink
add subpackage and embedded package sorting by dependency
Browse files Browse the repository at this point in the history
  • Loading branch information
adamcin committed Sep 10, 2020
1 parent f720ec6 commit 6c5161f
Show file tree
Hide file tree
Showing 8 changed files with 156 additions and 17 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ behavior.
- Added caliper content-package module structure to provide a common basis for oakpal self-test
functionality in the future. The intention is for it eventually to drive at least one example
of every event expressible to a ProgressCheck by the OakMachine.
- Added subpackage and embedded package sorted installation similar to BEST_EFFORT DependencyHandling behavior
to give some expectation and control of predictable install order.

## [2.1.0] - 2020-05-28

Expand Down
13 changes: 13 additions & 0 deletions calipers/ui.apps.author/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,13 @@
<properties>
<cloudManagerTarget>none</cloudManagerTarget>
</properties>
<dependencies>
<dependency>
<groupId>net.adamcin.oakpal</groupId>
<artifactId>oakpal-caliper.ui.apps</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
<repositoryStructurePackages>
<repositoryStructurePackage>
<groupId>net.adamcin.oakpal</groupId>
Expand All @@ -72,6 +79,12 @@
</plugins>
</build>
<dependencies>
<dependency>
<groupId>net.adamcin.oakpal</groupId>
<artifactId>oakpal-caliper.ui.apps</artifactId>
<version>2.2.0-SNAPSHOT</version>
<type>zip</type>
</dependency>
<dependency>
<groupId>net.adamcin.oakpal</groupId>
<artifactId>oakpal-caliper.ui.apps.structure</artifactId>
Expand Down
13 changes: 13 additions & 0 deletions calipers/ui.apps.publish/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,13 @@
<properties>
<cloudManagerTarget>none</cloudManagerTarget>
</properties>
<dependencies>
<dependency>
<groupId>net.adamcin.oakpal</groupId>
<artifactId>oakpal-caliper.ui.apps</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
<repositoryStructurePackages>
<repositoryStructurePackage>
<groupId>net.adamcin.oakpal</groupId>
Expand All @@ -72,6 +79,12 @@
</plugins>
</build>
<dependencies>
<dependency>
<groupId>net.adamcin.oakpal</groupId>
<artifactId>oakpal-caliper.ui.apps</artifactId>
<version>2.2.0-SNAPSHOT</version>
<type>zip</type>
</dependency>
<dependency>
<groupId>net.adamcin.oakpal</groupId>
<artifactId>oakpal-caliper.ui.apps.structure</artifactId>
Expand Down
11 changes: 11 additions & 0 deletions calipers/ui.content.suba2/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,11 @@
<artifactId>oakpal-caliper.ui.apps</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>net.adamcin.oakpal</groupId>
<artifactId>oakpal-caliper.ui.content.subc1</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</configuration>
</plugin>
Expand All @@ -74,5 +79,11 @@
<version>2.2.0-SNAPSHOT</version>
<type>zip</type>
</dependency>
<dependency>
<groupId>net.adamcin.oakpal</groupId>
<artifactId>oakpal-caliper.ui.content.subc1</artifactId>
<version>2.2.0-SNAPSHOT</version>
<type>zip</type>
</dependency>
</dependencies>
</project>
11 changes: 11 additions & 0 deletions calipers/ui.content.subb3/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,11 @@
<artifactId>oakpal-caliper.ui.apps</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>net.adamcin.oakpal</groupId>
<artifactId>oakpal-caliper.ui.content.suba2</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</configuration>
</plugin>
Expand All @@ -74,5 +79,11 @@
<version>2.2.0-SNAPSHOT</version>
<type>zip</type>
</dependency>
<dependency>
<groupId>net.adamcin.oakpal</groupId>
<artifactId>oakpal-caliper.ui.content.suba2</artifactId>
<version>2.2.0-SNAPSHOT</version>
<type>zip</type>
</dependency>
</dependencies>
</project>
50 changes: 38 additions & 12 deletions core/src/main/java/net/adamcin/oakpal/core/OakMachine.java
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
import org.apache.jackrabbit.oak.spi.xml.ProtectedItemImporter;
import org.apache.jackrabbit.vault.fs.api.ProgressTrackerListener;
import org.apache.jackrabbit.vault.packaging.DependencyHandling;
import org.apache.jackrabbit.vault.packaging.DependencyUtil;
import org.apache.jackrabbit.vault.packaging.InstallHookProcessorFactory;
import org.apache.jackrabbit.vault.packaging.JcrPackage;
import org.apache.jackrabbit.vault.packaging.JcrPackageManager;
Expand Down Expand Up @@ -80,6 +81,7 @@
import java.util.Collections;
import java.util.EnumSet;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Optional;
import java.util.Properties;
Expand Down Expand Up @@ -816,24 +818,48 @@ private void processPackage(Session admin, JcrPackageManager manager, JcrPackage
admin.save();

final SubPackageHandling subPackageHandling = jcrPackage.getPackage().getSubPackageHandling();
final List<PackageId> installableSubpacks = new ArrayList<>();
final EnumSet<SubPackageHandling.Option> installableOptions =
EnumSet.complementOf(EnumSet.of(SubPackageHandling.Option.ADD, SubPackageHandling.Option.IGNORE));
for (PackageId subpackId : subpacks) {
final SubPackageHandling.Option option = subPackageHandling.getOption(subpackId);
if (installableOptions.contains(option)) {
installableSubpacks.add(subpackId);
}
}

jcrPackage.close();

propagateCheckPackageEvent(preInstall, packageId, handler -> handler.afterExtract(packageId, inspectSession));

for (PackageId subpackId : installableSubpacks) {
processSubpackage(admin, manager, subpackId, packageId,
preInstall || subpackageSilencer.test(subpackId, packageId));
if (!subpacks.isEmpty()) {
final List<PackageId> installableSubpacks =
preprocessInstallableSubpackages(manager, packageId, subPackageHandling, subpacks);

for (PackageId subpackId : installableSubpacks) {
processSubpackage(admin, manager, subpackId, packageId,
preInstall || subpackageSilencer.test(subpackId, packageId));
}
}
}

List<PackageId> preprocessInstallableSubpackages(final JcrPackageManager manager,
final PackageId parentPackageId,
final SubPackageHandling subPackageHandling,
final List<PackageId> subpacks)
throws RepositoryException, IOException {
final List<PackageId> installSequence = new ArrayList<>();
final EnumSet<SubPackageHandling.Option> installableOptions =
EnumSet.complementOf(EnumSet.of(SubPackageHandling.Option.ADD, SubPackageHandling.Option.IGNORE));

final List<JcrPackage> sortable = new LinkedList<>();
try {
for (PackageId packageId : subpacks) {
sortable.add(manager.open(packageId));
}
Fun.<List<JcrPackage>>resultNothing1(DependencyUtil::sortPackages).apply(sortable);
for (JcrPackage sorted : sortable) {
final PackageId sortedId = sorted.getPackage().getId();
final SubPackageHandling.Option option = subPackageHandling.getOption(sortedId);
if (installableOptions.contains(option)) {
installSequence.add(sortedId);
}
}
} finally {
sortable.forEach(JcrPackage::close);
}
return installSequence;
}

static Consumer<ProgressCheck>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
import org.apache.felix.cm.file.ConfigurationHandler;
import org.apache.felix.cm.json.Configurations;
import org.apache.jackrabbit.commons.JcrUtils;
import org.apache.jackrabbit.vault.packaging.CyclicDependencyException;
import org.apache.jackrabbit.vault.packaging.DependencyUtil;
import org.apache.jackrabbit.vault.packaging.JcrPackage;
import org.apache.jackrabbit.vault.packaging.JcrPackageManager;
import org.apache.jackrabbit.vault.packaging.PackageId;
Expand All @@ -48,6 +50,7 @@
import java.io.Reader;
import java.lang.reflect.Array;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Dictionary;
import java.util.Enumeration;
Expand All @@ -58,16 +61,18 @@
import java.util.Map;
import java.util.Optional;
import java.util.Properties;
import java.util.Queue;
import java.util.function.Function;

import static net.adamcin.oakpal.api.Fun.inferTest1;
import static net.adamcin.oakpal.api.Fun.result0;
import static net.adamcin.oakpal.api.Fun.result1;
import static net.adamcin.oakpal.api.Fun.toEntry;

/**
* Noop implementation of a SlingSimulator.
*/
public final class DefaultSlingSimulator implements SlingSimulatorBackend, SlingSimulator {

public static SlingSimulatorBackend instance() {
return new DefaultSlingSimulator();
}
Expand All @@ -77,7 +82,7 @@ public static SlingSimulatorBackend instance() {

private ErrorListener errorListener;

private final Queue<SlingInstallable> installables = new LinkedList<>();
private final LinkedList<SlingInstallable> installables = new LinkedList<>();

@Override
public void startedScan() {
Expand Down Expand Up @@ -137,6 +142,12 @@ <T extends SlingInstallable> Optional<T> createInstallableOrReport(final @NotNul
}
}

void internalAddInstallable(final @NotNull SlingInstallable installable) {
installables.removeIf(registered ->
installable.getJcrPath().equals(registered.getJcrPath()));
installables.add(installable);
}

@Override
public @Nullable SlingInstallable addInstallableNode(final @NotNull PackageId parentPackageId,
final @NotNull Node node) {
Expand All @@ -151,11 +162,63 @@ <T extends SlingInstallable> Optional<T> createInstallableOrReport(final @NotNul
.toOptional().flatMap(Function.identity())
.orElse(null);
if (installable != null) {
installables.add(installable);
internalAddInstallable(installable);
}
if (installable instanceof EmbeddedPackageInstallable) {
Fun.resultNothing1(DefaultSlingSimulator::shufflePackagesByDependency).apply(this);
}
return installable;
}

LinkedList<SlingInstallable> getInstallables() {
return installables;
}

void shufflePackagesByDependency() throws RepositoryException, CyclicDependencyException, IOException {
final Map<PackageId, EmbeddedPackageInstallable> originalLookup = getInstallables().stream()
.filter(EmbeddedPackageInstallable.class::isInstance)
.map(EmbeddedPackageInstallable.class::cast)
.map(inst -> toEntry(inst.getEmbeddedId(), inst))
.collect(Fun.entriesToMapOfType(LinkedHashMap::new, Fun.keepFirstMerger()));

final List<PackageId> originalOrder = new ArrayList<>(originalLookup.keySet());
final List<PackageId> sortedOrder = new ArrayList<>();

final List<JcrPackage> closeable = new LinkedList<>();
final List<VaultPackage> sortable = new LinkedList<>();
try {
for (PackageId key : originalOrder) {
final JcrPackage jcrPack = packageManager.open(session.getNode(originalLookup.get(key).getJcrPath()),
true);
closeable.add(jcrPack);
sortable.add(jcrPack.getPackage());
}
DependencyUtil.sort(sortable);
for (VaultPackage pack : sortable) {
sortedOrder.add(pack.getId());
}
} finally {
closeable.forEach(Fun.toVoid1(Fun.resultNothing1(JcrPackage::close)));
}

if (sortedOrder.size() == originalOrder.size() && !originalOrder.equals(sortedOrder)) {
for (int i = 0; i < originalOrder.size(); i++) {
if (!originalOrder.get(i).equals(sortedOrder.get(i))) {
for (PackageId key : sortedOrder.subList(i, sortedOrder.size())) {
final EmbeddedPackageInstallable installable = originalLookup.get(key);
if (getInstallables().removeIf(inferTest1(EmbeddedPackageInstallable.class::isInstance)
.and(registered ->
key.equals(((EmbeddedPackageInstallable) registered).getEmbeddedId())))) {

internalAddInstallable(installable);
}
}
break;
}
}
}
}

static final String SLING_NS = "http://sling.apache.org/jcr/sling/1.0";
static final String SLING_OSGI_CONFIG = "{" + SLING_NS + "}OsgiConfig";
static final String JCR_CONTENT_DATA = "jcr:content/jcr:data";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ public Collection<Violation> getReportedViolations() {
.build()
.scanPackage(grandTourPackage);

assertEquals("expect identified packages in set", new HashSet<>(installOrderFull),
identifiedPackageIds.stream().map(PackageId::getName).collect(Collectors.toSet()));
assertEquals("expect identified packages in set", installOrderFull,
identifiedPackageIds.stream().map(PackageId::getName).collect(Collectors.toList()));
}
}

0 comments on commit 6c5161f

Please sign in to comment.