/* * Copyright (c) 2016 EMC Corporation * All Rights Reserved */ package com.emc.storageos.systemservices.impl.propertyhandler; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.emc.storageos.services.util.TimeUtils; import com.emc.storageos.management.backup.BackupConstants; import com.emc.storageos.model.property.PropertyInfoRestRep; import com.emc.storageos.svcs.errorhandling.resources.BadRequestException; import com.emc.storageos.systemservices.impl.jobs.backupscheduler.ScheduleTimeRange; import com.emc.storageos.systemservices.impl.jobs.backupscheduler.ScheduleTimeRange.ScheduleInterval; /** * This class serves as an extra validator for the backup related properties */ public class BackupConfigurationHandler extends DefaultUpdateHandler { private static final Logger _log = LoggerFactory.getLogger(BackupConfigurationHandler.class); private ScheduleInterval intervalUnit; private int intervalValue; private int startTime; /** * Check if backup related configurations conformed to rules, if not fail the property update. * * @param oldProps * @param newProps */ @Override public void before(PropertyInfoRestRep oldProps, PropertyInfoRestRep newProps) { String newIntervalStr = newProps.getProperty(BackupConstants.SCHEDULE_INTERVAL); String newStartTimeStr = newProps.getProperty(BackupConstants.SCHEDULE_TIME); if ((newIntervalStr == null || newIntervalStr.isEmpty()) && (newStartTimeStr == null || newStartTimeStr.isEmpty())){ _log.info("No changes in backup interval and start time"); return; } String intervalStr = (newIntervalStr == null || newIntervalStr.isEmpty()) ? oldProps.getProperty(BackupConstants.SCHEDULE_INTERVAL) : newIntervalStr; String startTimeStr = (newStartTimeStr == null || newStartTimeStr.isEmpty()) ? oldProps.getProperty(BackupConstants.SCHEDULE_TIME) : newStartTimeStr; _log.info("intervalStr={}, startTimeStr={}", intervalStr, startTimeStr); validateBackupIntervalAndStartTime(intervalStr, startTimeStr); } private void validateBackupInterval(String intervalStr) { if (intervalStr == null || intervalStr.isEmpty()) { _log.error("Backup interval string is null or empty"); throw BadRequestException.badRequests.backupIntervalIsInvalid(intervalStr); } // Format is ###$$$, where $$$ is interval unit, and ### represents times of the interval unit // E.g. "5day", ###=5, $$$=day. int digitLen = 0; while (Character.isDigit(intervalStr.charAt(digitLen))) { digitLen++; } String intervalValueStr = intervalStr.substring(0, digitLen); this.intervalValue = digitLen > 0 ? Integer.parseInt(intervalValueStr) : 0; if (this.intervalValue <= 0) { _log.error("The interval value({}) parsed from string({}) is invalid", intervalValueStr, intervalStr); throw BadRequestException.badRequests.backupIntervalIsInvalid(intervalStr); } String intervalUnitStr = intervalStr.substring(digitLen); try { this.intervalUnit = ScheduleTimeRange.parseInterval(intervalUnitStr); } catch (Exception ex) { _log.error("The interval unit({}) parsed from string({}) is invalid", intervalUnitStr, intervalStr); throw BadRequestException.badRequests.backupIntervalIsInvalid(intervalStr); } } private void validateBackupStartTime(String startTimeStr) { if (startTimeStr == null || startTimeStr.isEmpty()) { _log.error("Backup start time string is null or empty"); throw BadRequestException.badRequests.backupStartTimeIsInvalid(startTimeStr); } // Format is ...dddHHmm this.startTime = Integer.parseInt(startTimeStr); if (this.startTime < 0) { _log.error("The backup start time parsed from string({}) is invalid", startTime, startTimeStr); throw BadRequestException.badRequests.backupStartTimeIsInvalid(startTimeStr); } } private void validateBackupIntervalAndStartTime(String intervalStr, String startTimeStr) { boolean unsupportedInterval = false; boolean unsupportedStartTime = false; validateBackupInterval(intervalStr); validateBackupStartTime(startTimeStr); switch (intervalUnit) { case DAY: if (intervalValue != 1) { unsupportedInterval = true; } if (getStartTimeInMins(startTime) >= intervalValue * TimeUtils.DAYS/TimeUtils.MINUTES) { unsupportedStartTime = true; } break; case HOUR: if (intervalValue != 12) { unsupportedInterval = true; } if (getStartTimeInMins(startTime) >= intervalValue * TimeUtils.HOURS/TimeUtils.MINUTES) { unsupportedStartTime = true; } break; case MINUTE: if (intervalValue >= 60) { unsupportedInterval = true; _log.error("Please select proper unit, value should be less than 60 for unit MINUTE"); } else { _log.warn("Invalid scheduled backup interval left for internal test: {}", intervalStr); } if (getStartTimeInMins(startTime) >= intervalValue) { unsupportedStartTime = true; } break; default: unsupportedInterval = true; _log.error("Currently we just support scheduled backup interval unit as DAY or HOUR"); } if (unsupportedInterval) { _log.error("Invalid backup interval:{}, currently we only support '1day' and '12hour'", intervalStr); throw BadRequestException.badRequests.backupIntervalIsInvalid(intervalStr); } if (unsupportedStartTime) { _log.error("Start time({}) should be less than backup interval({})", startTimeStr, intervalStr); throw BadRequestException.badRequests.backupStartTimeIsInvalid(startTimeStr); } } private int getStartTimeInMins(int startTime) { int minute = startTime % 100; int startTimeInHour = startTime / 100; int hour = startTimeInHour % 100; int day = startTimeInHour / 100; return (day * 24 + hour) * 60 + minute; } /** * Do nothing * * @param oldProps * @param newProps */ @Override public void after(PropertyInfoRestRep oldProps, PropertyInfoRestRep newProps) { } }