This is an automated email from the ASF dual-hosted git repository. rombert pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-event.git
commit 1534e851abe6e44d306b2546aaaad7dfb54889a1 Author: Carsten Ziegeler <cziege...@apache.org> AuthorDate: Fri May 5 09:22:56 2017 +0000 SLING-6782 : Sling Job implementation should avoid unnecessary writes to the repository. Apply patch from Jörg Hoh. Modified the patch to be able to remove duplicate code from ResourceUtil git-svn-id: https://svn.apache.org/repos/asf/sling/trunk@1793991 13f79535-47bb-0310-9956-ffa450edef68 --- .../sling/event/impl/EnvironmentComponent.java | 5 +- .../sling/event/impl/EventingThreadPool.java | 3 +- .../apache/sling/event/impl/jobs/JobHandler.java | 4 +- .../sling/event/impl/jobs/JobManagerImpl.java | 9 +- .../impl/jobs/config/JobManagerConfiguration.java | 7 +- .../impl/jobs/notifications/NewJobSender.java | 3 +- .../sling/event/impl/jobs/queues/QueueManager.java | 5 +- .../impl/jobs/scheduling/ScheduledJobHandler.java | 2 +- .../event/impl/jobs/tasks/CheckTopologyTask.java | 6 +- .../sling/event/impl/jobs/tasks/UpgradeTask.java | 4 +- .../sling/event/impl/support/ResourceHelper.java | 187 +++++---------------- 11 files changed, 65 insertions(+), 170 deletions(-) diff --git a/src/main/java/org/apache/sling/event/impl/EnvironmentComponent.java b/src/main/java/org/apache/sling/event/impl/EnvironmentComponent.java index 7c3caad..56b5bd3 100644 --- a/src/main/java/org/apache/sling/event/impl/EnvironmentComponent.java +++ b/src/main/java/org/apache/sling/event/impl/EnvironmentComponent.java @@ -26,6 +26,7 @@ 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.component.annotations.ReferencePolicyOption; /** * Environment component. This component provides "global settings" @@ -45,11 +46,11 @@ public class EnvironmentComponent { /** * Our thread pool. */ - @Reference(service=EventingThreadPool.class) + @Reference(service=EventingThreadPool.class, policyOption=ReferencePolicyOption.GREEDY) private ThreadPool threadPool; /** Sling settings service. */ - @Reference + @Reference(policyOption=ReferencePolicyOption.GREEDY) private SlingSettingsService settingsService; /** diff --git a/src/main/java/org/apache/sling/event/impl/EventingThreadPool.java b/src/main/java/org/apache/sling/event/impl/EventingThreadPool.java index 652f09f..0cf1531 100644 --- a/src/main/java/org/apache/sling/event/impl/EventingThreadPool.java +++ b/src/main/java/org/apache/sling/event/impl/EventingThreadPool.java @@ -29,6 +29,7 @@ import org.osgi.service.component.annotations.Component; import org.osgi.service.component.annotations.Deactivate; import org.osgi.service.component.annotations.Modified; import org.osgi.service.component.annotations.Reference; +import org.osgi.service.component.annotations.ReferencePolicyOption; import org.osgi.service.metatype.annotations.AttributeDefinition; import org.osgi.service.metatype.annotations.Designate; import org.osgi.service.metatype.annotations.ObjectClassDefinition; @@ -57,7 +58,7 @@ public class EventingThreadPool implements ThreadPool { int minPoolSize() default 35; } - @Reference + @Reference(policyOption=ReferencePolicyOption.GREEDY) private ThreadPoolManager threadPoolManager; /** The real thread pool used. */ diff --git a/src/main/java/org/apache/sling/event/impl/jobs/JobHandler.java b/src/main/java/org/apache/sling/event/impl/jobs/JobHandler.java index 6337b6c..a3203fc 100644 --- a/src/main/java/org/apache/sling/event/impl/jobs/JobHandler.java +++ b/src/main/java/org/apache/sling/event/impl/jobs/JobHandler.java @@ -124,7 +124,7 @@ public class JobHandler { if ( keepJobInHistory ) { final ValueMap vm = ResourceHelper.getValueMap(jobResource); newPath = this.configuration.getStoragePath(job.getTopic(), job.getId(), isSuccess); - final Map<String, Object> props = new HashMap<String, Object>(vm); + final Map<String, Object> props = new HashMap<>(vm); props.put(JobImpl.PROPERTY_FINISHED_STATE, state.name()); if ( isSuccess ) { // we set the finish date to start date + duration @@ -181,7 +181,7 @@ public class JobHandler { final ValueMap vm = ResourceHelper.getValueMap(jobResource); final String newPath = this.configuration.getUniquePath(targetId, job.getTopic(), job.getId(), job.getProperties()); - final Map<String, Object> props = new HashMap<String, Object>(vm); + final Map<String, Object> props = new HashMap<>(vm); props.remove(Job.PROPERTY_JOB_QUEUE_NAME); if ( targetId == null ) { props.remove(Job.PROPERTY_JOB_TARGET_INSTANCE); diff --git a/src/main/java/org/apache/sling/event/impl/jobs/JobManagerImpl.java b/src/main/java/org/apache/sling/event/impl/jobs/JobManagerImpl.java index b5c6372..279d5ca 100644 --- a/src/main/java/org/apache/sling/event/impl/jobs/JobManagerImpl.java +++ b/src/main/java/org/apache/sling/event/impl/jobs/JobManagerImpl.java @@ -66,6 +66,7 @@ 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.component.annotations.ReferencePolicyOption; import org.osgi.service.event.Event; import org.osgi.service.event.EventAdmin; import org.osgi.service.event.EventConstants; @@ -92,10 +93,10 @@ public class JobManagerImpl /** Default logger. */ private final Logger logger = LoggerFactory.getLogger(this.getClass()); - @Reference + @Reference(policyOption=ReferencePolicyOption.GREEDY) private EventAdmin eventAdmin; - @Reference + @Reference(policyOption=ReferencePolicyOption.GREEDY) private Scheduler scheduler; @Reference @@ -104,7 +105,7 @@ public class JobManagerImpl @Reference private QueuesMBean queuesMBean; - @Reference + @Reference(policyOption=ReferencePolicyOption.GREEDY) private ThreadPoolManager threadPoolManager; /** The job manager configuration. */ @@ -637,7 +638,7 @@ public class JobManagerImpl if ( logger.isDebugEnabled() ) { logger.debug("Storing new job {} at {}", Utility.toString(jobTopic, properties), path); } - ResourceHelper.getOrCreateResource(resolver, + ResourceHelper.createAndCommitResource(resolver, path, properties); diff --git a/src/main/java/org/apache/sling/event/impl/jobs/config/JobManagerConfiguration.java b/src/main/java/org/apache/sling/event/impl/jobs/config/JobManagerConfiguration.java index b9262fb..418b064 100644 --- a/src/main/java/org/apache/sling/event/impl/jobs/config/JobManagerConfiguration.java +++ b/src/main/java/org/apache/sling/event/impl/jobs/config/JobManagerConfiguration.java @@ -52,6 +52,7 @@ import org.osgi.service.component.annotations.Component; import org.osgi.service.component.annotations.Deactivate; import org.osgi.service.component.annotations.Modified; import org.osgi.service.component.annotations.Reference; +import org.osgi.service.component.annotations.ReferencePolicyOption; import org.osgi.service.metatype.annotations.AttributeDefinition; import org.osgi.service.metatype.annotations.Designate; import org.osgi.service.metatype.annotations.ObjectClassDefinition; @@ -156,16 +157,16 @@ public class JobManagerConfiguration { @Reference private EnvironmentComponent environment; - @Reference + @Reference(policyOption=ReferencePolicyOption.GREEDY) private ResourceResolverFactory resourceResolverFactory; @Reference private QueueConfigurationManager queueConfigManager; - @Reference + @Reference(policyOption=ReferencePolicyOption.GREEDY) private Scheduler scheduler; - @Reference + @Reference(policyOption=ReferencePolicyOption.GREEDY) private ServiceUserMapped serviceUserMapped; /** Is this still active? */ diff --git a/src/main/java/org/apache/sling/event/impl/jobs/notifications/NewJobSender.java b/src/main/java/org/apache/sling/event/impl/jobs/notifications/NewJobSender.java index 03c5769..dc16be2 100644 --- a/src/main/java/org/apache/sling/event/impl/jobs/notifications/NewJobSender.java +++ b/src/main/java/org/apache/sling/event/impl/jobs/notifications/NewJobSender.java @@ -36,6 +36,7 @@ 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.component.annotations.ReferencePolicyOption; import org.osgi.service.event.Event; import org.osgi.service.event.EventAdmin; import org.slf4j.Logger; @@ -56,7 +57,7 @@ public class NewJobSender implements ResourceChangeListener, ExternalResourceCha private JobManagerConfiguration configuration; /** The event admin. */ - @Reference + @Reference(policyOption=ReferencePolicyOption.GREEDY) private EventAdmin eventAdmin; /** Service registration for the event handler. */ diff --git a/src/main/java/org/apache/sling/event/impl/jobs/queues/QueueManager.java b/src/main/java/org/apache/sling/event/impl/jobs/queues/QueueManager.java index 2a98f8a..11f24a9 100644 --- a/src/main/java/org/apache/sling/event/impl/jobs/queues/QueueManager.java +++ b/src/main/java/org/apache/sling/event/impl/jobs/queues/QueueManager.java @@ -56,6 +56,7 @@ 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.component.annotations.ReferencePolicyOption; import org.osgi.service.event.Event; import org.osgi.service.event.EventAdmin; import org.osgi.service.event.EventConstants; @@ -81,7 +82,7 @@ public class QueueManager /** Default logger. */ private final Logger logger = LoggerFactory.getLogger(this.getClass()); - @Reference + @Reference(policyOption=ReferencePolicyOption.GREEDY) private EventAdmin eventAdmin; @Reference @@ -90,7 +91,7 @@ public class QueueManager @Reference private QueuesMBean queuesMBean; - @Reference + @Reference(policyOption=ReferencePolicyOption.GREEDY) private ThreadPoolManager threadPoolManager; /** diff --git a/src/main/java/org/apache/sling/event/impl/jobs/scheduling/ScheduledJobHandler.java b/src/main/java/org/apache/sling/event/impl/jobs/scheduling/ScheduledJobHandler.java index deb3955..01ca010 100644 --- a/src/main/java/org/apache/sling/event/impl/jobs/scheduling/ScheduledJobHandler.java +++ b/src/main/java/org/apache/sling/event/impl/jobs/scheduling/ScheduledJobHandler.java @@ -277,7 +277,7 @@ public class ScheduledJobHandler implements Runnable { } else { logger.debug("Storing new scheduled job {} at {}", properties, path); } - ResourceHelper.getOrCreateResource(resolver, + ResourceHelper.createAndCommitResource(resolver, path, properties); // put back real schedule infos diff --git a/src/main/java/org/apache/sling/event/impl/jobs/tasks/CheckTopologyTask.java b/src/main/java/org/apache/sling/event/impl/jobs/tasks/CheckTopologyTask.java index 879ee2a..c5750be 100644 --- a/src/main/java/org/apache/sling/event/impl/jobs/tasks/CheckTopologyTask.java +++ b/src/main/java/org/apache/sling/event/impl/jobs/tasks/CheckTopologyTask.java @@ -140,7 +140,7 @@ public class CheckTopologyTask { final ValueMap vm = ResourceHelper.getValueMap(rsrc); final String targetId = caps.detectTarget(topicName, vm, info); - final Map<String, Object> props = new HashMap<String, Object>(vm); + final Map<String, Object> props = new HashMap<>(vm); props.remove(Job.PROPERTY_JOB_STARTED_TIME); final String newPath; @@ -251,7 +251,7 @@ public class CheckTopologyTask { if ( targetId != null ) { final String newPath = configuration.getAssginedJobsPath() + '/' + targetId + '/' + topicResource.getName() + rsrc.getPath().substring(topicResource.getPath().length()); - final Map<String, Object> props = new HashMap<String, Object>(vm); + final Map<String, Object> props = new HashMap<>(vm); props.put(Job.PROPERTY_JOB_QUEUE_NAME, info.queueName); props.put(Job.PROPERTY_JOB_TARGET_INSTANCE, targetId); props.remove(Job.PROPERTY_JOB_STARTED_TIME); @@ -287,7 +287,7 @@ public class CheckTopologyTask { try { final ValueMap vm = ResourceHelper.getValueMap(rsrc); final String newPath = configuration.getUnassignedJobsPath() + '/' + topicResource.getName() + rsrc.getPath().substring(topicResource.getPath().length()); - final Map<String, Object> props = new HashMap<String, Object>(vm); + final Map<String, Object> props = new HashMap<>(vm); props.remove(Job.PROPERTY_JOB_QUEUE_NAME); props.remove(Job.PROPERTY_JOB_TARGET_INSTANCE); props.remove(Job.PROPERTY_JOB_STARTED_TIME); diff --git a/src/main/java/org/apache/sling/event/impl/jobs/tasks/UpgradeTask.java b/src/main/java/org/apache/sling/event/impl/jobs/tasks/UpgradeTask.java index 99c7b0e..842addf 100644 --- a/src/main/java/org/apache/sling/event/impl/jobs/tasks/UpgradeTask.java +++ b/src/main/java/org/apache/sling/event/impl/jobs/tasks/UpgradeTask.java @@ -120,7 +120,7 @@ public class UpgradeTask { final ValueMap vm = ResourceHelper.getValueMap(rsrc); final String targetId = caps.detectTarget(topicName, vm, info); - final Map<String, Object> props = new HashMap<String, Object>(vm); + final Map<String, Object> props = new HashMap<>(vm); final String newPath; if ( targetId != null ) { newPath = configuration.getAssginedJobsPath() + '/' + targetId + '/' + topicResource.getName() + rsrc.getPath().substring(topicResource.getPath().length()); @@ -198,7 +198,7 @@ public class UpgradeTask { try { final ValueMap vm = ResourceHelper.getValueMap(jobResource); // check for binary properties - Map<String, Object> binaryProperties = new HashMap<String, Object>(); + Map<String, Object> binaryProperties = new HashMap<>(); final ObjectInputStream ois = vm.get("slingevent:properties", ObjectInputStream.class); if ( ois != null ) { try { diff --git a/src/main/java/org/apache/sling/event/impl/support/ResourceHelper.java b/src/main/java/org/apache/sling/event/impl/support/ResourceHelper.java index 4383480..83c583b 100644 --- a/src/main/java/org/apache/sling/event/impl/support/ResourceHelper.java +++ b/src/main/java/org/apache/sling/event/impl/support/ResourceHelper.java @@ -25,7 +25,6 @@ import java.io.Serializable; import java.util.ArrayList; import java.util.Arrays; import java.util.BitSet; -import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -173,17 +172,17 @@ public abstract class ResourceHelper { public static Map<String, Object> cloneValueMap(final ValueMap vm) throws InstantiationException { List<Exception> hasReadError = null; try { - final Map<String, Object> result = new HashMap<String, Object>(vm); + final Map<String, Object> result = new HashMap<>(vm); for(final Map.Entry<String, Object> entry : result.entrySet()) { if ( entry.getKey().equals(PROPERTY_SCHEDULE_INFO) ) { final String[] infoArray = vm.get(entry.getKey(), String[].class); if ( infoArray == null || infoArray.length == 0 ) { if ( hasReadError == null ) { - hasReadError = new ArrayList<Exception>(); + hasReadError = new ArrayList<>(); } hasReadError.add(new Exception("Unable to deserialize property '" + entry.getKey() + "' : " + entry.getValue())); } else { - final List<ScheduleInfo> infos = new ArrayList<ScheduleInfo>(); + final List<ScheduleInfo> infos = new ArrayList<>(); for(final String i : infoArray) { final ScheduleInfoImpl info = ScheduleInfoImpl.deserialize(i); if ( info != null ) { @@ -192,7 +191,7 @@ public abstract class ResourceHelper { } if ( infos.size() < infoArray.length ) { if ( hasReadError == null ) { - hasReadError = new ArrayList<Exception>(); + hasReadError = new ArrayList<>(); } hasReadError.add(new Exception("Unable to deserialize property '" + entry.getKey() + "' : " + Arrays.toString(infoArray))); } else { @@ -206,7 +205,7 @@ public abstract class ResourceHelper { entry.setValue(value); } else { if ( hasReadError == null ) { - hasReadError = new ArrayList<Exception>(); + hasReadError = new ArrayList<>(); } // let's find out which class might be missing ObjectInputStream ois = null; @@ -256,171 +255,61 @@ public abstract class ResourceHelper { public static void getOrCreateBasePath(final ResourceResolver resolver, final String path) throws PersistenceException { - getOrCreateResource(resolver, + ResourceUtil.getOrCreateResource(resolver, path, ResourceHelper.RESOURCE_TYPE_FOLDER, ResourceHelper.RESOURCE_TYPE_FOLDER, true); } - public static Resource getOrCreateResource(final ResourceResolver resolver, - final String path, final Map<String, Object> props) + /** + * Create the resource and commit it + * @param resolver The resource resolver + * @param path The path of the resource + * @param props The properties + * @return The created resource + * @throws PersistenceException If something goes wrong + */ + public static Resource createAndCommitResource(final ResourceResolver resolver, + final String path, + final Map<String, Object> props) throws PersistenceException { - return getOrCreateResource(resolver, + return ResourceUtil.getOrCreateResource(resolver, path, props, ResourceHelper.RESOURCE_TYPE_FOLDER, true); } - /** - * Creates or gets the resource at the given path. - * This is a copy of Sling's API ResourceUtil method to avoid a dependency on the latest - * Sling API version! We can remove this once we update to Sling API > 2.8 - * @param resolver The resource resolver to use for creation - * @param path The full path to be created - * @param resourceType The optional resource type of the final resource to create - * @param intermediateResourceType THe optional resource type of all intermediate resources - * @param autoCommit If set to true, a commit is performed after each resource creation. - */ - private static Resource getOrCreateResource( - final ResourceResolver resolver, - final String path, - final String resourceType, - final String intermediateResourceType, - final boolean autoCommit) - throws PersistenceException { - final Map<String, Object> props; - if ( resourceType == null ) { - props = null; - } else { - props = Collections.singletonMap(ResourceResolver.PROPERTY_RESOURCE_TYPE, (Object)resourceType); - } - return getOrCreateResource(resolver, path, props, intermediateResourceType, autoCommit); - } /** * Creates or gets the resource at the given path. - * If an exception occurs, it retries the operation up to five times if autoCommit is enabled. - * In this case, {@link ResourceResolver#revert()} is called on the resolver before the - * creation is retried. - * This is a copy of Sling's API ResourceUtil method to avoid a dependency on the latest - * Sling API version! We can remove this once we update to Sling API > 2.8 + * If any resource along the parent path needs to be created, + * this is committed immediately. The resource itself is not committed. + * This is the task of the caller. * * @param resolver The resource resolver to use for creation * @param path The full path to be created - * @param resourceProperties The optional resource properties of the final resource to create - * @param intermediateResourceType THe optional resource type of all intermediate resources - * @param autoCommit If set to true, a commit is performed after each resource creation. + * @param props The properties of the new resource. + * @return The resource for the path. + * @throws PersistenceException If something goes wrong */ - private static Resource getOrCreateResource( - final ResourceResolver resolver, + public static Resource getOrCreateResource(final ResourceResolver resolver, final String path, - final Map<String, Object> resourceProperties, - final String intermediateResourceType, - final boolean autoCommit) + final Map<String, Object> props) throws PersistenceException { - PersistenceException mostRecentPE = null; - for(int i=0;i<5;i++) { - try { - return getOrCreateResourceInternal(resolver, + // create parent path with auto commit set to true + final String parentPath = ResourceUtil.getParent(path); + ResourceUtil.getOrCreateResource(resolver, + parentPath, + ResourceHelper.RESOURCE_TYPE_FOLDER, + ResourceHelper.RESOURCE_TYPE_FOLDER, + true); + // now create resource itself + return ResourceUtil.getOrCreateResource(resolver, path, - resourceProperties, - intermediateResourceType, - autoCommit); - } catch ( final PersistenceException pe ) { - if ( autoCommit ) { - // in case of exception, revert to last clean state and retry - resolver.revert(); - resolver.refresh(); - mostRecentPE = pe; - } else { - throw pe; - } - } - } - throw mostRecentPE; - } - - /** - * Creates or gets the resource at the given path. - * This is a copy of Sling's API ResourceUtil method to avoid a dependency on the latest - * Sling API version! We can remove this once we update to Sling API > 2.8 - * - * @param resolver The resource resolver to use for creation - * @param path The full path to be created - * @param resourceProperties The optional resource properties of the final resource to create - * @param intermediateResourceType THe optional resource type of all intermediate resources - * @param autoCommit If set to true, a commit is performed after each resource creation. - */ - private static Resource getOrCreateResourceInternal( - final ResourceResolver resolver, - final String path, - final Map<String, Object> resourceProperties, - final String intermediateResourceType, - final boolean autoCommit) - throws PersistenceException { - Resource rsrc = resolver.getResource(path); - if ( rsrc == null ) { - final int lastPos = path.lastIndexOf('/'); - final String name = path.substring(lastPos + 1); - - final Resource parentResource; - if ( lastPos == 0 ) { - parentResource = resolver.getResource("/"); - } else { - final String parentPath = path.substring(0, lastPos); - parentResource = getOrCreateResource(resolver, - parentPath, - intermediateResourceType, - intermediateResourceType, - autoCommit); - } - if ( autoCommit ) { - resolver.refresh(); - } - try { - int retry = 5; - while ( retry > 0 && rsrc == null ) { - rsrc = resolver.create(parentResource, name, resourceProperties); - // check for SNS - if ( !name.equals(rsrc.getName()) ) { - resolver.refresh(); - resolver.delete(rsrc); - rsrc = resolver.getResource(parentResource, name); - } - retry--; - } - if ( rsrc == null ) { - throw new PersistenceException("Unable to create resource."); - } - } catch ( final PersistenceException pe ) { - // this could be thrown because someone else tried to create this - // node concurrently - resolver.refresh(); - rsrc = resolver.getResource(parentResource, name); - if ( rsrc == null ) { - throw pe; - } - } - if ( autoCommit ) { - try { - resolver.commit(); - resolver.refresh(); - rsrc = resolver.getResource(parentResource, name); - } catch ( final PersistenceException pe ) { - // try again - maybe someone else did create the resource in the meantime - // or we ran into Jackrabbit's stale item exception in a clustered environment - resolver.revert(); - resolver.refresh(); - rsrc = resolver.getResource(parentResource, name); - if ( rsrc == null ) { - rsrc = resolver.create(parentResource, name, resourceProperties); - resolver.commit(); - } - } - } - } - return rsrc; + props, + ResourceHelper.RESOURCE_TYPE_FOLDER, + false); } } \ No newline at end of file -- To stop receiving notification emails like this one, please contact "commits@sling.apache.org" <commits@sling.apache.org>.