mirror of
https://github.com/DSpace/DSpace.git
synced 2025-10-16 22:43:12 +00:00
[CST-6756] Implemented script to delete old processes
This commit is contained in:
@@ -0,0 +1,126 @@
|
|||||||
|
/**
|
||||||
|
* The contents of this file are subject to the license and copyright
|
||||||
|
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||||
|
* tree and available online at
|
||||||
|
*
|
||||||
|
* http://www.dspace.org/license/
|
||||||
|
*/
|
||||||
|
package org.dspace.administer;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.commons.cli.ParseException;
|
||||||
|
import org.apache.commons.lang.time.DateUtils;
|
||||||
|
import org.dspace.authorize.AuthorizeException;
|
||||||
|
import org.dspace.content.ProcessStatus;
|
||||||
|
import org.dspace.core.Context;
|
||||||
|
import org.dspace.scripts.DSpaceRunnable;
|
||||||
|
import org.dspace.scripts.Process;
|
||||||
|
import org.dspace.scripts.factory.ScriptServiceFactory;
|
||||||
|
import org.dspace.scripts.service.ProcessService;
|
||||||
|
import org.dspace.services.ConfigurationService;
|
||||||
|
import org.dspace.services.factory.DSpaceServicesFactory;
|
||||||
|
import org.dspace.utils.DSpace;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Script to cleanup the old processes in the specified state.
|
||||||
|
*
|
||||||
|
* @author Luca Giamminonni (luca.giamminonni at 4science.it)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class ProcessCleaner extends DSpaceRunnable<ProcessCleanerConfiguration<ProcessCleaner>> {
|
||||||
|
|
||||||
|
|
||||||
|
private ConfigurationService configurationService;
|
||||||
|
|
||||||
|
private ProcessService processService;
|
||||||
|
|
||||||
|
|
||||||
|
boolean cleanCompleted = false;
|
||||||
|
|
||||||
|
boolean cleanFailed = false;
|
||||||
|
|
||||||
|
boolean cleanRunning = false;
|
||||||
|
|
||||||
|
private Integer days;
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setup() throws ParseException {
|
||||||
|
|
||||||
|
this.configurationService = DSpaceServicesFactory.getInstance().getConfigurationService();
|
||||||
|
this.processService = ScriptServiceFactory.getInstance().getProcessService();
|
||||||
|
|
||||||
|
this.cleanFailed = commandLine.hasOption('f');
|
||||||
|
this.cleanRunning = commandLine.hasOption('r');
|
||||||
|
this.cleanCompleted = commandLine.hasOption('c') || (!cleanFailed && !cleanRunning);
|
||||||
|
|
||||||
|
this.days = configurationService.getIntProperty("process-cleaner.days", 14);
|
||||||
|
|
||||||
|
if (this.days <= 0) {
|
||||||
|
throw new IllegalArgumentException("The number of days must be a positive integer.");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void internalRun() throws Exception {
|
||||||
|
|
||||||
|
Context context = new Context();
|
||||||
|
|
||||||
|
try {
|
||||||
|
context.turnOffAuthorisationSystem();
|
||||||
|
performDeletion(context);
|
||||||
|
} finally {
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
context.complete();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void performDeletion(Context context) throws SQLException, IOException, AuthorizeException {
|
||||||
|
|
||||||
|
List<ProcessStatus> statuses = getProcessToDeleteStatuses();
|
||||||
|
Date creationDate = calculateCreationDate();
|
||||||
|
|
||||||
|
handler.logInfo("Searching for processes with one of the following status: " + statuses);
|
||||||
|
List<Process> processes = processService.findByStatusAndCreationTimeOlderThan(context, statuses, creationDate);
|
||||||
|
handler.logInfo("Found " + processes.size() + " processes to be deleted");
|
||||||
|
for (Process process : processes) {
|
||||||
|
processService.delete(context, process);
|
||||||
|
}
|
||||||
|
|
||||||
|
handler.logInfo("Process cleanup completed");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<ProcessStatus> getProcessToDeleteStatuses() {
|
||||||
|
List<ProcessStatus> statuses = new ArrayList<ProcessStatus>();
|
||||||
|
if (cleanCompleted) {
|
||||||
|
statuses.add(ProcessStatus.COMPLETED);
|
||||||
|
}
|
||||||
|
if (cleanFailed) {
|
||||||
|
statuses.add(ProcessStatus.FAILED);
|
||||||
|
}
|
||||||
|
if (cleanRunning) {
|
||||||
|
statuses.add(ProcessStatus.RUNNING);
|
||||||
|
}
|
||||||
|
return statuses;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Date calculateCreationDate() {
|
||||||
|
return DateUtils.addDays(new Date(), -days);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public ProcessCleanerConfiguration<ProcessCleaner> getScriptConfiguration() {
|
||||||
|
return new DSpace().getServiceManager()
|
||||||
|
.getServiceByName("process-cleaner", ProcessCleanerConfiguration.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,18 @@
|
|||||||
|
/**
|
||||||
|
* The contents of this file are subject to the license and copyright
|
||||||
|
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||||
|
* tree and available online at
|
||||||
|
*
|
||||||
|
* http://www.dspace.org/license/
|
||||||
|
*/
|
||||||
|
package org.dspace.administer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link ProcessCleaner} for CLI.
|
||||||
|
*
|
||||||
|
* @author Luca Giamminonni (luca.giamminonni at 4science.it)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class ProcessCleanerCli extends ProcessCleaner {
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,18 @@
|
|||||||
|
/**
|
||||||
|
* The contents of this file are subject to the license and copyright
|
||||||
|
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||||
|
* tree and available online at
|
||||||
|
*
|
||||||
|
* http://www.dspace.org/license/
|
||||||
|
*/
|
||||||
|
package org.dspace.administer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link ProcessCleanerConfiguration} for CLI.
|
||||||
|
*
|
||||||
|
* @author Luca Giamminonni (luca.giamminonni at 4science.it)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class ProcessCleanerCliConfiguration extends ProcessCleanerConfiguration<ProcessCleanerCli> {
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,68 @@
|
|||||||
|
/**
|
||||||
|
* The contents of this file are subject to the license and copyright
|
||||||
|
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||||
|
* tree and available online at
|
||||||
|
*
|
||||||
|
* http://www.dspace.org/license/
|
||||||
|
*/
|
||||||
|
package org.dspace.administer;
|
||||||
|
|
||||||
|
import java.sql.SQLException;
|
||||||
|
|
||||||
|
import org.apache.commons.cli.Options;
|
||||||
|
import org.dspace.authorize.service.AuthorizeService;
|
||||||
|
import org.dspace.core.Context;
|
||||||
|
import org.dspace.scripts.configuration.ScriptConfiguration;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link ScriptConfiguration} for the {@link ProcessCleaner} script.
|
||||||
|
*/
|
||||||
|
public class ProcessCleanerConfiguration<T extends ProcessCleaner> extends ScriptConfiguration<T> {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private AuthorizeService authorizeService;
|
||||||
|
|
||||||
|
private Class<T> dspaceRunnableClass;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isAllowedToExecute(Context context) {
|
||||||
|
try {
|
||||||
|
return authorizeService.isAdmin(context);
|
||||||
|
} catch (SQLException e) {
|
||||||
|
throw new RuntimeException("SQLException occurred when checking if the current user is an admin", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Options getOptions() {
|
||||||
|
if (options == null) {
|
||||||
|
|
||||||
|
Options options = new Options();
|
||||||
|
|
||||||
|
options.addOption("r", "running", false, "delete the process with RUNNING status");
|
||||||
|
options.getOption("r").setType(boolean.class);
|
||||||
|
|
||||||
|
options.addOption("f", "failed", false, "delete the process with FAILED status");
|
||||||
|
options.getOption("f").setType(boolean.class);
|
||||||
|
|
||||||
|
options.addOption("c", "completed", false,
|
||||||
|
"delete the process with COMPLETED status (default if no statuses are specified)");
|
||||||
|
options.getOption("c").setType(boolean.class);
|
||||||
|
|
||||||
|
super.options = options;
|
||||||
|
}
|
||||||
|
return options;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<T> getDspaceRunnableClass() {
|
||||||
|
return dspaceRunnableClass;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setDspaceRunnableClass(Class<T> dspaceRunnableClass) {
|
||||||
|
this.dspaceRunnableClass = dspaceRunnableClass;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -8,10 +8,13 @@
|
|||||||
package org.dspace.content.dao;
|
package org.dspace.content.dao;
|
||||||
|
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.dspace.content.ProcessStatus;
|
||||||
import org.dspace.core.Context;
|
import org.dspace.core.Context;
|
||||||
import org.dspace.core.GenericDAO;
|
import org.dspace.core.GenericDAO;
|
||||||
|
import org.dspace.eperson.EPerson;
|
||||||
import org.dspace.scripts.Process;
|
import org.dspace.scripts.Process;
|
||||||
import org.dspace.scripts.ProcessQueryParameterContainer;
|
import org.dspace.scripts.ProcessQueryParameterContainer;
|
||||||
|
|
||||||
@@ -81,4 +84,18 @@ public interface ProcessDAO extends GenericDAO<Process> {
|
|||||||
|
|
||||||
int countTotalWithParameters(Context context, ProcessQueryParameterContainer processQueryParameterContainer)
|
int countTotalWithParameters(Context context, ProcessQueryParameterContainer processQueryParameterContainer)
|
||||||
throws SQLException;
|
throws SQLException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find all the processes with one of the given status and with a creation time
|
||||||
|
* older than the specified date.
|
||||||
|
*
|
||||||
|
* @param context The relevant DSpace context
|
||||||
|
* @param statuses the statuses of the processes to search for
|
||||||
|
* @param date the creation date to search for
|
||||||
|
* @return The list of all Processes which match requirements
|
||||||
|
* @throws SQLException If something goes wrong
|
||||||
|
*/
|
||||||
|
List<Process> findByStatusAndCreationTimeOlderThan(Context context, List<ProcessStatus> statuses, Date date)
|
||||||
|
throws SQLException;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -7,7 +7,10 @@
|
|||||||
*/
|
*/
|
||||||
package org.dspace.content.dao.impl;
|
package org.dspace.content.dao.impl;
|
||||||
|
|
||||||
|
import static org.dspace.scripts.Process_.CREATION_TIME;
|
||||||
|
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
import java.util.Date;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -17,6 +20,7 @@ import javax.persistence.criteria.Predicate;
|
|||||||
import javax.persistence.criteria.Root;
|
import javax.persistence.criteria.Root;
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.dspace.content.ProcessStatus;
|
||||||
import org.dspace.content.dao.ProcessDAO;
|
import org.dspace.content.dao.ProcessDAO;
|
||||||
import org.dspace.core.AbstractHibernateDAO;
|
import org.dspace.core.AbstractHibernateDAO;
|
||||||
import org.dspace.core.Context;
|
import org.dspace.core.Context;
|
||||||
@@ -147,6 +151,23 @@ public class ProcessDAOImpl extends AbstractHibernateDAO<Process> implements Pro
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Process> findByStatusAndCreationTimeOlderThan(Context context, List<ProcessStatus> statuses,
|
||||||
|
Date date) throws SQLException {
|
||||||
|
|
||||||
|
CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context);
|
||||||
|
CriteriaQuery<Process> criteriaQuery = getCriteriaQuery(criteriaBuilder, Process.class);
|
||||||
|
|
||||||
|
Root<Process> processRoot = criteriaQuery.from(Process.class);
|
||||||
|
criteriaQuery.select(processRoot);
|
||||||
|
|
||||||
|
Predicate creationTimeLessThanGivenDate = criteriaBuilder.lessThan(processRoot.get(CREATION_TIME), date);
|
||||||
|
Predicate statusIn = processRoot.get(Process_.PROCESS_STATUS).in(statuses);
|
||||||
|
criteriaQuery.where(criteriaBuilder.and(creationTimeLessThanGivenDate, statusIn));
|
||||||
|
|
||||||
|
return list(context, criteriaQuery, false, Process.class, -1, -1);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -305,6 +305,12 @@ public class ProcessServiceImpl implements ProcessService {
|
|||||||
tempFile.delete();
|
tempFile.delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Process> findByStatusAndCreationTimeOlderThan(Context context, List<ProcessStatus> statuses,
|
||||||
|
Date date) throws SQLException {
|
||||||
|
return this.processDAO.findByStatusAndCreationTimeOlderThan(context, statuses, date);
|
||||||
|
}
|
||||||
|
|
||||||
private String formatLogLine(int processId, String scriptName, String output, ProcessLogLevel processLogLevel) {
|
private String formatLogLine(int processId, String scriptName, String output, ProcessLogLevel processLogLevel) {
|
||||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
|
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
|
@@ -10,11 +10,13 @@ package org.dspace.scripts.service;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.dspace.authorize.AuthorizeException;
|
import org.dspace.authorize.AuthorizeException;
|
||||||
import org.dspace.content.Bitstream;
|
import org.dspace.content.Bitstream;
|
||||||
|
import org.dspace.content.ProcessStatus;
|
||||||
import org.dspace.core.Context;
|
import org.dspace.core.Context;
|
||||||
import org.dspace.eperson.EPerson;
|
import org.dspace.eperson.EPerson;
|
||||||
import org.dspace.eperson.Group;
|
import org.dspace.eperson.Group;
|
||||||
@@ -240,4 +242,17 @@ public interface ProcessService {
|
|||||||
*/
|
*/
|
||||||
void createLogBitstream(Context context, Process process)
|
void createLogBitstream(Context context, Process process)
|
||||||
throws IOException, SQLException, AuthorizeException;
|
throws IOException, SQLException, AuthorizeException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find all the processes with one of the given status and with a creation time
|
||||||
|
* older than the specified date.
|
||||||
|
*
|
||||||
|
* @param context The relevant DSpace context
|
||||||
|
* @param statuses the statuses of the processes to search for
|
||||||
|
* @param date the creation date to search for
|
||||||
|
* @return The list of all Processes which match requirements
|
||||||
|
* @throws AuthorizeException If something goes wrong
|
||||||
|
*/
|
||||||
|
List<Process> findByStatusAndCreationTimeOlderThan(Context context, List<ProcessStatus> statuses, Date date)
|
||||||
|
throws SQLException;
|
||||||
}
|
}
|
||||||
|
@@ -50,6 +50,11 @@
|
|||||||
<property name="description" value="Manage the OAI-PMH harvesting of external collections"/>
|
<property name="description" value="Manage the OAI-PMH harvesting of external collections"/>
|
||||||
<property name="dspaceRunnableClass" value="org.dspace.app.harvest.HarvestCli"/>
|
<property name="dspaceRunnableClass" value="org.dspace.app.harvest.HarvestCli"/>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
|
<bean id="process-cleaner" class="org.dspace.administer.ProcessCleanerCliConfiguration">
|
||||||
|
<property name="description" value="Cleanup all the old processes in the specified state"/>
|
||||||
|
<property name="dspaceRunnableClass" value="org.dspace.administer.ProcessCleanerCli"/>
|
||||||
|
</bean>
|
||||||
|
|
||||||
<bean id="filter-media" class="org.dspace.app.mediafilter.MediaFilterScriptConfiguration">
|
<bean id="filter-media" class="org.dspace.app.mediafilter.MediaFilterScriptConfiguration">
|
||||||
<property name="description" value="Perform the media filtering to extract full text from documents and to create thumbnails"/>
|
<property name="description" value="Perform the media filtering to extract full text from documents and to create thumbnails"/>
|
||||||
|
@@ -39,6 +39,11 @@
|
|||||||
<property name="dspaceRunnableClass" value="org.dspace.app.harvest.Harvest"/>
|
<property name="dspaceRunnableClass" value="org.dspace.app.harvest.Harvest"/>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
|
<bean id="process-cleaner" class="org.dspace.administer.ProcessCleanerConfiguration" primary="true">
|
||||||
|
<property name="description" value="Cleanup all the old processes in the specified state"/>
|
||||||
|
<property name="dspaceRunnableClass" value="org.dspace.administer.ProcessCleaner"/>
|
||||||
|
</bean>
|
||||||
|
|
||||||
<bean id="orcid-bulk-push" class="org.dspace.orcid.script.OrcidBulkPushScriptConfiguration" primary="true">
|
<bean id="orcid-bulk-push" class="org.dspace.orcid.script.OrcidBulkPushScriptConfiguration" primary="true">
|
||||||
<property name="description" value="Perform the bulk synchronization of all the BATCH configured ORCID entities placed in the ORCID queue"/>
|
<property name="description" value="Perform the bulk synchronization of all the BATCH configured ORCID entities placed in the ORCID queue"/>
|
||||||
<property name="dspaceRunnableClass" value="org.dspace.orcid.script.OrcidBulkPush"/>
|
<property name="dspaceRunnableClass" value="org.dspace.orcid.script.OrcidBulkPush"/>
|
||||||
|
Reference in New Issue
Block a user