You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by cz...@apache.org on 2013/10/19 19:21:46 UTC

svn commit: r1533793 - /sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/tasks/HistoryCleanUpTask.java

Author: cziegeler
Date: Sat Oct 19 17:21:45 2013
New Revision: 1533793

URL: http://svn.apache.org/r1533793
Log:
SLiNG-3184 : Create a job consumer to clean up the history

Modified:
    sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/tasks/HistoryCleanUpTask.java

Modified: sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/tasks/HistoryCleanUpTask.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/tasks/HistoryCleanUpTask.java?rev=1533793&r1=1533792&r2=1533793&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/tasks/HistoryCleanUpTask.java (original)
+++ sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/tasks/HistoryCleanUpTask.java Sat Oct 19 17:21:45 2013
@@ -18,8 +18,11 @@
  */
 package org.apache.sling.event.impl.jobs.tasks;
 
+import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Calendar;
 import java.util.Iterator;
+import java.util.List;
 
 import org.apache.felix.scr.annotations.Component;
 import org.apache.felix.scr.annotations.Property;
@@ -30,8 +33,10 @@ import org.apache.sling.api.resource.Per
 import org.apache.sling.api.resource.Resource;
 import org.apache.sling.api.resource.ResourceResolver;
 import org.apache.sling.api.resource.ResourceResolverFactory;
+import org.apache.sling.api.resource.ResourceUtil;
+import org.apache.sling.api.resource.ValueMap;
+import org.apache.sling.event.impl.jobs.JobImpl;
 import org.apache.sling.event.impl.jobs.JobManagerImpl;
-import org.apache.sling.event.impl.support.BatchResourceRemover;
 import org.apache.sling.event.jobs.Job;
 import org.apache.sling.event.jobs.JobManager;
 import org.apache.sling.event.jobs.consumer.JobExecutionContext;
@@ -41,7 +46,14 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 /**
- * Task to clean up the history
+ * Task to clean up the history,
+ * A clean up task can be configured with three properties:
+ * - age : only jobs older than this amount of minutes are removed (default is two days)
+ * - topic : only jobs with this topic are removed (default is no topic, meaning all jobs are removed)
+ *           The value should either be a string or an array of string
+ * - state : only jobs in this state are removed (default is no state, meaning all jobs are removed)
+ *           The value should either be a string or an array of string. Allowed values are:
+ *           SUCCEEDED, STOPPED, GIVEN_UP, ERROR, DROPPED
  */
 @Component
 @Service(value = JobExecutor.class)
@@ -50,6 +62,10 @@ public class HistoryCleanUpTask implemen
 
     private static final String PROPERTY_AGE = "age";
 
+    private static final String PROPERTY_TOPIC = "topic";
+
+    private static final String PROPERTY_STATE = "state";
+
     private static final int DEFAULT_AGE = 60 * 24 * 2; // older than two days
 
     private final Logger logger = LoggerFactory.getLogger(this.getClass());
@@ -66,17 +82,38 @@ public class HistoryCleanUpTask implemen
         if ( age < 1 ) {
             age = DEFAULT_AGE;
         }
-        final Calendar now = Calendar.getInstance();
-        now.add(Calendar.MINUTE, -age);
+        final Calendar removeDate = Calendar.getInstance();
+        removeDate.add(Calendar.MINUTE, -age);
 
-        context.log("Cleaning up job history. Removing all jobs older than {0}", now);
+        final String[] topics = job.getProperty(PROPERTY_TOPIC, String[].class);
+        final String[] states = job.getProperty(PROPERTY_STATE, String[].class);
+        final String logTopics = (topics == null ? "ALL" : Arrays.toString(topics));
+        final String logStates = (states == null ? "ALL" : Arrays.toString(states));
+        context.log("Cleaning up job history. Removing all jobs older than {0}, with topics {1} and states {2}",
+                removeDate, logTopics, logStates);
+
+        final List<String> stateList;
+        if ( states != null ) {
+            stateList = new ArrayList<String>();
+            for(final String s : states) {
+                stateList.add(s);
+            }
+        } else {
+            stateList = null;
+        }
         ResourceResolver resolver = null;
         try {
             resolver = this.resourceResolverFactory.getAdministrativeResourceResolver(null);
 
-            this.cleanup(now, resolver, context, ((JobManagerImpl)jobManager).getConfiguration().getStoredCancelledJobsPath());
-            this.cleanup(now, resolver, context, ((JobManagerImpl)jobManager).getConfiguration().getStoredSuccessfulJobsPath());
-
+            if ( stateList == null || stateList.contains(Job.JobState.SUCCEEDED.name()) ) {
+                this.cleanup(removeDate, resolver, context, ((JobManagerImpl)jobManager).getConfiguration().getStoredSuccessfulJobsPath(), topics, null);
+            }
+            if ( stateList == null || stateList.contains(Job.JobState.DROPPED.name())
+                 || stateList.contains(Job.JobState.ERROR.name())
+                 || stateList.contains(Job.JobState.GIVEN_UP.name())
+                 || stateList.contains(Job.JobState.STOPPED.name())) {
+                this.cleanup(removeDate, resolver, context, ((JobManagerImpl)jobManager).getConfiguration().getStoredCancelledJobsPath(), topics, stateList);
+            }
 
         } catch (final PersistenceException pe) {
             // in the case of an error, we just log this as a warning
@@ -91,8 +128,12 @@ public class HistoryCleanUpTask implemen
         return context.result().succeeded();
     }
 
-    private void cleanup(final Calendar now,
-            final ResourceResolver resolver, final JobExecutionContext context, final String basePath)
+    private void cleanup(final Calendar removeDate,
+            final ResourceResolver resolver,
+            final JobExecutionContext context,
+            final String basePath,
+            final String[] topics,
+            final List<String> stateList)
     throws PersistenceException {
         final Resource baseResource = resolver.getResource(basePath);
         // sanity check - should never be null
@@ -101,33 +142,46 @@ public class HistoryCleanUpTask implemen
             while ( !context.isStopped() && topicIter.hasNext() ) {
                 final Resource topicResource = topicIter.next();
 
+                // check topic
+                boolean found = topics == null;
+                int index = 0;
+                while ( !found && index < topics.length ) {
+                    if ( topicResource.getName().equals(topics[index]) ) {
+                        found = true;
+                    }
+                    index++;
+                }
+                if ( !found ) {
+                    continue;
+                }
+
                 // now years
                 final Iterator<Resource> yearIter = topicResource.listChildren();
                 while ( !context.isStopped() && yearIter.hasNext() ) {
                     final Resource yearResource = yearIter.next();
                     final int year = Integer.valueOf(yearResource.getName());
-                    final boolean oldYear = year < now.get(Calendar.YEAR);
+                    final boolean oldYear = year < removeDate.get(Calendar.YEAR);
 
                     // months
                     final Iterator<Resource> monthIter = yearResource.listChildren();
                     while ( !context.isStopped() && monthIter.hasNext() ) {
                         final Resource monthResource = monthIter.next();
                         final int month = Integer.valueOf(monthResource.getName());
-                        final boolean oldMonth = oldYear || month < (now.get(Calendar.MONTH) + 1);
+                        final boolean oldMonth = oldYear || month < (removeDate.get(Calendar.MONTH) + 1);
 
                         // days
                         final Iterator<Resource> dayIter = monthResource.listChildren();
                         while ( !context.isStopped() && dayIter.hasNext() ) {
                             final Resource dayResource = dayIter.next();
                             final int day = Integer.valueOf(dayResource.getName());
-                            final boolean oldDay = oldMonth || day < now.get(Calendar.DAY_OF_MONTH);
+                            final boolean oldDay = oldMonth || day < removeDate.get(Calendar.DAY_OF_MONTH);
 
                             // hours
                             final Iterator<Resource> hourIter = dayResource.listChildren();
                             while ( !context.isStopped() && hourIter.hasNext() ) {
                                 final Resource hourResource = hourIter.next();
                                 final int hour = Integer.valueOf(hourResource.getName());
-                                final boolean oldHour = oldDay || hour < now.get(Calendar.HOUR_OF_DAY);
+                                final boolean oldHour = oldDay || hour < removeDate.get(Calendar.HOUR_OF_DAY);
 
                                 // minutes
                                 final Iterator<Resource> minuteIter = hourResource.listChildren();
@@ -136,10 +190,28 @@ public class HistoryCleanUpTask implemen
 
                                     // check if we can delete the minute
                                     final int minute = Integer.valueOf(minuteResource.getName());
-                                    final boolean oldMinute = oldHour || minute <= now.get(Calendar.MINUTE);
+                                    final boolean oldMinute = oldHour || minute <= removeDate.get(Calendar.MINUTE);
                                     if ( oldMinute ) {
-                                        BatchResourceRemover remover = new BatchResourceRemover();
-                                        remover.delete(minuteResource);
+                                        final Iterator<Resource> jobIter = minuteResource.listChildren();
+                                        while ( !context.isStopped() && jobIter.hasNext() ) {
+                                            final Resource jobResource = jobIter.next();
+                                            boolean remove = stateList == null;
+                                            if ( !remove ) {
+                                                final ValueMap vm = ResourceUtil.getValueMap(jobResource);
+                                                final String state = vm.get(JobImpl.PROPERTY_FINISHED_STATE, String.class);
+                                                if ( state != null && stateList.contains(state) ) {
+                                                    remove = true;
+                                                }
+                                            }
+                                            if ( remove ) {
+                                                resolver.delete(jobResource);
+                                                resolver.commit();
+                                            }
+                                        }
+                                    }
+                                    // check if we can delete the minute
+                                    if ( !context.isStopped() && oldMinute && !minuteResource.listChildren().hasNext()) {
+                                        resolver.delete(minuteResource);
                                         resolver.commit();
                                     }
                                 }