/**
* $Id: $
* $URL: $
*
**************************************************************************
* Copyright (c) 2013 The Apereo Foundation
*
* Licensed under the Educational Community License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.opensource.org/licenses/ECL-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sakaiproject.content;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.sakaiproject.component.api.ServerConfigurationService;
import org.sakaiproject.content.api.ContentHostingService;
import org.sakaiproject.content.api.ContentResource;
import org.sakaiproject.entity.api.ResourceProperties;
import org.sakaiproject.exception.IdUnusedException;
import org.sakaiproject.exception.InUseException;
import org.sakaiproject.exception.PermissionException;
import org.sakaiproject.exception.TypeException;
import org.sakaiproject.time.api.Time;
import org.sakaiproject.time.api.TimeService;
import org.sakaiproject.tool.api.Session;
import org.sakaiproject.tool.api.SessionManager;
/**
* Job to remove old delete content from content hosting. This is in a separate
* project as the kernel (content hosting) can't bind to stuff outside it.
*
* @author buckett
*
*/
public class CleanupDeletedContent implements Job {
private static final Log log = LogFactory
.getLog(CleanupDeletedContent.class);
private ContentHostingService chs;
private ServerConfigurationService scs;
private TimeService ts;
private SessionManager sm;
public void setContentHostingService(ContentHostingService chs) {
this.chs = chs;
}
public void setServerConfigurationService(ServerConfigurationService scs) {
this.scs = scs;
}
public void setTimeService(TimeService ts) {
this.ts = ts;
}
public void setSessionManager(SessionManager sm) {
this.sm = sm;
}
public void execute(JobExecutionContext context)
throws JobExecutionException {
Session sakaiSession = sm.getCurrentSession();
sakaiSession.setUserId("admin");
sakaiSession.setUserEid("admin");
List<ContentResource> deleted = (List<ContentResource>) chs
.getAllDeletedResources("/");
long daysToKeep = scs.getInt("content.keep.deleted.files.days", 30);
Time oldest = ts.newTime(System.currentTimeMillis()
- (daysToKeep * 1000 * 60 * 60 * 24));
log.info("Looking at " + deleted.size()
+ " resources, and removing anything older than: " + oldest.toStringLocalDate());
int removed = 0, attempted = 0;
long totalSize = 0, removedSize = 0;
for (ContentResource resource : deleted) {
// We can't get at the deleted field in the DB but the modification
// time is updated when it's deleted.
Object property = resource.getProperties().get(ResourceProperties.PROP_MODIFIED_DATE);
long size = resource.getContentLength();
totalSize += size;
if (property != null && property instanceof String) {
Time time = ts.newTimeGmt((String)property);
if (oldest.after(time)) {
try {
attempted++;
chs.removeDeletedResource(resource.getId());
removed++;
removedSize += size;
} catch (PermissionException e) {
log.warn("Failed to remove due to lack of permission: "
+ resource.getId());
} catch (IdUnusedException e) {
log
.warn("Failed to remove due to not beging able to find: "
+ resource.getId());
} catch (TypeException e) {
log.warn("Failed to remove due to type exception: "
+ resource.getId());
} catch (InUseException e) {
log.warn("Failed to remove due resource being in use: "
+ resource.getId());
}
}
else {
if (log.isDebugEnabled()) {
log.debug("Resource " + resource.getId() + " is still too new, skipping.");
}
}
}
else {
log.warn("No modified date set for file with id " + resource.getId() + ". Cannot process for deletion.");
}
}
int failed = attempted - removed;
log.info("Out of " + deleted.size() + "(~"+ formatSize(totalSize)+ ") "
+ "deleted resources, successfully removed " + removed + "(~"+ formatSize(removedSize)+ ")"
+ ((failed > 0) ? ", failed on " + failed + " resources": ""));
}
static String formatSize(long size) {
if (size >= 1L<<30) {
return ""+ (size / 1L>>30)+ "Gb";
} else if (size >= 1L<<20) {
return ""+ (size / 1L>>20)+ "Mb";
} else if (size >= 1L<<10) {
return ""+ (size / 1L>>10)+ "kb";
} else {
return ""+ size+ "b";
}
}
}