diff --git a/datastore_server/source/java/ch/systemsx/cisd/etlserver/MaintenancePlugin.java b/datastore_server/source/java/ch/systemsx/cisd/etlserver/MaintenancePlugin.java index f03004c4cc93d74828f29097147ebf59011511e5..9c870437eced6aeb77b1e9413f4f7af855de8b25 100644 --- a/datastore_server/source/java/ch/systemsx/cisd/etlserver/MaintenancePlugin.java +++ b/datastore_server/source/java/ch/systemsx/cisd/etlserver/MaintenancePlugin.java @@ -21,8 +21,8 @@ public class MaintenancePlugin this.task = ClassUtils.create(IMaintenanceTask.class, parameters.getClassName()); } catch (Exception ex) { - throw new ConfigurationFailureException("Cannot find the plugin class '" + parameters.getClassName() - + "'", CheckedExceptionTunnel.unwrapIfNecessary(ex)); + throw new ConfigurationFailureException("Cannot find the plugin class '" + + parameters.getClassName() + "'", CheckedExceptionTunnel.unwrapIfNecessary(ex)); } task.setUp(parameters.getPluginName(), parameters.getProperties()); } @@ -38,6 +38,6 @@ public class MaintenancePlugin { task.execute(); } - }, 0L, parameters.getIntervalSeconds() * 1000); + }, parameters.getStartDate(), parameters.getIntervalSeconds() * 1000); } } \ No newline at end of file diff --git a/datastore_server/source/java/ch/systemsx/cisd/etlserver/MaintenanceTaskParameters.java b/datastore_server/source/java/ch/systemsx/cisd/etlserver/MaintenanceTaskParameters.java index 84c221445bc6f80fc0c778622bccaa3e2dc851d1..467131434950dbf5e55cffc46e2fd79a0d2bab54 100644 --- a/datastore_server/source/java/ch/systemsx/cisd/etlserver/MaintenanceTaskParameters.java +++ b/datastore_server/source/java/ch/systemsx/cisd/etlserver/MaintenanceTaskParameters.java @@ -16,8 +16,17 @@ package ch.systemsx.cisd.etlserver; +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; +import java.util.GregorianCalendar; import java.util.Properties; +import org.apache.commons.lang.StringUtils; + +import ch.systemsx.cisd.common.exceptions.ConfigurationFailureException; import ch.systemsx.cisd.common.utilities.PropertyUtils; /** @@ -25,12 +34,16 @@ import ch.systemsx.cisd.common.utilities.PropertyUtils; */ public class MaintenanceTaskParameters { + private static final String TIME_FORMAT = "hh:mm"; + private static final int ONE_DAY_IN_SEC = 60 * 60 * 24; private static final String CLASS_KEY = "class"; private static final String INTERVAL_KEY = "interval"; + private static final String START_KEY = "start"; + private final String pluginName; private final long interval; @@ -39,12 +52,44 @@ public class MaintenanceTaskParameters private final Properties properties; + private final Date startDate; + public MaintenanceTaskParameters(Properties properties, String pluginName) { this.properties = properties; this.pluginName = pluginName; interval = PropertyUtils.getLong(properties, INTERVAL_KEY, ONE_DAY_IN_SEC); className = PropertyUtils.getMandatoryProperty(properties, CLASS_KEY); + startDate = extractStartDate(PropertyUtils.getProperty(properties, START_KEY)); + } + + private static Date extractStartDate(String timeOrNull) + { + try + { + if (StringUtils.isBlank(timeOrNull)) + { + return GregorianCalendar.getInstance().getTime(); + } + DateFormat format = new SimpleDateFormat(TIME_FORMAT); + Date parsedDate = format.parse(timeOrNull); + Calendar rightHourAndMinutes1970 = GregorianCalendar.getInstance(); + rightHourAndMinutes1970.setTime(parsedDate); + Calendar result = GregorianCalendar.getInstance(); + result.set(Calendar.HOUR_OF_DAY, rightHourAndMinutes1970.get(Calendar.HOUR_OF_DAY)); + result.set(Calendar.MINUTE, rightHourAndMinutes1970.get(Calendar.MINUTE)); + Calendar now = GregorianCalendar.getInstance(); + if (now.after(result)) + { + result.add(Calendar.DAY_OF_MONTH, 1); + } + return result.getTime(); + } catch (ParseException ex) + { + throw new ConfigurationFailureException(String.format( + "Start date <%s> does not match the required format <%s>", timeOrNull, + TIME_FORMAT)); + } } public long getIntervalSeconds() @@ -66,4 +111,9 @@ public class MaintenanceTaskParameters { return properties; } + + public Date getStartDate() + { + return startDate; + } } 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 a0464ee807bfc0482333de6714991527edb2c7da..509af5bba2aa17c2527f38c20128e5fddf09dd86 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 @@ -21,6 +21,7 @@ import java.util.Properties; import ch.systemsx.cisd.common.exceptions.UserFailureException; import ch.systemsx.cisd.openbis.dss.generic.server.plugins.standard.AbstractArchiverProcessingPlugin; +import ch.systemsx.cisd.openbis.dss.generic.server.plugins.standard.HighWaterMarkChecker; import ch.systemsx.cisd.openbis.generic.shared.dto.DatasetDescription; /** @@ -32,7 +33,8 @@ public class DemoArchiver extends AbstractArchiverProcessingPlugin public DemoArchiver(Properties properties, File storeRoot) { - super(properties, storeRoot); + super(properties, storeRoot, new HighWaterMarkChecker(storeRoot), new HighWaterMarkChecker( + storeRoot)); } @Override 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 36b7ad43b30b71950c769c823c8f03996cf6c533..26b9b1b41e350ef74c371a908a348cd4d6b87117 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 @@ -38,7 +38,6 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.DatasetDescription; * * @author Piotr Buczek */ -// TODO 2010-03-19, PTR: check HighWaterMark public abstract class AbstractArchiverProcessingPlugin extends AbstractDatastorePlugin implements IArchiverTask { @@ -48,9 +47,16 @@ public abstract class AbstractArchiverProcessingPlugin extends AbstractDatastore private static final long serialVersionUID = 1L; - public AbstractArchiverProcessingPlugin(Properties properties, File storeRoot) + private final IStatusChecker archivePrerequisiteOrNull; + + private final IStatusChecker unarchivePrerequisiteOrNull; + + public AbstractArchiverProcessingPlugin(Properties properties, File storeRoot, + IStatusChecker archivePrerequisiteOrNull, IStatusChecker unarchivePrerequisiteOrNull) { super(properties, storeRoot); + this.archivePrerequisiteOrNull = archivePrerequisiteOrNull; + this.unarchivePrerequisiteOrNull = unarchivePrerequisiteOrNull; } abstract protected void archive(DatasetDescription dataset) throws UserFailureException; @@ -67,6 +73,14 @@ public abstract class AbstractArchiverProcessingPlugin extends AbstractDatastore public Status handle(DatasetDescription dataset) { + if (archivePrerequisiteOrNull != null) + { + Status status = archivePrerequisiteOrNull.check(); + if (status.isError()) + { + return status; + } + } try { archive(dataset); @@ -90,6 +104,14 @@ public abstract class AbstractArchiverProcessingPlugin extends AbstractDatastore public Status handle(DatasetDescription dataset) { + if (unarchivePrerequisiteOrNull != null) + { + Status status = unarchivePrerequisiteOrNull.check(); + if (status.isError()) + { + return status; + } + } try { unarchive(dataset); diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/standard/HighWaterMarkChecker.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/standard/HighWaterMarkChecker.java new file mode 100644 index 0000000000000000000000000000000000000000..6b3502ad5041cc62cb533cf6a28b6edbd98b84b0 --- /dev/null +++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/standard/HighWaterMarkChecker.java @@ -0,0 +1,62 @@ +package ch.systemsx.cisd.openbis.dss.generic.server.plugins.standard; + +import java.io.File; +import java.io.Serializable; + +import ch.systemsx.cisd.common.exceptions.Status; +import ch.systemsx.cisd.common.highwatermark.HighwaterMarkWatcher; +import ch.systemsx.cisd.common.highwatermark.HostAwareFile; +import ch.systemsx.cisd.common.highwatermark.HostAwareFileWithHighwaterMark; +import ch.systemsx.cisd.common.highwatermark.HighwaterMarkWatcher.HighwaterMarkState; +import ch.systemsx.cisd.common.utilities.PropertyUtils; +import ch.systemsx.cisd.openbis.dss.generic.shared.utils.PropertyParametersUtil; + +/** + * Checks if the space available is larger than specified value. + * + * @author Izabela Adamczyk + */ +public class HighWaterMarkChecker implements IStatusChecker, Serializable +{ + private static final long serialVersionUID = 1L; + + private final long highWaterMark; + + private final File highWaterMarkPath; + + /** + * Loads the high water mark value from global properties - + * {@link HostAwareFileWithHighwaterMark#HIGHWATER_MARK_PROPERTY_KEY}. + */ + public HighWaterMarkChecker(File path) + { + this(PropertyUtils.getLong(PropertyParametersUtil.loadServiceProperties(), + HostAwareFileWithHighwaterMark.HIGHWATER_MARK_PROPERTY_KEY, -1L), path); + } + + public HighWaterMarkChecker(long archiveHighWaterMark, File archiveHighWaterMarkPath) + { + this.highWaterMark = archiveHighWaterMark; + this.highWaterMarkPath = archiveHighWaterMarkPath; + } + + public Status check() + { + HighwaterMarkWatcher w = new HighwaterMarkWatcher(highWaterMark); + HighwaterMarkState state = w.getHighwaterMarkState(new HostAwareFile(highWaterMarkPath)); + if (HighwaterMarkWatcher.isBelow(state)) + { + String canonicalPath = highWaterMarkPath.getPath(); + String mark = HighwaterMarkWatcher.displayKilobyteValue(state.getHighwaterMark()); + String space = HighwaterMarkWatcher.displayKilobyteValue(state.getFreeSpace()); + String message = + String.format("Free space on '%s': %s, highwater mark: %s.", canonicalPath, + space, mark); + return Status.createError(message); + } else + { + return Status.OK; + } + + } +} \ No newline at end of file diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/standard/IStatusChecker.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/standard/IStatusChecker.java new file mode 100644 index 0000000000000000000000000000000000000000..ad708037c9fab46856675ac76400cd8ed722b13b --- /dev/null +++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/standard/IStatusChecker.java @@ -0,0 +1,13 @@ +package ch.systemsx.cisd.openbis.dss.generic.server.plugins.standard; + +import ch.systemsx.cisd.common.exceptions.Status; + +/** + * Checks the status. + * + * @author Izabela Adamczyk + */ +public interface IStatusChecker +{ + Status check(); +} \ No newline at end of file