/* * Created on May 16, 2004 * * To change the template for this generated file go to * Window>Preferences>Java>Code Generation>Code and Comments */ package net.reliableresponse.notification.actions; import java.util.Date; import java.util.Hashtable; import java.util.Vector; import net.reliableresponse.notification.Notification; import net.reliableresponse.notification.NotificationException; import net.reliableresponse.notification.NotificationMessage; import net.reliableresponse.notification.aggregation.Squelcher; import net.reliableresponse.notification.broker.BrokerFactory; import net.reliableresponse.notification.device.Device; import net.reliableresponse.notification.providers.NotificationProvider; import net.reliableresponse.notification.providers.ProviderStatusLoop; import net.reliableresponse.notification.usermgmt.BroadcastGroup; import net.reliableresponse.notification.usermgmt.Group; import net.reliableresponse.notification.usermgmt.Member; import net.reliableresponse.notification.usermgmt.OnCallGroup; import net.reliableresponse.notification.usermgmt.User; /** * @author drig * * To change the template for this generated type comment go to * Window>Preferences>Java>Code Generation>Code and Comments */ public class SendNotification { private static SendNotification sendPage; public static SendNotification getInstance() { if (sendPage == null) { sendPage = new SendNotification(); } return sendPage; } private void doSend(Notification notification, Member member) throws NotificationException { if (notification.isPersistent()) { try { BrokerFactory.getNotificationBroker().addNotification( notification); } catch (Exception anyExc) { BrokerFactory.getLoggingBroker().logWarn(anyExc); } try { BrokerFactory.getNotificationBroker().setNotificationStatus( notification, "pending"); } catch (Exception anyExc) { BrokerFactory.getLoggingBroker().logWarn(anyExc); } if (Squelcher.isSquelched(notification.getChildSentToThisUser(member))) { BrokerFactory.getLoggingBroker().logDebug(notification.getUuid()+" is squelched"); notification.setStatus(Notification.ONHOLD); notification.addMessage("Notification squelched", null); } } if (member.getType() == Member.USER) { User user = (User) member; Device[] devices = notification.getDevices(); BrokerFactory.getLoggingBroker().logDebug("Sending notification to "+member+" with "+devices.length+" devices"); for (int i = 0; i < devices.length; i++) { if (devices[i].willSend(user, notification.getUltimateParent().getPriority(), notification)) { NotificationProvider provider = devices[i] .getNotificationProvider(); Hashtable<String, String> params = new Hashtable<String, String>(); try { try { BrokerFactory.getLoggingBroker().logInfo( "Sending notification to " + user + " via " + provider); } catch (Exception anyExc) { BrokerFactory.getLoggingBroker().logWarn(anyExc); } notification.addNotificationProvider(provider); provider.setStatusOfSend(notification, "succeeded"); params = provider.sendNotification(notification, devices[i]); if (notification.isPersistent()) { ProviderStatusLoop.getInstance().addNotification(notification); BrokerFactory.getNotificationBroker() .addProviderInformation(notification, provider, params, "succeeded"); BrokerFactory.getNotificationLoggingBroker() .logNotification(notification, notification.getRecipient(), devices[i], "succeeded"); } notification.addMessage("Notification delivered to " + notification.getRecipient().toString() + " via device " + devices[i].toString(), null, NotificationMessage.NOTIFICATION_CONTENT_TYPE); } catch (NotificationException nfExc) { // Check to see if it's a temporary failure if ((nfExc.getCode() >= 300) && (nfExc.getCode()<400)) { FailedNotificationThread.getInstance().addNotification(new FailedNotification(notification, devices[i], provider, user)); SendNotification.flagError(notification, devices[i], provider, nfExc, "temporarily failed"); } else { SendNotification.flagError(notification, devices[i], provider, nfExc, "failed"); } } catch (Exception anyExc) { SendNotification.flagError(notification, devices[i], provider, anyExc, "failed"); } } else { BrokerFactory.getLoggingBroker().logInfo( "Not sending notification to " + user + " via " + devices[i] + " because the priority blocks it"); notification.addMessage( "Not sending notification to " + user + " via " + devices[i] + " because the priority blocks it", null); } } BrokerFactory.getNotificationBroker().setNotificationStatus( notification, "sent"); } else { // Recurse into the group Notification sendPage = new Notification(notification.getUuid(), member, notification.getSender(), notification.getSubject(), notification.getMessages()); int priority = notification.getPriority(); sendPage.setPriority(priority); sendPage.setRequireConfirmation(notification .isRequireConfirmation()); sendPage.setIncludeTimestamp(notification.isIncludeTimestamp()); for (int i = 0; i < notification.getOptions().size(); i++) { sendPage.addOption((String) notification.getOptions() .elementAt(i)); } doSend(sendPage); } } /** * @param notification * @param devices * @param i * @param provider * @param anyExc */ public static void flagError(Notification notification, Device device, NotificationProvider provider, Exception anyExc, String status) { Hashtable<String, String> params; if (notification.isPersistent()) { BrokerFactory.getNotificationLoggingBroker() .logNotification(notification, notification.getRecipient(), device, status); BrokerFactory.getLoggingBroker() .logAction( "Notification not sent to " + provider + " because " + anyExc.getMessage()); params = provider.getParameters(notification, device); BrokerFactory.getNotificationBroker() .addProviderInformation(notification, provider, params, status); } provider.setStatusOfSend(notification, status); anyExc.printStackTrace(); NotificationMessage errorMessage = new NotificationMessage( "ERROR Sending to " + device + "\n\n" + anyExc.getMessage(), "system", new Date()); notification.addMessage(errorMessage); } /** * Tells this class to send the notification * * @return The IDs of the messages sent */ public void doSend(Notification notification) throws NotificationException { Member recipient = notification.getRecipient(); if (!EventStormManager.getInstance().willSend(notification)) { return; } if (recipient.getType() == Member.BROADCAST) { if (notification.isPersistent()) { BrokerFactory.getNotificationBroker().addNotification(notification); } Member[] members = ((BroadcastGroup) recipient).getMembers(); for (int memNum = 0; memNum < members.length; memNum++) { Notification directNotification = new Notification(notification .getUuid(), members[memNum], notification.getSender(), notification.getSubject(), notification.getMessages()); directNotification.setPersistent(notification.isPersistent()); int priority = notification.getPriority(); if (members[memNum].getType() == Member.USER) { priority = BrokerFactory.getUserMgmtBroker() .getPriorityOfGroup((User) members[memNum], (Group) recipient); } directNotification.setPriority(priority); doSend(directNotification, members[memNum]); } } else if (recipient.getType() == Member.ESCALATION) { if (notification.isPersistent()) { BrokerFactory.getNotificationBroker().addNotification( notification); BrokerFactory.getNotificationBroker().setNotificationStatus( notification, "sent"); EscalationThreadManager.getInstance().addEscalation( notification); } else { doSend(notification, recipient); } } else if (recipient.getType() == Member.ONCALL) { if (notification.isPersistent()) { BrokerFactory.getNotificationBroker().addNotification(notification); } Member[] members = ((OnCallGroup)recipient).getOnCallMembers(new Date()); for (int memNum = 0; memNum < members.length; memNum++) { Notification directNotification = new Notification(notification .getUuid(), members[memNum], notification.getSender(), notification.getSubject(), notification.getMessages()); directNotification.setPersistent(notification.isPersistent()); int priority = notification.getPriority(); if (members[memNum].getType() == Member.USER) { priority = BrokerFactory.getUserMgmtBroker() .getPriorityOfGroup((User) members[memNum], (Group) recipient); } directNotification.setPriority(priority); doSend(directNotification, members[memNum]); } } else if (recipient.getType() == Member.USER) { doSend(notification, recipient); } } public static void addFailedNotification (Notification notification, Device device, NotificationProvider provider, User user) { FailedNotification failedNotif = new FailedNotification(notification, device, provider, user); FailedNotificationThread.getInstance().addNotification(failedNotif); } } class FailedNotificationThread extends Thread { private Vector<FailedNotification> failedNotifications; private static FailedNotificationThread instance = null; private FailedNotificationThread() { failedNotifications = new Vector<FailedNotification>(); } public void addNotification (FailedNotification notification) { BrokerFactory.getLoggingBroker().logDebug("Adding failed notification to retry thread: "+notification.getNotification().getUuid()); failedNotifications.addElement(notification); } public static FailedNotificationThread getInstance() { if (instance == null) { instance = new FailedNotificationThread(); instance.start(); } return instance; } public void run() { while (true) { // Run once a minute try { Thread.sleep(60*1000); } catch (InterruptedException e) { BrokerFactory.getLoggingBroker().logWarn(e); } BrokerFactory.getLoggingBroker().logDebug("Running Failed Notification thread on "+failedNotifications.size()+" notifs"); for (int n = 0; n < failedNotifications.size(); n++) { FailedNotification failedNotification = (FailedNotification)failedNotifications.elementAt(n); Device device = failedNotification.getDevice(); Notification oldNotification = failedNotification.getNotification(); Vector<Device> deviceToSendTo = new Vector<Device>(); deviceToSendTo.addElement(device); Notification notification = new Notification(oldNotification.getUuid(), failedNotification.getUser(), deviceToSendTo, oldNotification.getSender(), oldNotification.getSubject(), oldNotification.getMessages()[0].getMessage()); notification.setPersistent(false); BrokerFactory.getLoggingBroker().logDebug("Resending "+notification); NotificationProvider provider = failedNotification.getProvider(); User user = failedNotification.getUser(); if (device.willSend(user, notification.getPriority(), notification)) { Hashtable<String, String> params = new Hashtable<String, String>(); try { try { BrokerFactory.getLoggingBroker().logInfo( "Sending notification to " + user + " via " + provider); } catch (Exception anyExc) { BrokerFactory.getLoggingBroker().logWarn(anyExc); } params = provider.sendNotification(notification, device); provider.setStatusOfSend(notification, "succeeded"); if (notification.isPersistent()) { ProviderStatusLoop.getInstance().addNotification(notification); BrokerFactory.getNotificationBroker() .addProviderInformation(notification, provider, params, "succeeded"); BrokerFactory.getNotificationLoggingBroker() .logNotification(notification, notification.getRecipient(), device, "succeeded"); } notification.addMessage("Notification delivered to " + notification.getRecipient().toString() + " via device " + device.toString(), null); failedNotifications.removeElementAt(n); } catch (NotificationException nfExc) { // Check to see if it's a temporary failure if ((nfExc.getCode() >= 300) && (nfExc.getCode()<400)) { SendNotification.flagError(notification, device, provider, nfExc, "temporarily failed"); } else { SendNotification.flagError(notification, device, provider, nfExc, "failed"); failedNotifications.removeElementAt(n); } } catch (Exception anyExc) { SendNotification.flagError(notification, device, provider, anyExc, "failed"); } } else { BrokerFactory.getLoggingBroker().logInfo( "Not sending notification to " + user + " via " + device + " because the priority blocks it"); } } } } } class FailedNotification { long time; Notification notification; Device device; NotificationProvider provider; int retryCount; User user; public FailedNotification (Notification notification, Device device, NotificationProvider provider, User user) { this.time = System.currentTimeMillis(); this.notification = notification; this.device = device; this.provider = provider; this.retryCount = 0; this.user = user; } public boolean doRetry() { return doRetry(BrokerFactory.getConfigurationBroker().getIntValue("notification.retryseconds", 10*60)); } public boolean doRetry(int seconds) { long now = System.currentTimeMillis(); long difference = now - time; difference = difference/1000; if (difference > seconds) { retryCount++; return true; } return false; } public Device getDevice() { return device; } public void setDevice(Device device) { this.device = device; } public Notification getNotification() { return notification; } public void setNotification(Notification notification) { this.notification = notification; } public NotificationProvider getProvider() { return provider; } public void setProvider(NotificationProvider provider) { this.provider = provider; } public int getRetryCount() { return retryCount; } public void setRetryCount(int retryCount) { this.retryCount = retryCount; } public long getTime() { return time; } public void setTime(long time) { this.time = time; } public User getUser() { return user; } public void setUser(User user) { this.user = user; } }