/*
* (C) Copyright 2013 Nuxeo SA (http://nuxeo.com/) and others.
*
* Licensed under the Apache 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.apache.org/licenses/LICENSE-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.
*
* Contributors:
* Florent Guillaume
*/
package org.nuxeo.ecm.core.storage.sql;
import java.util.Calendar;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.nuxeo.ecm.core.event.Event;
import org.nuxeo.ecm.core.event.EventListener;
import org.nuxeo.ecm.core.repository.RepositoryService;
import org.nuxeo.ecm.core.storage.sql.coremodel.SQLRepositoryService;
import org.nuxeo.runtime.api.Framework;
/**
* Sync listener that calls the soft delete cleanup method of the repositories. Designed to be called periodically.
*
* @since 5.7
*/
public class SoftDeleteCleanupListener implements EventListener {
private static final Log log = LogFactory.getLog(SoftDeleteCleanupListener.class);
public static final int DEFAULT_MAX = 1000;
/**
* Property for the maximum number of documents to delete in one call. Zero means all the documents. Default is
* {@value #DEFAULT_MAX}.
*/
public static final String DEFAULT_MAX_PROP = "org.nuxeo.vcs.softdelete.cleanup.max";
public static final int DEFAULT_DELAY = 5 * 60; // 5 min
/**
* Property for the minimum delay (in seconds) since when a document must have been soft-deleted before it can be
* hard-deleted. Zero means no delay. Default is {@value #DEFAULT_DELAY}.
*/
public static final String DEFAULT_DELAY_PROP = "org.nuxeo.vcs.softdelete.cleanup.age";
/**
* Gets the maximum number of documents to delete in one call. Zero means all the documents.
*/
protected int getMax() {
String max = Framework.getProperty(DEFAULT_MAX_PROP);
if (max == null) {
return DEFAULT_MAX;
}
try {
return Integer.parseInt(max);
} catch (NumberFormatException e) {
log.error("Invalid property " + DEFAULT_MAX_PROP, e);
return DEFAULT_MAX;
}
}
/**
* Gets the minimum delay (in seconds) since when a document must have been soft-deleted before it can be
* hard-deleted. Zero means no delay.
*/
protected int getDelaySeconds() {
String delay = Framework.getProperty(DEFAULT_DELAY_PROP);
if (delay == null) {
return DEFAULT_DELAY;
}
try {
return Integer.parseInt(delay);
} catch (NumberFormatException e) {
log.error("Invalid property " + DEFAULT_DELAY_PROP, e);
return DEFAULT_DELAY;
}
}
@Override
public void handleEvent(Event event) {
RepositoryService repositoryService = Framework.getService(RepositoryService.class);
if (repositoryService == null) {
// RepositoryService failed to start, no need to go further
return;
}
int max = getMax();
int delay = getDelaySeconds();
Calendar beforeTime;
if (delay <= 0) {
beforeTime = null;
} else {
beforeTime = Calendar.getInstance();
beforeTime.add(Calendar.SECOND, -delay);
}
SQLRepositoryService sqlRepositoryService = Framework.getService(SQLRepositoryService.class);
for (RepositoryManagement repoMgmt : sqlRepositoryService.getRepositories()) {
log.debug("Calling repository soft-delete cleanup for repository: " + repoMgmt.getName() + ", max=" + max
+ ", beforeTimeDelay=" + delay);
int n = repoMgmt.cleanupDeletedDocuments(max, beforeTime);
log.debug("Number of documents deleted: " + n);
}
}
}