From 61b67f57ac854903affc7dd6fefb9c8b7035e9b7 Mon Sep 17 00:00:00 2001 From: izabel <izabel> Date: Tue, 23 Mar 2010 20:25:35 +0000 Subject: [PATCH] [LMS-1452] use highwater mark; allow schedule at midnight SVN: 15240 --- .../cisd/etlserver/MaintenancePlugin.java | 6 +- .../etlserver/MaintenanceTaskParameters.java | 50 +++++++++++++++ .../server/plugins/demo/DemoArchiver.java | 4 +- .../AbstractArchiverProcessingPlugin.java | 26 +++++++- .../standard/HighWaterMarkChecker.java | 62 +++++++++++++++++++ .../plugins/standard/IStatusChecker.java | 13 ++++ 6 files changed, 155 insertions(+), 6 deletions(-) create mode 100644 datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/standard/HighWaterMarkChecker.java create mode 100644 datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/standard/IStatusChecker.java 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 f03004c4cc9..9c870437ece 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 84c221445bc..46713143495 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 a0464ee807b..509af5bba2a 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 36b7ad43b30..26b9b1b41e3 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 00000000000..6b3502ad504 --- /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 00000000000..ad708037c9f --- /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 -- GitLab