Skip to content

Commit

Permalink
fixed handling of ifModified property
Browse files Browse the repository at this point in the history
  • Loading branch information
dprzybyl committed Oct 19, 2023
1 parent 3755702 commit af1da33
Show file tree
Hide file tree
Showing 2 changed files with 120 additions and 30 deletions.
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 @@ -34,21 +34,30 @@
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 @@ -75,53 +84,107 @@ 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();
process(scriptPaths);
if (ifModified) {
registerScripts(bundleContext);
}
}

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

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

private void process() {
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);
}
});
private void process(List<String> scriptPaths) {
SlingHelper.operateTraced(resolverProvider, resolver -> process(scriptPaths, resolver));
}

private void processScripts(Configuration config, ResourceResolver resolver) throws PersistenceException {
private void process(List<String> scriptPaths, ResourceResolver resolver) throws PersistenceException {
boolean compositeNodeStore = RuntimeUtils.determineCompositeNodeStore(resolver);
String instanceName = ManagementFactory.getRuntimeMXBean().getName();
if (!compositeNodeStore || StringUtils.contains(instanceName, AEM_MUTABLE_CONTENT_INSTANCE)) {
List<Script> scripts = scriptPaths.stream()
.map(scriptPath -> scriptFinder
.find(scriptPath, resolver))
.filter(script -> isValid(script, resolver))
.collect(Collectors.toList());
processScripts(scripts, resolver);
}
}

private boolean isValid(Script script, ResourceResolver resolver) {
if (script == null) {
return false;
}
ReferenceFinder referenceFinder = new ReferenceFinder(scriptFinder, resolver);
List<Script> scripts = Arrays.stream(config.scriptPaths())
.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()
|| !checksum.equals(scriptVersion.getLastChecksum())
|| lastLocalRun == null
|| !checksum.equals(lastLocalRun.getChecksum());
})
.collect(Collectors.toList());
processScripts(scripts, resolver);
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 !ifModified || !checksum.equals(scriptVersion.getLastChecksum()) || lastLocalRun == null || !checksum.equals(lastLocalRun.getChecksum());
}

private void registerScripts(BundleContext bundleContext) {
registrations = new HashSet<>();
SlingHelper.operateTraced(resolverProvider, 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;
process(Collections.singletonList(scriptPath), resolver);
}
});
}
}

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

Expand Down

0 comments on commit af1da33

Please sign in to comment.