diff --git a/datastore_server/.gitignore b/datastore_server/.gitignore index ceb4ff050dac1cd6bea62f081f6ca7cbd6ed83e9..8cda29d94badd88336b075e2faeb141a419d0f6d 100644 --- a/datastore_server/.gitignore +++ b/datastore_server/.gitignore @@ -9,4 +9,4 @@ /clean-up-tasks /dss-tmp /log-registrations - +/core-plugins diff --git a/datastore_server/source/java/ch/systemsx/cisd/etlserver/ETLDaemon.java b/datastore_server/source/java/ch/systemsx/cisd/etlserver/ETLDaemon.java index edecf227bea56b3d4b84fdaae918270440a952f5..fbed2b8d7edb6850fcba6ddfcfdf2d504c42de76 100644 --- a/datastore_server/source/java/ch/systemsx/cisd/etlserver/ETLDaemon.java +++ b/datastore_server/source/java/ch/systemsx/cisd/etlserver/ETLDaemon.java @@ -56,6 +56,8 @@ import ch.systemsx.cisd.common.logging.LogCategory; import ch.systemsx.cisd.common.logging.LogFactory; import ch.systemsx.cisd.common.mail.IMailClient; import ch.systemsx.cisd.common.mail.MailClient; +import ch.systemsx.cisd.common.maintenance.MaintenancePlugin; +import ch.systemsx.cisd.common.maintenance.MaintenanceTaskParameters; import ch.systemsx.cisd.common.maintenance.MaintenanceTaskUtils; import ch.systemsx.cisd.common.utilities.ClassUtils; import ch.systemsx.cisd.common.utilities.IExitHandler; @@ -63,6 +65,7 @@ import ch.systemsx.cisd.common.utilities.ISelfTestable; import ch.systemsx.cisd.common.utilities.IStopSignaler; import ch.systemsx.cisd.common.utilities.PropertyUtils; import ch.systemsx.cisd.common.utilities.SystemExit; +import ch.systemsx.cisd.etlserver.postregistration.PostRegistrationMaintenanceTask; import ch.systemsx.cisd.etlserver.validation.DataSetValidator; import ch.systemsx.cisd.etlserver.validation.IDataSetValidator; import ch.systemsx.cisd.openbis.dss.BuildAndEnvironmentInfo; @@ -88,6 +91,8 @@ public final class ETLDaemon public static final File updaterQueueFile = new File(".updater"); + public static final int INJECTED_POST_REGISTRATION_TASK_INTERVAL = 1; + static final String NOTIFY_SUCCESSFUL_REGISTRATION = "notify-successful-registration"; private static final Logger operationLog = LogFactory.getLogger(LogCategory.OPERATION, @@ -606,10 +611,46 @@ public final class ETLDaemon } printInitialLogMessage(parameters); startupServer(parameters); - MaintenanceTaskUtils.startupMaintenancePlugins(parameters.getMaintenancePlugins()); + MaintenanceTaskParameters[] maintenancePlugins = parameters.getMaintenancePlugins(); + MaintenanceTaskUtils.startupMaintenancePlugins(maintenancePlugins); + injectPostRegistrationMaintenanceTaskIfNecessary(maintenancePlugins); + operationLog.info("Data Store Server ready and waiting for data."); } + /** + * In order for the post registration queue table in the database to be cleared, there must be a + * post registration maintenance task. + */ + private static void injectPostRegistrationMaintenanceTaskIfNecessary(MaintenanceTaskParameters[] maintenancePlugins) + { + boolean hasPostRegistrationMaintenanceTask = false; + for (MaintenanceTaskParameters task : maintenancePlugins) + { + if (PostRegistrationMaintenanceTask.class.getName().equals(task.getClassName())) + { + hasPostRegistrationMaintenanceTask = true; + } + } + + if (hasPostRegistrationMaintenanceTask) + { + // Nothing additional to do. + return; + } + + PostRegistrationMaintenanceTask task = new PostRegistrationMaintenanceTask(); + Properties props = new Properties(); + props.setProperty(MaintenanceTaskParameters.CLASS_KEY, task.getClass().getName()); + // Have the task run every second + props.setProperty(MaintenanceTaskParameters.INTERVAL_KEY, Integer.toString(INJECTED_POST_REGISTRATION_TASK_INTERVAL)); + MaintenanceTaskParameters parameters = new MaintenanceTaskParameters(props, "injected-post-registration-task"); + task.setUpEmpty(); + + MaintenancePlugin plugin = new MaintenancePlugin(task, parameters); + MaintenanceTaskUtils.injectMaintenancePlugin(plugin); + } + /** * Runs ETL Daemon for system testing: Replaces default {@link IExitHandler} by a one which * throws an {@link AssertionError}. diff --git a/datastore_server/source/java/ch/systemsx/cisd/etlserver/postregistration/PostRegistrationMaintenanceTask.java b/datastore_server/source/java/ch/systemsx/cisd/etlserver/postregistration/PostRegistrationMaintenanceTask.java index fd90cf74eeb12739ed978833318dd18005be2f40..dd4e7240b7b10d6d3d9d20f7e3790401a1adba88 100644 --- a/datastore_server/source/java/ch/systemsx/cisd/etlserver/postregistration/PostRegistrationMaintenanceTask.java +++ b/datastore_server/source/java/ch/systemsx/cisd/etlserver/postregistration/PostRegistrationMaintenanceTask.java @@ -46,7 +46,6 @@ import ch.systemsx.cisd.common.utilities.PropertyUtils; import ch.systemsx.cisd.openbis.dss.generic.shared.IEncapsulatedOpenBISService; import ch.systemsx.cisd.openbis.dss.generic.shared.ServiceProvider; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ExternalData; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.TrackingDataSetCriteria; /** * Maintenance task performing {@link IPostRegistrationTask}s. @@ -90,6 +89,9 @@ public class PostRegistrationMaintenanceTask implements IDataStoreLockingMainten public void setUp(String pluginName, Properties properties) { + // + // NB Changes to this method need to be reflected in setUpEmpty as well! + // service = ServiceProvider.getOpenBISService(); // Linked hash map because the task should be executed in the order of definition. Map<String, IPostRegistrationTask> map = new LinkedHashMap<String, IPostRegistrationTask>(); @@ -134,6 +136,24 @@ public class PostRegistrationMaintenanceTask implements IDataStoreLockingMainten } } + /** + * The PostRegistrationMaintenanceTask is a bit exceptional since it needs to be run even if it + * is not configured by the user. This method is used to set it up in that case. + */ + public void setUpEmpty() + { + service = ServiceProvider.getOpenBISService(); + // Linked hash map because the task should be executed in the order of definition. + Map<String, IPostRegistrationTask> map = new LinkedHashMap<String, IPostRegistrationTask>(); + needsLockOnDataStore = false; + tasks = map.entrySet(); + executor = new TaskExecutor(new Properties(), operationLog); + String fileName = DEFAULT_LAST_SEEN_DATA_SET_FILE; + lastSeenDataSetFile = new File(fileName); + newLastSeenDataSetFile = new File(fileName + ".new"); + ignoreBeforeDate = new Date(0); + } + public void execute() { executor.cleanup(); @@ -145,12 +165,12 @@ public class PostRegistrationMaintenanceTask implements IDataStoreLockingMainten { String lastRegisteredCode = FileUtilities.loadToString(lastSeenDataSetFile).trim(); - service.markSuccessfulPostRegistration(lastRegisteredCode); - deleteLastSeenDataSetId(); + service.markSuccessfulPostRegistration(lastRegisteredCode); + deleteLastSeenDataSetId(); } List<ExternalData> dataSets = getDataSetsForPostRegistration(); - + for (int i = 0; i < dataSets.size(); i++) { ExternalData dataSet = dataSets.get(i); @@ -184,7 +204,7 @@ public class PostRegistrationMaintenanceTask implements IDataStoreLockingMainten } /** - * @return List of datasets to process in post registration. Sorted by Id, incrementally. + * @return List of datasets to process in post registration. Sorted by Id, incrementally. */ private List<ExternalData> getDataSetsForPostRegistration() { @@ -212,7 +232,7 @@ public class PostRegistrationMaintenanceTask implements IDataStoreLockingMainten */ private void saveLastSeenDataSetId(String lastRegisteredDataSetCode) { - FileUtilities.writeToFile(newLastSeenDataSetFile,lastRegisteredDataSetCode); + FileUtilities.writeToFile(newLastSeenDataSetFile, lastRegisteredDataSetCode); newLastSeenDataSetFile.renameTo(lastSeenDataSetFile); } diff --git a/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/datastoreserver/systemtests/DssComponentTest.java b/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/datastoreserver/systemtests/DssComponentTest.java index 20a8963b02b659ba4f0c6f985c86d525a93b3173..b5a29af906c0b269d77c652507bdc96e2c480971 100644 --- a/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/datastoreserver/systemtests/DssComponentTest.java +++ b/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/datastoreserver/systemtests/DssComponentTest.java @@ -35,6 +35,7 @@ import org.testng.annotations.Test; import ch.systemsx.cisd.common.exceptions.AuthorizationFailureException; import ch.systemsx.cisd.common.filesystem.FileUtilities; import ch.systemsx.cisd.etlserver.DssRegistrationLogDirectoryHelper; +import ch.systemsx.cisd.etlserver.ETLDaemon; import ch.systemsx.cisd.openbis.dss.client.api.v1.DssComponentFactory; import ch.systemsx.cisd.openbis.dss.client.api.v1.IDataSetDss; import ch.systemsx.cisd.openbis.dss.client.api.v1.IDssComponent; @@ -351,6 +352,16 @@ public class DssComponentTest extends SystemTestCase assertEquals("hello world", getContent(dataSet, "data.log")); assertEquals("1 2 3", getContent(dataSet, "data/1.data")); assertEquals("4 5 6 7", getContent(dataSet, "data/2.data")); + + // Wait a bit for the maintenance task to run + try + { + Thread.sleep((ETLDaemon.INJECTED_POST_REGISTRATION_TASK_INTERVAL + 1) * 1000); + } catch (InterruptedException e) + { + } + IEncapsulatedOpenBISService openbisService = ServiceProvider.getOpenBISService(); + assertEquals(0, openbisService.listDataSetsForPostRegistration().size()); } private String getContent(IDataSetDss dataSet, String path) throws IOException