Coverage Report - sk.baka.webvm.misc.NotificationDelivery
 
Classes in this File Line Coverage Branch Coverage Complexity
NotificationDelivery
30%
17/56
0%
0/28
2.538
NotificationDelivery$1
0%
0/2
N/A
2.538
NotificationDelivery$Notificator
85%
12/14
N/A
2.538
 
 1  
 /**
 2  
  * Copyright 2009 Martin Vysny.
 3  
  *
 4  
  * This file is part of WebVM.
 5  
  *
 6  
  * WebVM is free software: you can redistribute it and/or modify
 7  
  * it under the terms of the GNU General Public License as published by
 8  
  * the Free Software Foundation, either version 3 of the License, or
 9  
  * (at your option) any later version.
 10  
  *
 11  
  * WebVM is distributed in the hope that it will be useful,
 12  
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 13  
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 14  
  * GNU General Public License for more details.
 15  
  *
 16  
  * You should have received a copy of the GNU General Public License
 17  
  * along with WebVM.  If not, see <http://www.gnu.org/licenses/>.
 18  
  */
 19  
 package sk.baka.webvm.misc;
 20  
 
 21  
 import java.util.List;
 22  
 import java.util.StringTokenizer;
 23  
 import java.util.concurrent.BlockingQueue;
 24  
 import java.util.concurrent.LinkedBlockingQueue;
 25  
 import java.util.concurrent.ScheduledExecutorService;
 26  
 import java.util.logging.Level;
 27  
 import java.util.logging.Logger;
 28  
 import org.apache.commons.mail.Email;
 29  
 import org.apache.commons.mail.EmailException;
 30  
 import org.apache.commons.mail.HtmlEmail;
 31  
 import org.jivesoftware.smack.Chat;
 32  
 import org.jivesoftware.smack.MessageListener;
 33  
 import org.jivesoftware.smack.XMPPConnection;
 34  
 import org.jivesoftware.smack.XMPPException;
 35  
 import org.jivesoftware.smack.packet.Message;
 36  
 import sk.baka.webvm.analyzer.ProblemReport;
 37  
 import sk.baka.webvm.config.Config;
 38  
 
 39  
 /**
 40  
  * Delivers miscellaneous notifications (mail, jabber).
 41  
  * @author Martin Vysny
 42  
  */
 43  12
 public final class NotificationDelivery extends BackgroundService {
 44  
 
 45  
     /**
 46  
      * Creates new deliverer.
 47  
      */
 48  
     public NotificationDelivery() {
 49  2
         super("Notificator", 1);
 50  2
     }
 51  
 
 52  
     /**
 53  
      * Checks if sending mail is enabled in given config object.
 54  
      * @param config the configuration object
 55  
      * @return true if {@link Config#mailSmtpHost} is non-empty, false otherwise.
 56  
      */
 57  
     public static boolean isEmailEnabled(final Config config) {
 58  2
         return !isBlank(config.mailSmtpHost);
 59  
     }
 60  
 
 61  
     private static boolean isBlank(final String str) {
 62  0
         return str == null || str.trim().length() == 0;
 63  
     }
 64  
 
 65  
     /**
 66  
      * Checks if sending mail is enabled in given config object.
 67  
      * @param config the configuration object
 68  
      * @return true if {@link Config#mailSmtpHost} is non-empty, false otherwise.
 69  
      */
 70  
     public static boolean isJabberEnabled(final Config config) {
 71  2
         return !isBlank(config.jabberServer);
 72  
     }
 73  
 
 74  
     /**
 75  
      * Sends a mail with given report.
 76  
      * @param config the mail server configuration.
 77  
      * @param testing if true then a testing mail is sent
 78  
      * @param reports the current reports
 79  
      * @throws org.apache.commons.mail.EmailException if sending mail fails.
 80  
      */
 81  
     public static void sendEmail(final Config config, final boolean testing, final List<ProblemReport> reports) throws EmailException {
 82  2
         if (!isEmailEnabled(config)) {
 83  0
             return;
 84  
         }
 85  0
         final HtmlEmail mail = new HtmlEmail();
 86  0
         configure(mail, config);
 87  0
         mail.setSubject("WebVM: Problems notification" + (testing ? " (testing mail)" : ""));
 88  0
         mail.setMsg(ProblemReport.toString(reports, "\n"));
 89  0
         mail.setHtmlMsg("<html><body>\n" + ProblemReport.toHtml(reports) + "\n</body></html>");
 90  0
         mail.send();
 91  0
     }
 92  
 
 93  
     private static void configure(final Email mail, final Config config) throws EmailException {
 94  0
         mail.setHostName(config.mailSmtpHost);
 95  0
         config.mailSmtpEncryption.activate(mail);
 96  0
         if (config.mailSmtpPort > 0) {
 97  0
             if (mail.isSSL()) {
 98  0
                 mail.setSslSmtpPort(Integer.toString(config.mailSmtpPort));
 99  
             } else {
 100  0
                 mail.setSmtpPort(config.mailSmtpPort);
 101  
             }
 102  
         }
 103  0
         if (config.mailSmtpUsername != null) {
 104  0
             mail.setAuthentication(config.mailSmtpUsername, config.mailSmtpPassword);
 105  
         }
 106  0
         mail.setFrom(config.mailFrom);
 107  0
         if (config.mailTo == null) {
 108  0
             config.mailTo = "";
 109  
         }
 110  
         // add recipients
 111  0
         final StringTokenizer t = new StringTokenizer(config.mailTo, ",");
 112  0
         for (; t.hasMoreTokens();) {
 113  0
             mail.addTo(t.nextToken().trim());
 114  
         }
 115  0
     }
 116  
 
 117  
     /**
 118  
      * Sends a Jabber message with the Problems analysis.
 119  
      * @param config use this config.
 120  
      * @param testing if true then a (testing) string is appended to the message
 121  
      * @param reports use these reports
 122  
      * @throws org.jivesoftware.smack.XMPPException when send fails
 123  
      */
 124  
     public static void sendJabber(final Config config, final boolean testing, final List<ProblemReport> reports) throws XMPPException {
 125  2
         if (!isJabberEnabled(config)) {
 126  0
             return;
 127  
         }
 128  0
         XMPPConnection connection = new XMPPConnection(config.jabberServer);
 129  0
         connection.connect();
 130  
         try {
 131  0
             connection.login(config.jabberUsername, config.jabberPassword);
 132  0
             final StringTokenizer t = new StringTokenizer(config.jabberRecipients, ",");
 133  0
             for (; t.hasMoreTokens();) {
 134  0
                 final String recipient = t.nextToken().trim();
 135  0
                 final Chat chat = connection.getChatManager().createChat(recipient, "WebVM", new MessageListener() {
 136  
 
 137  
                     public void processMessage(Chat chat, Message message) {
 138  
                         // do nothing
 139  0
                     }
 140  
                 });
 141  0
                 chat.sendMessage("WebVM Problems report: " + (testing ? "(testing)" : "") + "\n" + ProblemReport.toString(reports, "\n"));
 142  0
             }
 143  
         } finally {
 144  0
             connection.disconnect();
 145  0
         }
 146  0
     }
 147  
 
 148  
     /**
 149  
      * Delivers given report asynchronously.
 150  
      * @param reports the reports to deliver.
 151  
      */
 152  
     public void deliverAsync(final List<ProblemReport> reports) {
 153  
         try {
 154  2
             asyncQueue.put(reports);
 155  0
         } catch (InterruptedException ex) {
 156  
             // we do not have a space-bound queue
 157  0
             throw new AssertionError(ex);
 158  2
         }
 159  2
     }
 160  2
     private final BlockingQueue<List<ProblemReport>> asyncQueue = new LinkedBlockingQueue<List<ProblemReport>>();
 161  
 
 162  
     @Override
 163  
     protected void started(ScheduledExecutorService executor) {
 164  2
         executor.execute(new Notificator());
 165  2
     }
 166  
     private volatile Config config;
 167  
 
 168  
     /**
 169  
      * Sets the new configuration file.
 170  
      * @param config the new config file.
 171  
      */
 172  
     public void configure(final Config config) {
 173  1
         this.config = new Config(config);
 174  1
     }
 175  
 
 176  
     @Override
 177  
     protected void stopped() {
 178  
         // do nothing
 179  1
     }
 180  
 
 181  4
     private class Notificator implements Runnable {
 182  
 
 183  
         public void run() {
 184  
             while (true) {
 185  
                 final List<ProblemReport> reports;
 186  
                 try {
 187  4
                     reports = asyncQueue.take();
 188  1
                 } catch (InterruptedException ex) {
 189  
                     // we are terminating.
 190  1
                     return;
 191  2
                 }
 192  
                 try {
 193  2
                     NotificationDelivery.sendEmail(config, false, reports);
 194  2
                 } catch (Exception ex) {
 195  2
                     LOG.log(Level.SEVERE, "Failed to send email", ex);
 196  0
                 }
 197  
                 try {
 198  2
                     NotificationDelivery.sendJabber(config, false, reports);
 199  2
                 } catch (Exception ex) {
 200  2
                     LOG.log(Level.SEVERE, "Failed to send jabber message", ex);
 201  0
                 }
 202  2
             }
 203  
         }
 204  
     }
 205  1
     private static final Logger LOG = Logger.getLogger(NotificationDelivery.class.getName());
 206  
 }