/*
* Copyright 2013-2014 the original author or authors.
*
* 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 de.codecentric.boot.admin.notify;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import org.springframework.util.Assert;
import de.codecentric.boot.admin.event.ClientApplicationDeregisteredEvent;
import de.codecentric.boot.admin.event.ClientApplicationEvent;
import de.codecentric.boot.admin.event.ClientApplicationStatusChangedEvent;
/**
* Notifier that reminds certain statuses to send reminder notification using a delegate.
*
* @author Johannes Edmeier
*/
public class RemindingNotifier extends AbstractEventNotifier {
private final ConcurrentHashMap<String, Reminder> reminders = new ConcurrentHashMap<>();
private long reminderPeriod = TimeUnit.MINUTES.toMillis(10L);
private String[] reminderStatuses = { "DOWN", "OFFLINE" };
private final Notifier delegate;
public RemindingNotifier(Notifier delegate) {
Assert.notNull(delegate, "'delegate' must not be null!");
this.delegate = delegate;
}
@Override
public void doNotify(ClientApplicationEvent event) {
delegate.notify(event);
if (shouldEndReminder(event)) {
reminders.remove(event.getApplication().getId());
} else if (shouldStartReminder(event)) {
reminders.putIfAbsent(event.getApplication().getId(), new Reminder(event));
}
}
public void sendReminders() {
long now = System.currentTimeMillis();
for (Reminder reminder : new ArrayList<>(reminders.values())) {
if (now - reminder.getLastNotification() > reminderPeriod) {
reminder.setLastNotification(now);
delegate.notify(reminder.getEvent());
}
}
}
protected boolean shouldStartReminder(ClientApplicationEvent event) {
if (event instanceof ClientApplicationStatusChangedEvent) {
return Arrays.binarySearch(reminderStatuses,
event.getApplication().getStatusInfo().getStatus()) >= 0;
}
return false;
}
protected boolean shouldEndReminder(ClientApplicationEvent event) {
if (event instanceof ClientApplicationDeregisteredEvent) {
return true;
}
if (event instanceof ClientApplicationStatusChangedEvent) {
return Arrays.binarySearch(reminderStatuses,
event.getApplication().getStatusInfo().getStatus()) < 0;
}
return false;
}
public void setReminderPeriod(long reminderPeriod) {
this.reminderPeriod = reminderPeriod;
}
public void setReminderStatuses(String[] reminderStatuses) {
String[] copy = Arrays.copyOf(reminderStatuses, reminderStatuses.length);
Arrays.sort(copy);
this.reminderStatuses = copy;
}
private static class Reminder {
private final ClientApplicationEvent event;
private long lastNotification;
private Reminder(ClientApplicationEvent event) {
this.event = event;
this.lastNotification = event.getTimestamp();
}
public void setLastNotification(long lastNotification) {
this.lastNotification = lastNotification;
}
public long getLastNotification() {
return lastNotification;
}
public ClientApplicationEvent getEvent() {
return event;
}
}
}