001    package tynamo_watchdog;
002    
003    import java.io.IOException;
004    import java.util.ArrayList;
005    import java.util.Arrays;
006    import java.util.Date;
007    import java.util.List;
008    import java.util.Properties;
009    
010    import javax.mail.Message;
011    import javax.mail.MessagingException;
012    import javax.mail.Session;
013    import javax.mail.Transport;
014    import javax.mail.internet.InternetAddress;
015    import javax.mail.internet.MimeMessage;
016    
017    public class Watchdog {
018            public static final String SMTP_HOST = "smtp.host";
019            public static final String SMTP_PORT = "smtp.port";
020            public static final String SEND_EMAIL = "watchdog.sendemail";
021            public static final String EMAIL_PATH = "watchdog.emailpath";
022            public static final String COMMAND = "watchdog.command";
023    
024            public static final String STOP_MESSAGE = Watchdog.class.getSimpleName();
025    
026            private String emailRecipient;
027            private String smtpHost;
028            private Integer smtpPort;
029            private String appName;
030            private String hostname;
031    
032            public Watchdog(String appName, String emailRecipient, String smtpHost, String smtpPort) {
033                    this.appName = appName;
034                    this.emailRecipient = emailRecipient;
035                    this.smtpHost = smtpHost;
036                    // FIXME catch numberFormatException
037                    this.smtpPort = smtpPort == null ? null : Integer.valueOf(smtpPort);
038                    hostname = System.getenv("HOSTNAME");
039                    if (hostname == null) hostname = "localhost.localdomain";
040            }
041    
042            public static void main(String[] args) throws Exception {
043                    // With no arguments, print out the help and exit
044                    List<String> arguments = new ArrayList<String>(Arrays.asList(args));
045    
046                    if (args.length <= 0 || arguments.contains("--help")) {
047                            System.out.println("Tynamo watchdog. This application is designed to run as a child process ");
048                            return;
049                    }
050    
051                    String appName = args.length > 0 ? args[0] : "dev/exploded";
052                    Thread.sleep(5000);
053                    int available = 0;
054                    byte[] bytes = new byte[STOP_MESSAGE.getBytes().length];
055                    try {
056                            while ((available = System.in.available()) > 0) {
057                                    if (available >= STOP_MESSAGE.getBytes().length) System.exit(0);
058                                    // skip() didn't seem to work for standard input
059                                    System.in.read(bytes, 0, available);
060                                    Thread.sleep(10000);
061                            }
062                    } catch (IOException e) {
063                            System.err.println("Parent process stopped at " + (new Date()));
064                    }
065                    Watchdog watchdog = new Watchdog(appName, System.getProperty(SEND_EMAIL), System.getProperty(SMTP_HOST), System.getProperty(SMTP_PORT));
066                    watchdog.sendEmail();
067            }
068    
069            boolean sendEmail() throws MessagingException {
070                    if (emailRecipient == null || emailRecipient.isEmpty()) return false;
071                    System.out.println("Sending email to: " + emailRecipient + " " + System.getProperty(SMTP_PORT));
072                    boolean debug = false;
073    
074                    // Set the host smtp address
075                    Properties props = new Properties();
076                    props.put("mail.smtp.host", smtpHost);
077                    props.put("mail.smtp.port", String.valueOf(smtpPort));
078                    props.put("mail.smtp.debug", "true");
079    
080                    // create some properties and get the default Session
081                    Session session = Session.getDefaultInstance(props, null);
082                    session.setDebug(debug);
083    
084                    // create a message
085                    Message msg = new MimeMessage(session);
086    
087                    // set the from and to addresses
088                    InternetAddress addressFrom = new InternetAddress("watchdog@" + hostname);
089                    msg.setFrom(addressFrom);
090    
091                    InternetAddress[] addressTo = new InternetAddress[1];
092                    addressTo[0] = new InternetAddress(emailRecipient);
093                    msg.setRecipients(Message.RecipientType.TO, addressTo);
094    
095                    msg.setSubject("Application " + appName + " has failed!");
096                    StringBuilder sb = new StringBuilder();
097                    sb.append("Master application '");
098                    sb.append(appName);
099                    sb.append("' at ");
100                    sb.append(hostname);
101                    sb.append(" was lost at ");
102                    sb.append(new Date());
103                    sb.append("\n");
104                    sb.append("Action taken: email sent to '");
105                    sb.append(emailRecipient);
106                    sb.append("'\n");
107                    msg.setText(sb.toString());
108                    Transport.send(msg);
109                    return true;
110            }
111    }