/**
* Copyright (c) Istituto Nazionale di Fisica Nucleare (INFN). 2006-2016
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.glite.security.voms.admin.notification;
import java.util.Date;
import java.util.concurrent.TimeUnit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* This strategy sends out notifications based on an expiration time and a set
* of intervals calculated before that expiration time according to a
* {@link TimeUnit}.
*
* As an example, given an expiration time, time unit set to
* {@link TimeUnit#DAYS}, and "5,3,1" as the warning times, notifications will
* be sent out 5, 3, and 1 days before the expiration time.
*
* Of course the notification must be triggered by an external thread using the
* {@link #sendNotification} method.
*
* The {@link #notificationRequired} method will return a {@link Boolean}
* telling if a call to {@link #sendNotification} would result in a notification
* being sent.
*
* @author andreaceccanti
*
*/
public class WarningsBeforeExpirationNotificationStrategy extends
BaseConditionalNotificationStrategy {
private static final Logger log = LoggerFactory
.getLogger(WarningsBeforeExpirationNotificationStrategy.class);
private static final TimeUnit DEFAULT_TIME_UNIT = TimeUnit.DAYS;
private TimeUnit timeUnit = DEFAULT_TIME_UNIT;
private long expirationTime;
private int[] warningTimes;
private void sanityChecks() {
if (warningTimes.length == 0)
throw new IllegalArgumentException("Warning times should not be empty.");
for (int t : warningTimes) {
if (t <= 0)
throw new IllegalArgumentException(
"Warning times should be positive integers! '" + t + "' <= 0,");
}
long now = System.currentTimeMillis();
if (expirationTime < now)
throw new IllegalArgumentException("Expiration time is in the past!");
}
public WarningsBeforeExpirationNotificationStrategy(
NotificationTimeStorage timeStorage,
NotificationServiceIF notificationService, int[] warningTimes,
TimeUnit warningUnit, long expirationTime) {
super(timeStorage, notificationService);
this.warningTimes = warningTimes;
this.timeUnit = warningUnit;
this.expirationTime = expirationTime;
sanityChecks();
}
private long getNextNotificationMessageTime() {
for (int t : warningTimes) {
long nextWarningTime = expirationTime - timeUnit.toMillis(t);
if (nextWarningTime < 0)
new IllegalArgumentException("Please set the time "
+ "unit and expiration time for this strategy correctly!");
if (notificationTimeStorage.getLastNotificationTime() > nextWarningTime)
continue;
return nextWarningTime;
}
return 0L;
}
@Override
public boolean notificationRequired() {
if (notificationTimeStorage.getLastNotificationTime() == 0) {
return true;
}
long now = new Date().getTime();
if (now > expirationTime) {
log.debug("No notification required. Expiration time reached.");
return false;
}
long nextWarningTime = getNextNotificationMessageTime();
if (now >= nextWarningTime
&& notificationTimeStorage.getLastNotificationTime() < nextWarningTime) {
if (log.isDebugEnabled()) {
log.debug("Notification required. "
+ "Last notification time: {} Now: {} Next warning time: {}",
new Object[] { notificationTimeStorage.getLastNotificationTime(),
now, nextWarningTime });
}
return true;
}
log.debug("No notification required.");
return false;
}
/**
* @return the timeUnit
*/
public TimeUnit getTimeUnit() {
return timeUnit;
}
/**
* @param timeUnit
* the timeUnit to set
*/
public void setTimeUnit(TimeUnit timeUnit) {
this.timeUnit = timeUnit;
}
}