Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fixed handling of ifModified property #413

Merged
merged 5 commits into from
Oct 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,12 @@
import com.day.cq.commons.jcr.JcrConstants;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import javax.annotation.PostConstruct;
Expand Down Expand Up @@ -260,4 +262,29 @@ public static boolean isScript(Resource resource) {
private static List<String> getArrayProperty(Resource resource, String name) {
return Lists.newArrayList(resource.getValueMap().get(name, new String[]{}));
}

@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj instanceof ScriptModel) {
ScriptModel that = (ScriptModel) obj;
return Objects.equals(path, that.path)
&& Objects.equals(launchEnabled, that.launchEnabled)
&& Objects.equals(launchMode, that.launchMode)
&& Objects.equals(launchEnvironment, that.launchEnvironment)
&& Arrays.equals(launchRunModes, that.launchRunModes)
&& Objects.equals(launchHook, that.launchHook)
&& Objects.equals(launchSchedule, that.launchSchedule)
&& Objects.equals(checksum, that.checksum)
&& Objects.equals(verified, that.verified);
}
return false;
}

@Override
public int hashCode() {
return Objects.hashCode(path);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,19 @@
*/
package com.cognifide.apm.core.utils;

import java.lang.management.ManagementFactory;
import javax.jcr.Node;
import javax.jcr.Session;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.apache.sling.api.resource.ResourceResolver;

@NoArgsConstructor(access = AccessLevel.PRIVATE)
public final class RuntimeUtils {

private static final String AEM_MUTABLE_CONTENT_INSTANCE = "aem-install-mutable-content";

public static boolean determineCompositeNodeStore(ResourceResolver resolver) {
boolean result;
try {
Expand All @@ -43,4 +47,9 @@ public static boolean determineCompositeNodeStore(ResourceResolver resolver) {
return result;
}

public static boolean isMutableContentInstance(ResourceResolver resolver) {
boolean compositeNodeStore = RuntimeUtils.determineCompositeNodeStore(resolver);
String instanceName = ManagementFactory.getRuntimeMXBean().getName();
return !compositeNodeStore || StringUtils.contains(instanceName, AEM_MUTABLE_CONTENT_INSTANCE);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,23 +32,29 @@
import com.cognifide.apm.core.services.version.VersionService;
import com.cognifide.apm.core.utils.RuntimeUtils;
import com.cognifide.apm.core.utils.sling.SlingHelper;
import java.lang.management.ManagementFactory;
import java.util.Arrays;
import java.util.Collections;
import java.util.Dictionary;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
import org.apache.commons.lang3.StringUtils;
import org.apache.sling.api.resource.PersistenceException;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.observation.ResourceChange;
import org.apache.sling.api.resource.observation.ResourceChangeListener;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Deactivate;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.metatype.annotations.AttributeDefinition;
import org.osgi.service.metatype.annotations.Designate;
import org.osgi.service.metatype.annotations.ObjectClassDefinition;

@Component(
service = {ApmInstallService.class, Runnable.class},
immediate = true,
property = {
Property.DESCRIPTION + "APM Launches configured scripts",
Expand All @@ -58,8 +64,6 @@
@Designate(ocd = ApmInstallService.Configuration.class, factory = true)
public class ApmInstallService extends AbstractLauncher implements Runnable {

private static final String AEM_MUTABLE_CONTENT_INSTANCE = "aem-install-mutable-content";

@Reference
private ResourceResolverProvider resolverProvider;

Expand All @@ -75,53 +79,106 @@ public class ApmInstallService extends AbstractLauncher implements Runnable {
@Reference
private History history;

private Configuration config;
private List<String> scriptPaths;

private boolean ifModified;

private Set<ServiceRegistration<ResourceChangeListener>> registrations;

@Activate
public void activate(Configuration config) {
this.config = config;
process();
public void activate(Configuration config, BundleContext bundleContext) {
scriptPaths = Arrays.asList(config.scriptPaths());
ifModified = config.ifModified();
processAllScripts();
registerScripts(bundleContext);
}

@Deactivate
public void deactivate() {
registrations.forEach(ServiceRegistration::unregister);
registrations.clear();
}

@Override
public void run() {
process();
processAllScripts();
}

private void process() {
private void processAllScripts() {
SlingHelper.operateTraced(resolverProvider, resolver -> {
boolean compositeNodeStore = RuntimeUtils.determineCompositeNodeStore(resolver);
String instanceName = ManagementFactory.getRuntimeMXBean().getName();
if (!compositeNodeStore || StringUtils.contains(instanceName, AEM_MUTABLE_CONTENT_INSTANCE)) {
processScripts(config, resolver);
if (RuntimeUtils.isMutableContentInstance(resolver)) {
List<Script> scripts = determineScripts(scriptPaths, resolver);
processScripts(scripts, resolver);
}
});
}

private void processScripts(Configuration config, ResourceResolver resolver) throws PersistenceException {
private List<Script> determineScripts(List<String> scriptPaths, ResourceResolver resolver) {
ReferenceFinder referenceFinder = new ReferenceFinder(scriptFinder, resolver);
List<Script> scripts = Arrays.stream(config.scriptPaths())
return scriptPaths.stream()
.map(scriptPath -> scriptFinder.find(scriptPath, resolver))
.filter(Objects::nonNull)
.filter(script -> {
List<Script> subtree = referenceFinder.findReferences(script);
String checksum = versionService.countChecksum(subtree);
ScriptVersion scriptVersion = versionService.getScriptVersion(resolver, script);
HistoryEntry lastLocalRun = history.findScriptHistory(resolver, script).getLastLocalRun();
return !config.ifModified()
return !ifModified
|| !checksum.equals(scriptVersion.getLastChecksum())
|| lastLocalRun == null
|| !checksum.equals(lastLocalRun.getChecksum());
})
.collect(Collectors.toList());
processScripts(scripts, resolver);
}

private void registerScripts(BundleContext bundleContext) {
registrations = new HashSet<>();
SlingHelper.operateTraced(resolverProvider, resolver -> {
if (ifModified && RuntimeUtils.isMutableContentInstance(resolver)) {
scriptPaths.forEach(scriptPath -> registerScript(scriptPath, resolver, bundleContext));
}
});
}

private void registerScript(String scriptPath, ResourceResolver resolver, BundleContext bundleContext) {
Script script = scriptFinder.find(scriptPath, resolver);
ScriptResourceChangeListener service = new ScriptResourceChangeListener(script, scriptPath);
Dictionary<String, Object> dictionary = new Hashtable<>();
dictionary.put(ResourceChangeListener.CHANGES, new String[]{"ADDED", "CHANGED", "REMOVED"});
dictionary.put(ResourceChangeListener.PATHS, scriptPath);
ServiceRegistration<ResourceChangeListener> registration = bundleContext.registerService(ResourceChangeListener.class, service, dictionary);
registrations.add(registration);
}

@Override
protected ScriptManager getScriptManager() {
return scriptManager;
}

private class ScriptResourceChangeListener implements ResourceChangeListener {

private Script script;

private final String scriptPath;

public ScriptResourceChangeListener(Script script, String scriptPath) {
this.script = script;
this.scriptPath = scriptPath;
}

@Override
public void onChange(List<ResourceChange> changes) {
SlingHelper.operateTraced(resolverProvider, resolver -> {
Script newScript = scriptFinder.find(scriptPath, resolver);
if (!Objects.equals(script, newScript)) {
script = newScript;
List<Script> scripts = determineScripts(Collections.singletonList(scriptPath), resolver);
processScripts(scripts, resolver);
}
});
}
}

@ObjectClassDefinition(name = "AEM Permission Management - Install Launcher Configuration")
public @interface Configuration {

Expand Down
Loading