package org.lightfish.business.escalation.boundary.notification.transmitters.comet;
import java.io.Writer;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.logging.Logger;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.ejb.LocalBean;
import javax.ejb.ScheduleExpression;
import javax.ejb.Singleton;
import javax.ejb.Startup;
import javax.ejb.Timeout;
import javax.ejb.Timer;
import javax.ejb.TimerService;
import javax.enterprise.event.Observes;
import javax.enterprise.inject.Instance;
import javax.inject.Inject;
import org.lightfish.business.escalation.boundary.notification.EscalationNotificationBroker;
import org.lightfish.business.escalation.entity.Notifier;
import org.lightfish.business.escalation.boundary.notification.NotifierStore;
import org.lightfish.business.escalation.boundary.notification.transmitter.Transmitter;
import org.lightfish.business.escalation.boundary.notification.transmitter.TransmitterType;
import org.lightfish.business.escalation.entity.Escalation;
import org.lightfish.business.heartbeat.control.Serializer;
import org.lightfish.presentation.publication.BrowserWindow;
import org.lightfish.presentation.publication.escalation.EscalationWindow;
import org.lightfish.presentation.publication.escalation.Escalations;
/**
*
* @author rveldpau
*/
@Singleton
@Startup
public class CometTransmitterDelegate {
public static Logger LOG = Logger.getLogger(CometTransmitterDelegate.class.getName());
private ConcurrentLinkedQueue<BrowserWindow> escalationBrowsers = new ConcurrentLinkedQueue<>();
private ConcurrentHashMap<String, Escalation> escalations = new ConcurrentHashMap<>();
@Inject
Serializer serializer;
@Resource
TimerService timerService;
@Inject
private Instance<Integer> interval;
@Inject
NotifierStore notificationStore;
@PostConstruct
public void initialize() {
startTimer();
persistDefaultConfiguration();
}
private void startTimer() {
ScheduleExpression expression = new ScheduleExpression();
expression.minute("*").second("*/" + interval.get()).hour("*");
timerService.createCalendarTimer(expression);
}
private void persistDefaultConfiguration() {
if (notificationStore.getNotifier("comet-escalator") == null) {
Notifier configuration = new Notifier.Builder()
.name("comet-escalator")
.transmitterId("comet")
.configuration(new CometTransmitterConfiguration())
.system(true)
.build();
notificationStore.save(configuration);
}
}
public void addEscalation(Escalation escalation) {
this.escalations.put(escalation.getChannel(), escalation);
}
public void onEscalationBrowserRequest(@Observes @EscalationWindow BrowserWindow browserWindow) {
escalationBrowsers.add(browserWindow);
}
@Timeout
public void notifyEscalationListeners() {
for (BrowserWindow browserWindow : escalationBrowsers) {
String channel = browserWindow.getChannel();
try {
if (channel != null && !channel.isEmpty()) {
Escalation snapshot = this.escalations.get(channel);
if (snapshot != null) {
sendToWindow(browserWindow, snapshot);
} else {
browserWindow.nothingToSay();
}
} else {
if (!this.escalations.isEmpty()) {
sendToWindow(browserWindow, new Escalations(this.escalations));
} else {
browserWindow.nothingToSay();
}
}
} finally {
escalationBrowsers.remove(browserWindow);
}
}
}
private void sendToWindow(BrowserWindow browserWindow, Escalation escalation) {
Writer writer = browserWindow.getWriter();
serializer.serialize(escalation, writer);
browserWindow.send();
}
void sendToWindow(BrowserWindow browserWindow, Escalations escalations) {
Writer writer = browserWindow.getWriter();
serializer.serialize(escalations, writer);
browserWindow.send();
}
}