diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/DataStoreService.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/DataStoreService.java index 6a4b27348a50e01abd4e602ec932004d61324fd6..b986343df1225e22a7acd0d10956651b0124d629 100644 --- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/DataStoreService.java +++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/DataStoreService.java @@ -38,8 +38,8 @@ import ch.systemsx.cisd.common.spring.AbstractServiceWithLogger; import ch.systemsx.cisd.common.spring.IInvocationLoggerContext; import ch.systemsx.cisd.common.utilities.IInitializable; import ch.systemsx.cisd.openbis.dss.generic.server.plugins.tasks.ArchiverTaskContext; -import ch.systemsx.cisd.openbis.dss.generic.server.plugins.tasks.ArchiverTaskFactory; -import ch.systemsx.cisd.openbis.dss.generic.server.plugins.tasks.IArchiverTask; +import ch.systemsx.cisd.openbis.dss.generic.server.plugins.tasks.ArchiverPluginFactory; +import ch.systemsx.cisd.openbis.dss.generic.server.plugins.tasks.IArchiverPlugin; import ch.systemsx.cisd.openbis.dss.generic.server.plugins.tasks.IProcessingPluginTask; import ch.systemsx.cisd.openbis.dss.generic.server.plugins.tasks.IReportingPluginTask; import ch.systemsx.cisd.openbis.dss.generic.server.plugins.tasks.PluginTaskProvider; @@ -333,24 +333,33 @@ public class DataStoreService extends AbstractServiceWithLogger<IDataStoreServic public void unarchiveDatasets(String sessionToken, List<DatasetDescription> datasets, String userEmailOrNull) { - scheduleArchiverTask(sessionToken, datasets, userEmailOrNull, false); + String description = "Unarchiving"; + IProcessingPluginTask task = new UnarchiveProcessingPluginTask(createArchiver()); + + scheduleTask(sessionToken, description, task, datasets, userEmailOrNull); } public void archiveDatasets(String sessionToken, List<DatasetDescription> datasets, - String userEmailOrNull) + String userEmailOrNull, boolean removeFromDataStore) { - scheduleArchiverTask(sessionToken, datasets, userEmailOrNull, true); + String description = removeFromDataStore ? "Archiving" : "Copying data sets to archive"; + IProcessingPluginTask task = + new ArchiveProcessingPluginTask(createArchiver(), removeFromDataStore); + + scheduleTask(sessionToken, description, task, datasets, userEmailOrNull); } - private void scheduleArchiverTask(String sessionToken, List<DatasetDescription> datasets, - String userEmailOrNull, boolean archive) + private IArchiverPlugin createArchiver() { - sessionTokenManager.assertValidSessionToken(sessionToken); + ArchiverPluginFactory factory = pluginTaskParameters.getArchiverTaskFactory(); + return factory.createInstance(storeRoot, commandExecutor); + } - String description = archive ? "Archiving" : "Unarchiving"; - ArchiverTaskFactory factory = pluginTaskParameters.getArchiverTaskFactory(); - final IArchiverTask archiverTask = factory.createInstance(storeRoot); - IProcessingPluginTask processingTask = new ArchiverProcessingTask(archiverTask, archive); + private void scheduleTask(String sessionToken, String description, + IProcessingPluginTask processingTask, List<DatasetDescription> datasets, + String userEmailOrNull) + { + sessionTokenManager.assertValidSessionToken(sessionToken); DatastoreServiceDescription pluginDescription = DatastoreServiceDescription.processing(description, description, null, null); Map<String, String> parameterBindings = Collections.<String, String> emptyMap(); @@ -358,19 +367,20 @@ public class DataStoreService extends AbstractServiceWithLogger<IDataStoreServic userEmailOrNull, pluginDescription, mailClientParameters); } - private static class ArchiverProcessingTask implements IProcessingPluginTask + private static class ArchiveProcessingPluginTask implements IProcessingPluginTask { private static final long serialVersionUID = 1L; - private boolean archive; + private IArchiverPlugin archiverTask; - private IArchiverTask archiverTask; + private boolean removeFromDataStore; - public ArchiverProcessingTask(final IArchiverTask archiverTask, final boolean archive) + public ArchiveProcessingPluginTask(final IArchiverPlugin archiverTask, + final boolean removeFromDataStore) { this.archiverTask = archiverTask; - this.archive = archive; + this.removeFromDataStore = removeFromDataStore; } public ProcessingStatus process(List<DatasetDescription> datasets, @@ -378,13 +388,28 @@ public class DataStoreService extends AbstractServiceWithLogger<IDataStoreServic { ArchiverTaskContext archiverContext = new ArchiverTaskContext(context.getDirectoryProvider()); - if (archive) - { - return archiverTask.archive(datasets, archiverContext); - } else - { - return archiverTask.unarchive(datasets, archiverContext); - } + return archiverTask.archive(datasets, archiverContext, removeFromDataStore); + } + } + + private static class UnarchiveProcessingPluginTask implements IProcessingPluginTask + { + + private static final long serialVersionUID = 1L; + + private IArchiverPlugin archiverTask; + + public UnarchiveProcessingPluginTask(final IArchiverPlugin archiverTask) + { + this.archiverTask = archiverTask; + } + + public ProcessingStatus process(List<DatasetDescription> datasets, + DataSetProcessingContext context) + { + ArchiverTaskContext archiverContext = + new ArchiverTaskContext(context.getDirectoryProvider()); + return archiverTask.unarchive(datasets, archiverContext); } } diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/DataStoreServiceLogger.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/DataStoreServiceLogger.java index f49f9fb22982be3a2881e6ed9fffa108792c164a..723c26c2a896c183757d8c4c3b4c43d44d8eb244 100644 --- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/DataStoreServiceLogger.java +++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/DataStoreServiceLogger.java @@ -133,10 +133,10 @@ class DataStoreServiceLogger implements IDataStoreService, IInitializable } public void archiveDatasets(String sessionToken, List<DatasetDescription> datasets, - String userEmailOrNull) + String userEmailOrNull, boolean removeFromDataStore) { - log("archiveDatasets", "NO_OF_DATASETS(%s) USER_EMAIL(%s)", datasets.size(), - userEmailOrNull); + log("archiveDatasets", "NO_OF_DATASETS(%s) USER_EMAIL(%s) REMOVE_FROM_DATA_STORE(%s)", + datasets.size(), userEmailOrNull, removeFromDataStore); } public LinkModel retrieveLinkFromDataSet(String sessionToken, String serviceKey, diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/EncapsulatedOpenBISService.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/EncapsulatedOpenBISService.java index 7222d8f2c0b266c526b93afc105b377bfd324d1d..6aed490436529bfa028261df318106a08bd3795a 100644 --- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/EncapsulatedOpenBISService.java +++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/EncapsulatedOpenBISService.java @@ -292,14 +292,14 @@ public final class EncapsulatedOpenBISService implements IEncapsulatedOpenBISSer } } - public final void updateDataSetStatuses(List<String> codes, - DataSetArchivingStatus newStatus) throws UserFailureException + public final void updateDataSetStatuses(List<String> codes, DataSetArchivingStatus newStatus, + boolean presentInArchive) throws UserFailureException { assert codes != null : "missing data set codes"; assert newStatus != null : "missing status"; - service.updateDataSetStatuses(session.getToken(), codes, newStatus); + service.updateDataSetStatuses(session.getToken(), codes, newStatus, presentInArchive); if (operationLog.isInfoEnabled()) { operationLog.info("Updated in openBIS: data sets " + codes + ", status=" + newStatus); @@ -426,9 +426,10 @@ public final class EncapsulatedOpenBISService implements IEncapsulatedOpenBISSer return service.listDeletedDataSets(session.getToken(), lastSeenDeletionEventIdOrNull); } - public void archiveDataSets(List<String> dataSetCodes) throws UserFailureException + public void archiveDataSets(List<String> dataSetCodes, boolean removeFromDataStore) + throws UserFailureException { - service.archiveDatasets(session.getToken(), dataSetCodes); + service.archiveDatasets(session.getToken(), dataSetCodes, removeFromDataStore); } public void unarchiveDataSets(List<String> dataSetCodes) throws UserFailureException diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/IDataSetCommandExecutor.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/IDataSetCommandExecutor.java index ee1f5954291c254a6a219a3c13553c5e48256112..e05d54176df78421d6c62cdf923c8006a2b15180 100644 --- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/IDataSetCommandExecutor.java +++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/IDataSetCommandExecutor.java @@ -33,7 +33,7 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.DatasetDescription; * * @author Franz-Josef Elmer */ -interface IDataSetCommandExecutor +public interface IDataSetCommandExecutor { /** * Starts up executor. diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/demo/DemoArchiver.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/demo/DemoArchiver.java index 8cc2074f6d4296ebd223d13aa0ba33c0cc136f4d..b942465059750b19823222fb21501084a6e6f881 100644 --- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/demo/DemoArchiver.java +++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/demo/DemoArchiver.java @@ -17,11 +17,15 @@ package ch.systemsx.cisd.openbis.dss.generic.server.plugins.demo; import java.io.File; +import java.util.HashSet; import java.util.List; import java.util.Properties; +import java.util.Set; import ch.systemsx.cisd.common.exceptions.Status; import ch.systemsx.cisd.common.exceptions.UserFailureException; +import ch.systemsx.cisd.common.filesystem.BooleanStatus; +import ch.systemsx.cisd.openbis.dss.generic.server.IDataSetCommandExecutor; import ch.systemsx.cisd.openbis.dss.generic.server.plugins.standard.AbstractArchiverProcessingPlugin; import ch.systemsx.cisd.openbis.dss.generic.server.plugins.tasks.ArchiverTaskContext; import ch.systemsx.cisd.openbis.generic.shared.dto.DatasetDescription; @@ -33,9 +37,12 @@ public class DemoArchiver extends AbstractArchiverProcessingPlugin { private static final long serialVersionUID = 1L; - public DemoArchiver(Properties properties, File storeRoot) + private final static Set<String/* data set code */> archiveContents = new HashSet<String>(); + + public DemoArchiver(Properties properties, File storeRoot, + IDataSetCommandExecutor commandExecutor) { - super(properties, storeRoot, null, null); + super(properties, storeRoot, commandExecutor, null, null); } @Override @@ -43,7 +50,8 @@ public class DemoArchiver extends AbstractArchiverProcessingPlugin ArchiverTaskContext context) throws UserFailureException { System.out.println("DemoArchiver - Archived: " + datasets); - return createStatusesFrom(Status.OK, datasets, true); + archiveContents.addAll(extractCodes(datasets)); + return createStatuses(Status.OK, datasets, Operation.ARCHIVE); } @Override @@ -51,7 +59,24 @@ public class DemoArchiver extends AbstractArchiverProcessingPlugin ArchiverTaskContext context) throws UserFailureException { System.out.println("DemoArchiver - Unarchived: " + datasets); - return createStatusesFrom(Status.OK, datasets, false); + return createStatuses(Status.OK, datasets, Operation.UNARCHIVE); + } + + @Override + public BooleanStatus isDataSetPresentInArchive(DatasetDescription dataset, + ArchiverTaskContext context) + { + boolean present = archiveContents.contains(dataset.getDatasetCode()); + return BooleanStatus.createFromBoolean(present); + } + + @Override + protected DatasetProcessingStatuses doDeleteFromArchive(List<DatasetDescription> datasets, + ArchiverTaskContext context) throws UserFailureException + { + archiveContents.addAll(extractCodes(datasets)); + System.out.println("DemoArchiver - deleteFromArchive: " + datasets); + return createStatuses(Status.OK, datasets, Operation.DELETE_FROM_ARCHIVE); } } diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/standard/AbstractArchiverProcessingPlugin.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/standard/AbstractArchiverProcessingPlugin.java index d64ac31783bf19916f6edb2e22eb82e46e24e523..7bf9c34921f71b8f505190660bcaf47ce488da26 100644 --- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/standard/AbstractArchiverProcessingPlugin.java +++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/standard/AbstractArchiverProcessingPlugin.java @@ -16,16 +16,23 @@ package ch.systemsx.cisd.openbis.dss.generic.server.plugins.standard; +import static ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetArchivingStatus.ARCHIVED; +import static ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetArchivingStatus.AVAILABLE; + import java.io.File; import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Properties; import ch.systemsx.cisd.common.collections.CollectionUtils; import ch.systemsx.cisd.common.exceptions.Status; -import ch.systemsx.cisd.common.exceptions.UserFailureException; +import ch.systemsx.cisd.common.filesystem.BooleanStatus; +import ch.systemsx.cisd.openbis.dss.generic.server.IDataSetCommandExecutor; import ch.systemsx.cisd.openbis.dss.generic.server.plugins.tasks.ArchiverTaskContext; -import ch.systemsx.cisd.openbis.dss.generic.server.plugins.tasks.IArchiverTask; +import ch.systemsx.cisd.openbis.dss.generic.server.plugins.tasks.IArchiverPlugin; import ch.systemsx.cisd.openbis.dss.generic.server.plugins.tasks.ProcessingStatus; import ch.systemsx.cisd.openbis.dss.generic.shared.QueueingDataSetStatusUpdaterService; import ch.systemsx.cisd.openbis.dss.generic.shared.dto.DataSetCodesWithStatus; @@ -36,9 +43,10 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.DatasetDescription; * The base class for archiving. * * @author Piotr Buczek + * @author Kaloyan Enimanev */ public abstract class AbstractArchiverProcessingPlugin extends AbstractDatastorePlugin implements - IArchiverTask + IArchiverPlugin { private static final long serialVersionUID = 1L; @@ -47,62 +55,134 @@ public abstract class AbstractArchiverProcessingPlugin extends AbstractDatastore private final IStatusChecker unarchivePrerequisiteOrNull; + private final IDataSetCommandExecutor commandExecutor; + public AbstractArchiverProcessingPlugin(Properties properties, File storeRoot, + IDataSetCommandExecutor commandExecutor, IStatusChecker archivePrerequisiteOrNull, IStatusChecker unarchivePrerequisiteOrNull) { super(properties, storeRoot); + this.commandExecutor = commandExecutor; this.archivePrerequisiteOrNull = archivePrerequisiteOrNull; this.unarchivePrerequisiteOrNull = unarchivePrerequisiteOrNull; } + /** + * NOTE: this method is not allowed to throw exception as this will leave data sets in the + * openBIS database with an inconsistent status. + */ abstract protected DatasetProcessingStatuses doArchive(List<DatasetDescription> datasets, - ArchiverTaskContext context) throws UserFailureException; + ArchiverTaskContext context); + /** + * NOTE: this method is not allowed to throw exception as this will leave data sets in the + * openBIS database with an inconsistent status. + */ abstract protected DatasetProcessingStatuses doUnarchive(List<DatasetDescription> datasets, - ArchiverTaskContext context) throws UserFailureException; + ArchiverTaskContext context); + + /** + * NOTE: this method is not allowed to throw exception as this will leave data sets in the + * openBIS database with an inconsistent status. + */ + abstract protected DatasetProcessingStatuses doDeleteFromArchive( + List<DatasetDescription> datasets, ArchiverTaskContext context); + + /** + * @return <code>true</code> if the dataset is present in the archive, <code>false</code> + * otherwise. + */ + abstract protected BooleanStatus isDataSetPresentInArchive(DatasetDescription dataset, + ArchiverTaskContext context); public ProcessingStatus archive(List<DatasetDescription> datasets, - final ArchiverTaskContext context) + final ArchiverTaskContext context, boolean removeFromDataStore) { operationLog.info("Archiving of the following datasets has been requested: " + CollectionUtils.abbreviate(datasets, 10)); - return handleDatasets(datasets, DataSetArchivingStatus.ARCHIVED, - DataSetArchivingStatus.AVAILABLE, new IDatasetDescriptionHandler() - { - public DatasetProcessingStatuses handle(List<DatasetDescription> allDatasets) - { - Status prerequisiteStatus = checkArchivePrerequisite(allDatasets); - if (prerequisiteStatus.isError()) - { - return createStatusesFrom(prerequisiteStatus, allDatasets, true); - } else - { - return doArchive(allDatasets, context); - } - } - }); + + Status prerequisiteStatus = checkUnarchivePrerequisite(datasets); + DatasetProcessingStatuses statuses = null; + if (prerequisiteStatus.isError()) + { + statuses = createStatuses(prerequisiteStatus, datasets, Operation.ARCHIVE); + } else + { + statuses = archiveInternal(datasets, context, removeFromDataStore); + } + + DataSetArchivingStatus successStatus = (removeFromDataStore) ? ARCHIVED : AVAILABLE; + + asyncUpdateStatuses(statuses.getSuccessfulDatasetCodes(), successStatus, true); + asyncUpdateStatuses(statuses.getFailedDatasetCodes(), AVAILABLE, false); + + return statuses.getProcessingStatus(); + } + + private DatasetProcessingStatuses archiveInternal(List<DatasetDescription> datasets, + final ArchiverTaskContext context, boolean removeFromDataStore) + { + + GroupedDatasets groupedDatasets = groupByPresenceInArchive(datasets, context); + List<DatasetDescription> notPresentInArchive = groupedDatasets.getNotPresentAsList(); + if (notPresentInArchive.isEmpty() == false) + { + // copy data sets in the archive + // TODO KE: try to keep the error messages from the returned statuses + doArchive(notPresentInArchive, context); + + // paranoid check to make sure everything really got archived + groupedDatasets = groupByPresenceInArchive(datasets, context); + } + + if (removeFromDataStore) + { + // only remove the when we are sure we have got a backup in the archive + removeFromDataStore(groupedDatasets.getPresentInArchive(), context); + } + + DatasetProcessingStatuses statuses = new DatasetProcessingStatuses(); + statuses.addResult(groupedDatasets.getPresentInArchive(), Status.OK, Operation.ARCHIVE); + statuses.addResult(groupedDatasets.getNotPresentInArchive().keySet(), Status.createError(), + Operation.ARCHIVE); + + return statuses; + } + + protected void removeFromDataStore(List<DatasetDescription> datasets, + ArchiverTaskContext context) + { + // the deletion will happen at a later point in time + commandExecutor.scheduleDeletionOfDataSets(datasets); } public ProcessingStatus unarchive(List<DatasetDescription> datasets, - final ArchiverTaskContext contex) + final ArchiverTaskContext context) { operationLog.info("Unarchiving of the following datasets has been requested: " + CollectionUtils.abbreviate(datasets, 10)); - return handleDatasets(datasets, DataSetArchivingStatus.AVAILABLE, - DataSetArchivingStatus.ARCHIVED, new IDatasetDescriptionHandler() - { - public DatasetProcessingStatuses handle(List<DatasetDescription> allDatasets) - { - Status prerequisiteStatus = checkUnarchivePrerequisite(allDatasets); - if (prerequisiteStatus.isError()) - { - return createStatusesFrom(prerequisiteStatus, allDatasets, false); - } else - { - return doUnarchive(allDatasets, contex); - } - } - }); + + Status prerequisiteStatus = checkUnarchivePrerequisite(datasets); + DatasetProcessingStatuses statuses = null; + if (prerequisiteStatus.isError()) + { + statuses = createStatuses(prerequisiteStatus, datasets, Operation.UNARCHIVE); + } else + { + statuses = doUnarchive(datasets, context); + } + + asyncUpdateStatuses(statuses.getSuccessfulDatasetCodes(), AVAILABLE, true); + asyncUpdateStatuses(statuses.getFailedDatasetCodes(), ARCHIVED, true); + + return statuses.getProcessingStatus(); + } + + public ProcessingStatus deleteFromArchive(List<DatasetDescription> datasets, + ArchiverTaskContext context) + { + DatasetProcessingStatuses status = doDeleteFromArchive(datasets, context); + return status != null ? status.getProcessingStatus() : null; } protected final Status checkUnarchivePrerequisite(List<DatasetDescription> datasets) @@ -127,6 +207,24 @@ public abstract class AbstractArchiverProcessingPlugin extends AbstractDatastore } } + protected static enum Operation + { + ARCHIVE("Archiving"), UNARCHIVE("Unarchiving"), + DELETE_FROM_ARCHIVE("Deleting from archive"); + + private final String description; + + Operation(String description) + { + this.description = description; + } + + public String getDescription() + { + return description; + } + } + protected static class DatasetProcessingStatuses { private final List<String> successfulDatasetCodes; @@ -142,9 +240,23 @@ public abstract class AbstractArchiverProcessingPlugin extends AbstractDatastore this.processingStatus = new ProcessingStatus(); } - public void addResult(String datasetCode, Status status, boolean isArchiving) + public void addResult(Collection<DatasetDescription> datasets, Status status, + Operation operation) { - String logMessage = createLogMessage(datasetCode, status, isArchiving); + for (DatasetDescription dataset : datasets) + { + addResult(dataset.getDatasetCode(), status, operation.getDescription()); + } + } + + public void addResult(String datasetCode, Status status, Operation operation) + { + addResult(datasetCode, status, operation.getDescription()); + } + + public void addResult(String datasetCode, Status status, String operationDescription) + { + String logMessage = createLogMessage(datasetCode, status, operationDescription); if (status.isError()) { operationLog.error(logMessage); @@ -157,11 +269,10 @@ public abstract class AbstractArchiverProcessingPlugin extends AbstractDatastore processingStatus.addDatasetStatus(datasetCode, status); } - private String createLogMessage(String datasetCode, Status status, boolean isArchiving) + private String createLogMessage(String datasetCode, Status status, String operation) { - String operationDescription = isArchiving ? "Archiving" : "Unarchiving"; - return String.format("%s for dataset %s finished with the status: %s.", - operationDescription, datasetCode, status); + return String.format("%s for dataset %s finished with the status: %s.", operation, + datasetCode, status); } public List<String> getSuccessfulDatasetCodes() @@ -180,44 +291,89 @@ public abstract class AbstractArchiverProcessingPlugin extends AbstractDatastore } } - private ProcessingStatus handleDatasets(List<DatasetDescription> datasets, - DataSetArchivingStatus success, DataSetArchivingStatus failure, - IDatasetDescriptionHandler handler) + protected final static DatasetProcessingStatuses createStatuses(Status status, + List<DatasetDescription> datasets, Operation operation) { - DatasetProcessingStatuses statuses = handler.handle(datasets); - asyncUpdateStatuses(statuses, success, failure); - return statuses.getProcessingStatus(); + return createStatuses(status, datasets, operation.getDescription()); } // creates the same status for all datasets - protected final static DatasetProcessingStatuses createStatusesFrom(Status status, - List<DatasetDescription> datasets, boolean isArchiving) + protected final static DatasetProcessingStatuses createStatuses(Status status, + List<DatasetDescription> datasets, String operationDescription) { DatasetProcessingStatuses statuses = new DatasetProcessingStatuses(); for (DatasetDescription dataset : datasets) { - statuses.addResult(dataset.getDatasetCode(), status, isArchiving); + statuses.addResult(dataset.getDatasetCode(), status, operationDescription); } return statuses; } - private void asyncUpdateStatuses(DatasetProcessingStatuses statuses, - DataSetArchivingStatus success, DataSetArchivingStatus failure) + protected List<String> extractCodes(List<DatasetDescription> dataSets) { - asyncUpdateStatuses(statuses.getSuccessfulDatasetCodes(), success); - asyncUpdateStatuses(statuses.getFailedDatasetCodes(), failure); + List<String> result = new ArrayList<String>(); + for (DatasetDescription description : dataSets) + { + result.add(description.getDatasetCode()); + } + return result; } private static void asyncUpdateStatuses(List<String> dataSetCodes, - DataSetArchivingStatus newStatus) + DataSetArchivingStatus newStatus, boolean presentInArchive) { QueueingDataSetStatusUpdaterService.update(new DataSetCodesWithStatus(dataSetCodes, - newStatus)); + newStatus, presentInArchive)); } - private interface IDatasetDescriptionHandler + protected static class GroupedDatasets { - public DatasetProcessingStatuses handle(List<DatasetDescription> datasets); + private List<DatasetDescription> presentInArchive; + + private Map<DatasetDescription, BooleanStatus> notPresentInArchive; + + GroupedDatasets(List<DatasetDescription> presentInArchive, + Map<DatasetDescription, BooleanStatus> notPresentInArchive) + { + this.presentInArchive = presentInArchive; + this.notPresentInArchive = notPresentInArchive; + } + + public List<DatasetDescription> getPresentInArchive() + { + return presentInArchive; + } + + public Map<DatasetDescription, BooleanStatus> getNotPresentInArchive() + { + return notPresentInArchive; + } + + public List<DatasetDescription> getNotPresentAsList() + { + + return new ArrayList<DatasetDescription>(notPresentInArchive.keySet()); + } + } + + protected GroupedDatasets groupByPresenceInArchive(List<DatasetDescription> datasets, + ArchiverTaskContext context) + { + List<DatasetDescription> present = new ArrayList<DatasetDescription>(); + Map<DatasetDescription, BooleanStatus> notPresent = new HashMap<DatasetDescription, BooleanStatus>(); + + for (DatasetDescription dataset : datasets) { + BooleanStatus presentStatus = isDataSetPresentInArchive(dataset, context); + if (presentStatus.isSuccess()) + { + present.add(dataset); + } else { + notPresent.put(dataset, presentStatus); + } + } + + return new GroupedDatasets(present, notPresent); } + } diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/standard/RsyncArchiver.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/standard/RsyncArchiver.java index 5c2b5420579b7fc3229ece6a5bd6eb6e10348599..968fe01e44f5bc88af713ec81766546de576b7fd 100644 --- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/standard/RsyncArchiver.java +++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/standard/RsyncArchiver.java @@ -24,6 +24,7 @@ import ch.rinn.restrictions.Private; import ch.systemsx.cisd.common.exceptions.Status; import ch.systemsx.cisd.common.exceptions.UserFailureException; import ch.systemsx.cisd.common.filesystem.BooleanStatus; +import ch.systemsx.cisd.openbis.dss.generic.server.IDataSetCommandExecutor; import ch.systemsx.cisd.openbis.dss.generic.server.plugins.tasks.ArchiverTaskContext; import ch.systemsx.cisd.openbis.generic.shared.dto.DatasetDescription; @@ -49,16 +50,19 @@ public class RsyncArchiver extends AbstractArchiverProcessingPlugin private final ISshCommandExecutorFactory sshCommandExecutorFactory; - public RsyncArchiver(Properties properties, File storeRoot) + public RsyncArchiver(Properties properties, File storeRoot, + IDataSetCommandExecutor commandExecutor) { - this(properties, storeRoot, new RsyncCopierFactory(), new SshCommandExecutorFactory()); + this(properties, storeRoot, commandExecutor, new RsyncCopierFactory(), + new SshCommandExecutorFactory()); } @Private - RsyncArchiver(Properties properties, File storeRoot, IPathCopierFactory pathCopierFactory, + RsyncArchiver(Properties properties, File storeRoot, IDataSetCommandExecutor commandExecutor, + IPathCopierFactory pathCopierFactory, ISshCommandExecutorFactory sshCommandExecutorFactory) { - super(properties, storeRoot, null, null); + super(properties, storeRoot, commandExecutor, null, null); this.pathCopierFactory = pathCopierFactory; this.sshCommandExecutorFactory = sshCommandExecutorFactory; } @@ -74,7 +78,7 @@ public class RsyncArchiver extends AbstractArchiverProcessingPlugin { File originalData = getDatasetDirectory(context, dataset); Status status = doArchive(dataset, originalData); - statuses.addResult(dataset.getDatasetCode(), status, true); + statuses.addResult(dataset.getDatasetCode(), status, Operation.ARCHIVE); } return statuses; @@ -92,12 +96,13 @@ public class RsyncArchiver extends AbstractArchiverProcessingPlugin { File originalData = getDatasetDirectory(context, dataset); Status status = doUnarchive(dataset, originalData); - statuses.addResult(dataset.getDatasetCode(), status, false); + statuses.addResult(dataset.getDatasetCode(), status, Operation.UNARCHIVE); } return statuses; } + @Override protected DatasetProcessingStatuses doDeleteFromArchive(List<DatasetDescription> datasets, ArchiverTaskContext context) { @@ -108,12 +113,13 @@ public class RsyncArchiver extends AbstractArchiverProcessingPlugin for (DatasetDescription dataset : datasets) { Status status = doDeleteFromArchive(dataset); - statuses.addResult(dataset.getDatasetCode(), status, false); // false -> deletion + statuses.addResult(dataset.getDatasetCode(), status, Operation.DELETE_FROM_ARCHIVE); } return statuses; } + @Override protected BooleanStatus isDataSetPresentInArchive(DatasetDescription dataset, ArchiverTaskContext context) { diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/tasks/ArchiverTaskFactory.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/tasks/ArchiverPluginFactory.java similarity index 86% rename from datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/tasks/ArchiverTaskFactory.java rename to datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/tasks/ArchiverPluginFactory.java index 50a53559952cfb8f3c7f5422cb38eedf38cf096c..0a399668baaf4c97851943314ace0a310e1f6757 100644 --- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/tasks/ArchiverTaskFactory.java +++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/tasks/ArchiverPluginFactory.java @@ -28,16 +28,17 @@ import ch.systemsx.cisd.common.logging.LogCategory; import ch.systemsx.cisd.common.logging.LogFactory; import ch.systemsx.cisd.common.utilities.ClassUtils; import ch.systemsx.cisd.common.utilities.PropertyParametersUtil.SectionProperties; +import ch.systemsx.cisd.openbis.dss.generic.server.IDataSetCommandExecutor; /** * Factory of Archiver Tasks. * * @author Piotr Buczek */ -public class ArchiverTaskFactory +public class ArchiverPluginFactory { private static final Logger operationLog = - LogFactory.getLogger(LogCategory.OPERATION, ArchiverTaskFactory.class); + LogFactory.getLogger(LogCategory.OPERATION, ArchiverPluginFactory.class); private final String className; @@ -47,7 +48,7 @@ public class ArchiverTaskFactory @Private public final static String CLASS_PROPERTY_NAME = "class"; - public ArchiverTaskFactory(SectionProperties sectionProperties) + public ArchiverPluginFactory(SectionProperties sectionProperties) { this.className = sectionProperties.getProperties().getProperty(CLASS_PROPERTY_NAME); this.archiverProperties = sectionProperties.getProperties(); @@ -58,7 +59,7 @@ public class ArchiverTaskFactory return className != null; } - public IArchiverTask createInstance(File storeRoot) + public IArchiverPlugin createInstance(File storeRoot, IDataSetCommandExecutor commandExecutor) { if (isArchiverConfigured() == false) { @@ -66,7 +67,8 @@ public class ArchiverTaskFactory } try { - return ClassUtils.create(IArchiverTask.class, className, archiverProperties, storeRoot); + return ClassUtils.create(IArchiverPlugin.class, className, archiverProperties, + storeRoot, commandExecutor); } catch (ConfigurationFailureException ex) { throw ex; // rethrow the exception without changing the message diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/tasks/IArchiverTask.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/tasks/IArchiverPlugin.java similarity index 76% rename from datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/tasks/IArchiverTask.java rename to datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/tasks/IArchiverPlugin.java index 4fb82103bb2f38aa2bed66a5218834e496ea865b..7101dce639798f060798c02afdfb435c77d83454 100644 --- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/tasks/IArchiverTask.java +++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/tasks/IArchiverPlugin.java @@ -25,8 +25,9 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.DatasetDescription; * Interface of the archiver task. * * @author Piotr Buczek + * @author Kaloyan Enimanev */ -public interface IArchiverTask extends Serializable +public interface IArchiverPlugin extends Serializable { /** * Asynchronously processes archiving of the specified datasets. @@ -35,7 +36,8 @@ public interface IArchiverTask extends Serializable * all scheduled data sets or null if processing succeeded for all datasets and no * additional information is provided. */ - ProcessingStatus archive(List<DatasetDescription> datasets, ArchiverTaskContext context); + ProcessingStatus archive(List<DatasetDescription> datasets, ArchiverTaskContext context, + boolean removeFromDataStore); /** * Asynchronously processes unarchiving of the specified datasets. @@ -45,4 +47,13 @@ public interface IArchiverTask extends Serializable * additional information is provided. */ ProcessingStatus unarchive(List<DatasetDescription> datasets, ArchiverTaskContext context); + + /** + * Delete data sets from the archive. + * + * @returns {@link ProcessingStatus} containing the deletion statuses for all data sets or null + * if processing succeeded for all datasets and no additional information is provided. + */ + ProcessingStatus deleteFromArchive(List<DatasetDescription> datasets, + ArchiverTaskContext context); } diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/tasks/PluginTaskProviders.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/tasks/PluginTaskProviders.java index 69358745be985d4849056fb4b6cdc95e1a198c1a..edc1b860e298249deee33bc416f5962a11991295 100644 --- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/tasks/PluginTaskProviders.java +++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/tasks/PluginTaskProviders.java @@ -48,7 +48,7 @@ public class PluginTaskProviders private final PluginTaskProvider<IProcessingPluginTask> processingPlugins; - private final ArchiverTaskFactory archiverTaskFactory; + private final ArchiverPluginFactory archiverTaskFactory; private final File storeRoot; @@ -92,7 +92,7 @@ public class PluginTaskProviders return processingPlugins; } - public ArchiverTaskFactory getArchiverTaskFactory() + public ArchiverPluginFactory getArchiverTaskFactory() { return archiverTaskFactory; } @@ -142,12 +142,12 @@ public class PluginTaskProviders return new PluginTaskProvider<IProcessingPluginTask>(factories); } - private ArchiverTaskFactory createArchiverTaskFactory(Properties serviceProperties, + private ArchiverPluginFactory createArchiverTaskFactory(Properties serviceProperties, String datastoreCode) { SectionProperties sectionsProperties = extractSingleSectionProperties(serviceProperties, ARCHIVER_SECTION_NAME); - return new ArchiverTaskFactory(sectionsProperties); + return new ArchiverPluginFactory(sectionsProperties); } private static SectionProperties[] extractSectionProperties(Properties serviceProperties, diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/IEncapsulatedOpenBISService.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/IEncapsulatedOpenBISService.java index a4d614fb8a83ae8f2b25e700b5d6eed1ea914a36..dc0ce6cbe570a8c9e8ffd1a9a0019607a4983590 100644 --- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/IEncapsulatedOpenBISService.java +++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/IEncapsulatedOpenBISService.java @@ -318,18 +318,22 @@ public interface IEncapsulatedOpenBISService public List<ExternalData> listAvailableDataSets(ArchiverDataSetCriteria criteria) throws UserFailureException; - /** See {@link IETLLIMSService#archiveDatasets(String, List)} */ + /** See {@link IETLLIMSService#archiveDatasets(String, List, boolean)} */ @ManagedAuthentication - public void archiveDataSets(List<String> dataSetCodes) throws UserFailureException; + public void archiveDataSets(List<String> dataSetCodes, boolean removeFromDataStore) + throws UserFailureException; /** See {@link IETLLIMSService#unarchiveDatasets(String, List)} */ @ManagedAuthentication public void unarchiveDataSets(List<String> dataSetCodes) throws UserFailureException; - /** See {@link IETLLIMSService#updateDataSetStatuses(String, List, DataSetArchivingStatus)} */ + /** + * See + * {@link IETLLIMSService#updateDataSetStatuses(String, List, DataSetArchivingStatus, boolean)} + */ @ManagedAuthentication - public void updateDataSetStatuses(List<String> codes, DataSetArchivingStatus newStatus) - throws UserFailureException; + public void updateDataSetStatuses(List<String> codes, DataSetArchivingStatus newStatus, + boolean presentInArchive) throws UserFailureException; /** See {@link IETLLIMSService#checkSpaceAccess(String, SpaceIdentifier)} */ @ManagedAuthentication diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/QueueingDataSetStatusUpdaterService.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/QueueingDataSetStatusUpdaterService.java index 3c8658f94643abfa7fc32259dad5b5f51b0baac7..5e58c902d90eacdc1302d9039cb57cd8d46380d3 100644 --- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/QueueingDataSetStatusUpdaterService.java +++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/QueueingDataSetStatusUpdaterService.java @@ -105,8 +105,8 @@ public class QueueingDataSetStatusUpdaterService final DataSetCodesWithStatus dataSets = queue.peekWait(); try { - updater.updateDataSetStatuses(dataSets.getDataSetCodes(), dataSets - .getStatus()); + updater.updateDataSetStatuses(dataSets.getDataSetCodes(), + dataSets.getStatus(), dataSets.isPresentInArchive()); // Note: this is the only consumer of this queue. queue.take(); // If update succeeded than it is possible that other updates @@ -158,10 +158,10 @@ public class QueueingDataSetStatusUpdaterService return new IDataSetStatusUpdater() { public void updateDataSetStatuses(List<String> dataSetCodes, - DataSetArchivingStatus newStatus) + DataSetArchivingStatus newStatus, boolean presentInArchive) { ServiceProvider.getOpenBISService().updateDataSetStatuses(dataSetCodes, - newStatus); + newStatus, presentInArchive); operationLog.info("Data Sets " + CollectionUtils.abbreviate(dataSetCodes, 10) + " changed status to " + newStatus); } @@ -310,9 +310,10 @@ public class QueueingDataSetStatusUpdaterService * * @param dataSetCodes codes of data sets to be updated * @param newStatus status to be set + * @param presentInArchive the present in archive flag to set */ public void updateDataSetStatuses(List<String> dataSetCodes, - DataSetArchivingStatus newStatus); + DataSetArchivingStatus newStatus, boolean presentInArchive); } } diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/dto/DataSetCodesWithStatus.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/dto/DataSetCodesWithStatus.java index 5a72c8ea7617d747370335ff304ee761f28ddc3f..c4a388c2272488028b363a0868ff17682656026d 100644 --- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/dto/DataSetCodesWithStatus.java +++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/dto/DataSetCodesWithStatus.java @@ -28,14 +28,18 @@ public class DataSetCodesWithStatus implements Serializable { private static final long serialVersionUID = 1L; - private List<String> dataSetCodes; + private final List<String> dataSetCodes; - private DataSetArchivingStatus status; + private final DataSetArchivingStatus status; - public DataSetCodesWithStatus(List<String> dataSetCodes, DataSetArchivingStatus status) + private final boolean presentInArchive; + + public DataSetCodesWithStatus(List<String> dataSetCodes, DataSetArchivingStatus status, + boolean presentInArchive) { this.dataSetCodes = dataSetCodes; this.status = status; + this.presentInArchive = presentInArchive; } public List<String> getDataSetCodes() @@ -48,6 +52,11 @@ public class DataSetCodesWithStatus implements Serializable return status; } + public boolean isPresentInArchive() + { + return presentInArchive; + } + @Override public String toString() { diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/AbstractCommonServer.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/AbstractCommonServer.java index 62c0fd1f111a8a875701aa1ffa0ada4ec1c8032e..e882b4d3f7853e81f0ec81670180f95dfb0d99f5 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/AbstractCommonServer.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/AbstractCommonServer.java @@ -91,13 +91,14 @@ abstract class AbstractCommonServer<T extends IServer> extends AbstractServer<T> } - public int archiveDatasets(String sessionToken, List<String> datasetCodes) + public int archiveDatasets(String sessionToken, List<String> datasetCodes, + boolean deleteFromDataStore) { Session session = getSession(sessionToken); IExternalDataTable externalDataTable = businessObjectFactory.createExternalDataTable(session); externalDataTable.loadByDataSetCodes(datasetCodes, false, true); - return externalDataTable.archiveDatasets(); + return externalDataTable.archiveDatasets(deleteFromDataStore); } public int unarchiveDatasets(String sessionToken, List<String> datasetCodes) diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/ETLService.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/ETLService.java index 9594114ea895eb2284aeb68ef24748fb80df7923..8d0243a6d26ac98920225897daf540eabaa4760d 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/ETLService.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/ETLService.java @@ -666,12 +666,12 @@ public class ETLService extends AbstractCommonServer<IETLService> implements IET } public void updateDataSetStatuses(String sessionToken, List<String> dataSetCodes, - DataSetArchivingStatus newStatus) throws UserFailureException + DataSetArchivingStatus newStatus, boolean presentInArchive) throws UserFailureException { assert sessionToken != null : "Unspecified session token."; final Session session = getSession(sessionToken); final IExternalDataBO externalDataBO = businessObjectFactory.createExternalDataBO(session); - externalDataBO.updateStatuses(dataSetCodes, newStatus); + externalDataBO.updateStatuses(dataSetCodes, newStatus, presentInArchive); } public ExternalData tryGetDataSet(String sessionToken, String dataSetCode) @@ -1075,4 +1075,5 @@ public class ETLService extends AbstractCommonServer<IETLService> implements IET return externalDataBO; } + } diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/ETLServiceLogger.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/ETLServiceLogger.java index 066d329df93d34a716b76a70a2dfcff8a62dba7f..1d1cb22c2478372e7e4fedc5cf6be18ed672ee86 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/ETLServiceLogger.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/ETLServiceLogger.java @@ -328,10 +328,11 @@ public class ETLServiceLogger extends AbstractServerLogger implements IETLServic } public void updateDataSetStatuses(String sessionToken, List<String> dataSetCodes, - DataSetArchivingStatus newStatus) throws UserFailureException + DataSetArchivingStatus newStatus, boolean presentInArchive) throws UserFailureException { - logTracking(sessionToken, "updateDataSetStatus", "NO_OF_DATASETS(%s) STATUS(%s)", - dataSetCodes.size(), newStatus); + logTracking(sessionToken, "updateDataSetStatus", + "NO_OF_DATASETS(%s) STATUS(%s) PRESENT_IN_ARCHIVE(%s)", dataSetCodes.size(), + newStatus, presentInArchive); } public String getDefaultPutDataStoreBaseURL(String sessionToken) diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/ExternalDataBO.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/ExternalDataBO.java index 877d5258e018ba0906c7f8132927d27fa5f3818a..2e5a18519f462830c54c497f845c1095c3c5d4d8 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/ExternalDataBO.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/ExternalDataBO.java @@ -683,9 +683,10 @@ public class ExternalDataBO extends AbstractExternalDataBusinessObject implement return result; } - public void updateStatuses(List<String> dataSetCodes, DataSetArchivingStatus newStatus) + public void updateStatuses(List<String> dataSetCodes, DataSetArchivingStatus newStatus, + boolean newPresentInArchive) { - getExternalDataDAO().updateDataSetStatuses(dataSetCodes, newStatus); + getExternalDataDAO().updateDataSetStatuses(dataSetCodes, newStatus, newPresentInArchive); } public void updateManagedProperty(IManagedProperty managedProperty) diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/ExternalDataTable.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/ExternalDataTable.java index 5496abcea42c4d853fb9bbfed686e9da10841c83..e35b9f9ed2c9a767899a26d5a96d84ea093f0dfb 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/ExternalDataTable.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/ExternalDataTable.java @@ -150,6 +150,25 @@ public final class ExternalDataTable extends AbstractExternalDataBusinessObject } } + private static void assertDatasetsAreDeletable(List<ExternalDataPE> datasets) + { + List<String> notDeletableDatasets = new ArrayList<String>(); + for (ExternalDataPE dataSet : datasets) + { + if (dataSet.getStatus().isDeletable() == false) + { + notDeletableDatasets.add(dataSet.getCode()); + } + } + if (notDeletableDatasets.isEmpty() == false) + { + throw UserFailureException.fromTemplate( + "Deletion failed because the following data sets are required " + + "by a background process (their status is pending): %s. ", + CollectionUtils.abbreviate(notDeletableDatasets, 10)); + } + } + private final IDataStoreServiceFactory dssFactory; private List<ExternalDataPE> externalData; @@ -205,7 +224,7 @@ public final class ExternalDataTable extends AbstractExternalDataBusinessObject public void deleteLoadedDataSets(String reason) { - assertDatasetsAreAvailable(externalData); + assertDatasetsAreDeletable(externalData); Map<DataStorePE, List<ExternalDataPE>> map = groupDataSetsByDataStores(); assertDataSetsAreKnown(map); for (Map.Entry<DataStorePE, List<ExternalDataPE>> entry : map.entrySet()) @@ -533,13 +552,13 @@ public final class ExternalDataTable extends AbstractExternalDataBusinessObject // Archiving // - public int archiveDatasets() + public int archiveDatasets(boolean removeFromDataStore) { Map<DataStorePE, List<ExternalDataPE>> datasetsByStore = groupDataSetsByDataStores(); int result = filterByStatusAndUpdate(datasetsByStore, DataSetArchivingStatus.AVAILABLE, DataSetArchivingStatus.ARCHIVE_PENDING); - performArchiving(datasetsByStore); + performArchiving(datasetsByStore, removeFromDataStore); return result; } @@ -615,14 +634,16 @@ public final class ExternalDataTable extends AbstractExternalDataBusinessObject } - private void performArchiving(Map<DataStorePE, List<ExternalDataPE>> datasetsByStore) + private void performArchiving(Map<DataStorePE, List<ExternalDataPE>> datasetsByStore, + final boolean removeFromDataStore) { performArchivingAction(datasetsByStore, new IArchivingAction() { public void execute(String sessionToken, IDataStoreService service, List<DatasetDescription> descriptions, String userEmailOrNull) { - service.archiveDatasets(sessionToken, descriptions, userEmailOrNull); + service.archiveDatasets(sessionToken, descriptions, userEmailOrNull, + removeFromDataStore); } }); } diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/IExternalDataBO.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/IExternalDataBO.java index 1f5cad12a4ff8637d2c2b5417232d29d926ef474..7b14087f03c85b69c3c3e3bcf3a1886c0d95bbf2 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/IExternalDataBO.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/IExternalDataBO.java @@ -73,8 +73,8 @@ public interface IExternalDataBO extends IEntityBusinessObject * * @throws UserFailureException if a data set does not exist or status couldn't be set. */ - public void updateStatuses(List<String> dataSetCodes, DataSetArchivingStatus newStatus) - throws UserFailureException; + public void updateStatuses(List<String> dataSetCodes, DataSetArchivingStatus newStatus, + boolean newPresentInArchive) throws UserFailureException; /** * Adds chosen properties to given data set. If given property has been already defined, the diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/IExternalDataTable.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/IExternalDataTable.java index ca35aa59b2dd7288edc72d3777357f3ec25ff99a..f85d26b1434408c604700c15d6064f1b7574f814 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/IExternalDataTable.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/IExternalDataTable.java @@ -79,9 +79,11 @@ public interface IExternalDataTable * Schedules archiving of loaded data sets. Only available data sets that are not locked will be * archived. * + * @param removeFromDataStore when set to <code>true</code> the data sets will be removed from + * the data store after a successful archiving operation. * @return number of data sets scheduled for archiving. */ - int archiveDatasets(); + int archiveDatasets(boolean removeFromDataStore); /** * Schedules unarchiving of loaded data sets. Only archived datasets will be unarchived. diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/datasetlister/DatasetLister.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/datasetlister/DatasetLister.java index 3a78ca7195cb514e218acb9b62069e468a803008..fdc337579e67622479ca2c55a4065c7b1656f1c3 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/datasetlister/DatasetLister.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/datasetlister/DatasetLister.java @@ -348,15 +348,16 @@ public class DatasetLister extends AbstractLister implements IDatasetLister final Long dataStoreId = extractDataStoreId(dataStoreCode); final Date lastRegistrationDate = extractLastRegistrationDate(criteria); final String dataSetTypeCodeOrNull = criteria.tryGetDataSetTypeCode(); + final boolean presentInArchive = criteria.isPresentInArchive(); if (dataSetTypeCodeOrNull == null) { return enrichDatasets(query.getAvailableDataSetsRegisteredBefore(dataStoreId, - lastRegistrationDate)); + lastRegistrationDate, presentInArchive)); } else { Long dataSetTypeId = extractDataSetTypeId(dataSetTypeCodeOrNull); return enrichDatasets(query.getAvailableDataSetsRegisteredBeforeWithDataSetType( - dataStoreId, lastRegistrationDate, dataSetTypeId)); + dataStoreId, lastRegistrationDate, presentInArchive, dataSetTypeId)); } } diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/datasetlister/IDatasetListingQuery.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/datasetlister/IDatasetListingQuery.java index 243944dc633cbc276a05cb2e54271fc88be58f78..ba8dd76616294ff3fe8a270e0148cae18cb76609 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/datasetlister/IDatasetListingQuery.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/datasetlister/IDatasetListingQuery.java @@ -86,19 +86,21 @@ public interface IDatasetListingQuery extends TransactionQuery, IPropertyListing */ @Select(sql = "SELECT * FROM data JOIN external_data ON data.id = external_data.data_id" + " WHERE data.dast_id = ?{1} AND external_data.status = 'AVAILABLE' " - + " AND data.registration_timestamp < ?{2}", fetchSize = FETCH_SIZE) + + " AND data.registration_timestamp < ?{2} AND external_data.present_in_archive=?{3}", fetchSize = FETCH_SIZE) public DataIterator<DatasetRecord> getAvailableDataSetsRegisteredBefore(long dataStoreId, - Date lastModificationDate); + Date lastModificationDate, boolean presentInArchive); /** - * Like {@link #getAvailableDataSetsRegisteredBefore(long, Date)} with additional condition for - * data set type id. + * Like {@link #getAvailableDataSetsRegisteredBefore(long, Date, boolean)} with additional + * condition for data set type id. */ @Select(sql = "SELECT * FROM data JOIN external_data ON data.id = external_data.data_id" + " WHERE data.dast_id = ?{1} AND external_data.status = 'AVAILABLE' " - + " AND data.registration_timestamp < ?{2} AND data.dsty_id = ?{3}", fetchSize = FETCH_SIZE) + + " AND data.registration_timestamp < ?{2} AND external_data.present_in_archive=?{3} " + + " AND data.dsty_id = ?{4}", fetchSize = FETCH_SIZE) public DataIterator<DatasetRecord> getAvailableDataSetsRegisteredBeforeWithDataSetType( - long dataStoreId, Date lastModificationDate, long dataSetTypeId); + long dataStoreId, Date lastModificationDate, boolean presentInArchive, + long dataSetTypeId); /** * Returns the directly connected dataset ids for the given sample id. diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/IExternalDataDAO.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/IExternalDataDAO.java index c3b76177cdd49b78ad0658f06ea67b6b7b9575c4..921112fe7687977ee569c0fb6e71ee25fc387b56 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/IExternalDataDAO.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/IExternalDataDAO.java @@ -61,6 +61,16 @@ public interface IExternalDataDAO extends IGenericDAO<ExternalDataPE> */ public List<ExternalDataPE> listExternalData(final SamplePE sample) throws DataAccessException; + // /** + // * List the all {@link ExternalDataPE} for given {@link DataSetArchivingStatus}. + // * + // * @param maxResultSize the maximum size of the returned list. Specifying a negative number + // * (e.g. -1) is equal to no limitation. + // * @returns list of {@link ExternalDataPE}s with the specified status. + // */ + // public List<ExternalDataPE> listByArchivingStatus(DataSetArchivingStatus status, + // int maxResultSize); + /** * List the {@link ExternalDataPE} for given <var>experiment</var>. * @@ -91,6 +101,12 @@ public interface IExternalDataDAO extends IGenericDAO<ExternalDataPE> */ public void updateDataSetStatuses(List<String> dataSetCodes, DataSetArchivingStatus status); + /** + * Updates the status and the present in archive flag for given datasets. + */ + public void updateDataSetStatuses(List<String> dataSetCodes, DataSetArchivingStatus status, + boolean newPresentInArchive); + /** * Persists the specified data set. */ diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/DatabaseVersionHolder.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/DatabaseVersionHolder.java index a694d582c9fb3506db977f0b89f54262786cb281..0e462471d2cd1cd1996b19f60aaad15a75c12716 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/DatabaseVersionHolder.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/DatabaseVersionHolder.java @@ -24,7 +24,7 @@ package ch.systemsx.cisd.openbis.generic.server.dataaccess.db; public final class DatabaseVersionHolder { /** Current version of the database. */ - private static final String DATABASE_VERSION = "066";// S100 + private static final String DATABASE_VERSION = "067";// S120 private DatabaseVersionHolder() { diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/ExternalDataDAO.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/ExternalDataDAO.java index 5f1e39cffd72a5186490a8e71271c36c97be935b..151a91058cdeb85fd3b7fea8eb8227fedc5846b3 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/ExternalDataDAO.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/ExternalDataDAO.java @@ -323,6 +323,54 @@ final class ExternalDataDAO extends AbstractGenericEntityWithPropertiesDAO<Exter } } + public void updateDataSetStatuses(final List<String> dataSetCodes, + final DataSetArchivingStatus status, final boolean presentInArchive) + { + assert dataSetCodes != null : "Unspecified data set codes"; + assert status != null : "Unspecified code"; + + if (dataSetCodes.size() == 0) + { + return; + } + + final HibernateTemplate hibernateTemplate = getHibernateTemplate(); + int updatedRows = (Integer) hibernateTemplate.execute(new HibernateCallback() + { + + // + // HibernateCallback + // + + public final Object doInHibernate(final Session session) throws HibernateException, + SQLException + { + // NOTE: 'VERSIONED' makes modification time modified too + return session + .createQuery( + "UPDATE VERSIONED " + TABLE_NAME + + " SET status = :status, isPresentInArchive = :presentInArchive" + + " WHERE code IN (:codes) ") + .setParameter("status", status) + .setParameter("presentInArchive", presentInArchive) + .setParameterList("codes", dataSetCodes) + .executeUpdate(); + } + }); + hibernateTemplate.flush(); + if (updatedRows != dataSetCodes.size()) + { + throw UserFailureException.fromTemplate( + "Update of %s data set statuses to '%s' and presentInArchive to '%s' failed.", + dataSetCodes.size(), status, presentInArchive); + } else if (operationLog.isInfoEnabled()) + { + operationLog.info(String.format( + "UPDATED: %s data set statuses to '%s' and presentInArchive flag to '%s'.", + dataSetCodes.size(), status, presentInArchive)); + } + } + public void createDataSet(DataPE dataset) { assert dataset != null : "Unspecified data set."; diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/AbstractServerLogger.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/AbstractServerLogger.java index 1ee8d178c7eebf67db4444c07531609264b9e2ca..84ba5738502cafa33af339d891b7743357a3dd55 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/AbstractServerLogger.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/AbstractServerLogger.java @@ -279,9 +279,11 @@ public abstract class AbstractServerLogger implements IServer return 0; } - public int archiveDatasets(String sessionToken, List<String> datasetCodes) + public int archiveDatasets(String sessionToken, List<String> datasetCodes, + boolean removeFromDataStore) { - logTracking(sessionToken, "archiveDatasets", "DATASETS(%s)", abbreviate(datasetCodes)); + logTracking(sessionToken, "archiveDatasets", "DATASETS(%s), REMOVE_FROM_DATA_STORE(%s)", + abbreviate(datasetCodes), removeFromDataStore); return 0; } } diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/ICommonServer.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/ICommonServer.java index 8726967c5cd586601c65f86f6d71fa7cfea551c9..610cec0ebf6e87149b9927ce7434d33935e8129e 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/ICommonServer.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/ICommonServer.java @@ -1016,6 +1016,8 @@ public interface ICommonServer extends IServer /** * Schedules archiving of specified data sets. * + * @param removeFromDataStore when set to <code>true</code> the data sets will be removed from + * the data store after a successful archiving operation. * @return number of data sets scheduled for archiving. */ @Transactional @@ -1023,7 +1025,8 @@ public interface ICommonServer extends IServer @DatabaseUpdateModification(value = ObjectKind.DATA_SET) public int archiveDatasets( String sessionToken, - @AuthorizationGuard(guardClass = DataSetCodeCollectionPredicate.class) List<String> datasetCodes); + @AuthorizationGuard(guardClass = DataSetCodeCollectionPredicate.class) List<String> datasetCodes, + boolean removeFromDataStore); /** * Schedules unarchiving of specified data sets. diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/IDataStoreService.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/IDataStoreService.java index 7cefba2da43268de1d4295f085dc98587796b2da..8fcce253dfca48b9914b9db178406157cfc6500a 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/IDataStoreService.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/IDataStoreService.java @@ -37,7 +37,7 @@ public interface IDataStoreService /** * Every time this interface and related DTO's are changed, we should increment this number. */ - public static final int VERSION = 5; // for release S77 + public static final int VERSION = 6; // for release 102 /** * Returns the version of this service. @@ -101,9 +101,11 @@ public interface IDataStoreService * @param userEmailOrNull Email of user who initiated archiving and will get a message after the * task is finished. It may be null if the user doesn't have email and no message * will be send in such case. + * @param removeFromDataStore when set to <code>true</code> the data sets will be removed from + * the data store after a successful archiving operation. */ public void archiveDatasets(String sessionToken, List<DatasetDescription> datasets, - String userEmailOrNull); + String userEmailOrNull, boolean removeFromDataStore); /** * Schedules unarchiving of provided datasets. diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/IETLLIMSService.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/IETLLIMSService.java index 8f546360b35748d9bdb6a64c59477bb264388411..5049423d96909295759e3aa956f963463d9bc269 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/IETLLIMSService.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/IETLLIMSService.java @@ -471,11 +471,14 @@ public interface IETLLIMSService extends IServer, ISessionProvider public void updateDataSetStatuses( String sessionToken, @AuthorizationGuard(guardClass = DataSetCodeCollectionPredicate.class) List<String> dataSetCodes, - final DataSetArchivingStatus newStatus) throws UserFailureException; + final DataSetArchivingStatus newStatus, boolean presentInArchive) + throws UserFailureException; /** * Schedules archiving of specified data sets. * + * @param removeFromDataStore when set to <code>true</code> the data sets will be removed from + * the data store after a successful archiving operation. * @return number of data sets scheduled for archiving. */ @Transactional @@ -483,7 +486,8 @@ public interface IETLLIMSService extends IServer, ISessionProvider @DatabaseUpdateModification(value = ObjectKind.DATA_SET) public int archiveDatasets( String sessionToken, - @AuthorizationGuard(guardClass = DataSetCodeCollectionPredicate.class) List<String> datasetCodes); + @AuthorizationGuard(guardClass = DataSetCodeCollectionPredicate.class) List<String> datasetCodes, + boolean removeFromDataStore); /** * Schedules unarchiving of specified data sets. diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/ArchiverDataSetCriteria.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/ArchiverDataSetCriteria.java index 5f8cbda74de9838e913efc57afb982198d6c82a4..e979267004215a20dca2d077b097548ba0d91106 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/ArchiverDataSetCriteria.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/ArchiverDataSetCriteria.java @@ -32,10 +32,14 @@ public class ArchiverDataSetCriteria implements Serializable private final String dataSetTypeCodeOrNull; - public ArchiverDataSetCriteria(int olderThan, String dataSetTypeCodeOrNull) + private final boolean presentInArchive; + + public ArchiverDataSetCriteria(int olderThan, String dataSetTypeCodeOrNull, + boolean presentInArchive) { this.olderThan = olderThan; this.dataSetTypeCodeOrNull = dataSetTypeCodeOrNull; + this.presentInArchive = presentInArchive; } public int getOlderThan() @@ -48,6 +52,11 @@ public class ArchiverDataSetCriteria implements Serializable return dataSetTypeCodeOrNull; } + public boolean isPresentInArchive() + { + return presentInArchive; + } + @Override public String toString() { diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/DataSetArchivingStatus.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/DataSetArchivingStatus.java index 87deb6853daf884f264898e6a9cfe3596c11ac80..bba72f525be549650345ac5f087d621f23b48482 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/DataSetArchivingStatus.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/DataSetArchivingStatus.java @@ -21,12 +21,34 @@ import com.google.gwt.user.client.rpc.IsSerializable; /** * Status of data set archiving process. * + * <pre> + * | + * archive + * ---------------> ARCHIVE_PENDING -------> ARCHIVED + * | | + * | | unarchive + * | | + * AVAILABLE <--------------------| | + * ^ | | + * | | V + * |------>LOCKED |----- UNARCHIVE_PENDING + * + * </pre> + * * @author Piotr Buczek */ public enum DataSetArchivingStatus implements IsSerializable { - AVAILABLE("AVAILABLE", true), LOCKED("AVAILABLE (LOCKED)", true), ARCHIVED("ARCHIVED", false), - UNARCHIVE_PENDING("UNARCHIVE PENDING", false), ARCHIVE_PENDING("ARCHIVE PENDING", false); + AVAILABLE("AVAILABLE", true), // the data set is present in the data store only + + // TODO KE: we might want to archive data sets in this state too + LOCKED("AVAILABLE (LOCKED)", true), + + ARCHIVED("ARCHIVED", false), // the data set is present in the archive only + + UNARCHIVE_PENDING("UNARCHIVE PENDING", false), + + ARCHIVE_PENDING("ARCHIVE PENDING", false); private final String description; @@ -48,4 +70,12 @@ public enum DataSetArchivingStatus implements IsSerializable return available; } + /** + * when deleting datasets from the archive + */ + public boolean isDeletable() + { + return isAvailable() || this == ARCHIVED; + } + } diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/ColumnNames.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/ColumnNames.java index 4201cc455ca1bf673b8484ce04c3f163fe9f623c..6c8a2d7eb3ca1619b9ec9a1cf11a7a12ef291260 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/ColumnNames.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/ColumnNames.java @@ -268,6 +268,8 @@ public final class ColumnNames public static final String SCRIPT_TYPE = "script_type"; + public static final String PRESENT_IN_ARCHIVE = "present_in_archive"; + private ColumnNames() { // Can not be instantiated. diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/ExternalDataPE.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/ExternalDataPE.java index 903451e034611a0ceaf44f5dc3898397f5a930a6..d04de6563265b2bed0c37b8d128fbd7210131b11 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/ExternalDataPE.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/ExternalDataPE.java @@ -77,6 +77,8 @@ public final class ExternalDataPE extends DataPE private DataSetArchivingStatus status = DataSetArchivingStatus.AVAILABLE; + private boolean isPresentInArchive; + /** * Returns the id of the locator type of the location of this external data, or * <code>null</code> if not yet set. @@ -207,4 +209,15 @@ public final class ExternalDataPE extends DataPE this.status = status; } + @Column(name = ColumnNames.PRESENT_IN_ARCHIVE) + public boolean isPresentInArchive() + { + return isPresentInArchive; + } + + public void setPresentInArchive(boolean isPresentInArchive) + { + this.isPresentInArchive = isPresentInArchive; + } + } diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/CommonServerTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/CommonServerTest.java index 8fbe2b05cad60158b1afc1e0a28a37c97b0d02d9..af278137a744baf0ca30ae5d4d1f91e359e5eede 100644 --- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/CommonServerTest.java +++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/CommonServerTest.java @@ -1408,6 +1408,7 @@ public final class CommonServerTest extends AbstractServerTestCase public void testArchiveDataSets() { prepareGetSession(); + final boolean removeFromDataStore = true; final List<String> dataSetCodes = Arrays.asList("a", "b"); context.checking(new Expectations() { @@ -1416,11 +1417,11 @@ public final class CommonServerTest extends AbstractServerTestCase will(returnValue(externalDataTable)); one(externalDataTable).loadByDataSetCodes(dataSetCodes, false, true); - one(externalDataTable).archiveDatasets(); + one(externalDataTable).archiveDatasets(removeFromDataStore); } }); - createServer().archiveDatasets(SESSION_TOKEN, dataSetCodes); + createServer().archiveDatasets(SESSION_TOKEN, dataSetCodes, removeFromDataStore); context.assertIsSatisfied(); } diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/ExternalDataBOTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/ExternalDataBOTest.java index 1abf7ae9f888f7ed8fc7ae5ef79f3a9fb9c14c3e..c48e5ed0d3120574d4510f191979eb541e2b1c14 100644 --- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/ExternalDataBOTest.java +++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/ExternalDataBOTest.java @@ -396,12 +396,12 @@ public class ExternalDataBOTest extends AbstractBOTest { { one(externalDataDAO).updateDataSetStatuses(codes, - DataSetArchivingStatus.ARCHIVED); + DataSetArchivingStatus.ARCHIVED, true); } }); IExternalDataBO dataBO = createExternalDataBO(); - dataBO.updateStatuses(codes, DataSetArchivingStatus.ARCHIVED); + dataBO.updateStatuses(codes, DataSetArchivingStatus.ARCHIVED, true); // TODO 2010-04-26, Piotr Buczek: write a DAO test context.assertIsSatisfied(); } diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/ExternalDataTableTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/ExternalDataTableTest.java index 67d525597763599975022b15befb266d56066fe1..056887d961265f019d094ef5720333afd17e513c 100644 --- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/ExternalDataTableTest.java +++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/ExternalDataTableTest.java @@ -295,10 +295,10 @@ public final class ExternalDataTableTest extends AbstractBOTest fail("UserFailureException expected"); } catch (UserFailureException e) { - assertEquals("Operation failed because following data sets are not available " - + "(they are archived or their status is pending): [d3n, d4n, d5n]. " - + "Unarchive these data sets or filter them out using data set status " - + "before performing the operation once again.", e.getMessage()); + + assertEquals("Deletion failed because the following data sets are " + + "required by a background process (their status is pending): " + + "[d4n, d5n]. ", e.getMessage()); } context.assertIsSatisfied(); @@ -568,7 +568,7 @@ public final class ExternalDataTableTest extends AbstractBOTest ExternalDataTable externalDataTable = createExternalDataTable(); externalDataTable.loadByDataSetCodes(Code.extractCodes(Arrays.asList(allDataSets)), false, true); - int archived = externalDataTable.archiveDatasets(); + int archived = externalDataTable.archiveDatasets(true); assertEquals(3, archived); context.assertIsSatisfied(); @@ -629,7 +629,8 @@ public final class ExternalDataTableTest extends AbstractBOTest { one(service).archiveDatasets(with(equal(store.getSessionToken())), with(createDatasetDescriptionsMatcher(dataSets)), - with(equal(ManagerTestTool.EXAMPLE_PERSON.getEmail()))); + with(equal(ManagerTestTool.EXAMPLE_PERSON.getEmail())), + with(equal(true))); } }); } diff --git a/rtd_yeastx/source/java/ch/systemsx/cisd/yeastx/etl/MLArchiverTask.java b/rtd_yeastx/source/java/ch/systemsx/cisd/yeastx/etl/MLArchiverTask.java index 22377aaa6bff3c5f74c560abb470c67f23747bcc..23dba3c5aa5ce74aa9eac7fa44ad0d8a4b624ed3 100644 --- a/rtd_yeastx/source/java/ch/systemsx/cisd/yeastx/etl/MLArchiverTask.java +++ b/rtd_yeastx/source/java/ch/systemsx/cisd/yeastx/etl/MLArchiverTask.java @@ -214,7 +214,8 @@ public class MLArchiverTask extends AbstractArchiverProcessingPlugin } @Override - public BooleanStatus isDataSetPresentInArchive(DatasetDescription dataset) + public BooleanStatus isDataSetPresentInArchive(DatasetDescription dataset, + ArchiverTaskContext context) { // data is always present, since there is no archive return BooleanStatus.createTrue();