Java tutorial
/* The MIT License (MIT) Copyright (c) 2016 EMC Corporation Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ package com.emc.kibana.emailer; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Properties; import javax.activation.DataHandler; import javax.activation.DataSource; import javax.activation.FileDataSource; import javax.mail.BodyPart; import javax.mail.Message; import javax.mail.MessagingException; import javax.mail.Multipart; import javax.mail.PasswordAuthentication; import javax.mail.Session; import javax.mail.Transport; import javax.mail.internet.InternetAddress; import javax.mail.internet.MimeBodyPart; import javax.mail.internet.MimeMessage; import javax.mail.internet.MimeMultipart; import org.openqa.selenium.OutputType; import org.openqa.selenium.TakesScreenshot; import org.openqa.selenium.WebDriver; import org.openqa.selenium.chrome.ChromeDriver; import org.openqa.selenium.chrome.ChromeOptions; import org.openqa.selenium.remote.DesiredCapabilities; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.apache.commons.io.FileUtils; import com.esotericsoftware.yamlbeans.YamlException; import com.esotericsoftware.yamlbeans.YamlReader; /** * Utility to grab Kibana web sites' content and email them. */ public class KibanaEmailer { //================================ // Final members //================================ private static final String CONFIG_FILE_CONFIG_ARGUMENT = "--config-file"; private static final String KIBANA_URLS_CONFIG = "kibana.urls"; private static final String CHROME_DRIVER_CONFIG = "chrome.driver"; private static final String CHROME_BROWSER_CONFIG = "chrome.browser"; private static final String SCREEN_CAPTURE_DELAY = "screen.capture.delay"; private static final String DESTINATION_PATH_CONFIG = "destination.path"; private static final String SMTP_HOST_CONFIG = "smtp.host"; private static final String SMTP_PORT_CONFIG = "smtp.port"; private static final String SMTP_USERNAME_CONFIG = "smtp.username"; private static final String SMTP_PASSWORD_CONFIG = "smtp.password"; private static final String SMTP_SECURITY_CONFIG = "smtp.security"; private static final String SMTP_SECURITY_TLS = "tls"; private static final String SMTP_SECURITY_SSL = "ssl"; private static final String SOURCE_HOST_CONFIG = "source.host"; private static final String SOURCE_ADDRESS_CONFIG = "source.address"; private static final String DESTINATION_ADDRESS_CONFIG = "destination.addresses"; private static final String MAIL_TITLE_CONFIG = "mail.title"; private static final String MAIL_BODY_CONFIG = "mail.body"; private static final String ABSOLUE_FILE_NAME_KEY = "absolute-file-name"; private static final String FILE_NAME_KEY = "file-name"; private static final String NAME_KEY = "name"; private static final String URL_KEY = "url"; private static final String DATA_DATE_PATTERN = "yyyy-MM-dd'T'HH:mm:ss"; //================================ // Private Members //================================ private static final SimpleDateFormat DATA_DATE_FORMAT = new SimpleDateFormat(DATA_DATE_PATTERN); private static String chromeDriverPath = ""; private static String chromeBrowserPath = ""; private static Integer screenCaptureDelay = 20; private static String kibanaConfigFile = "../config/kibana-emailer.yml"; private static String destinationPath = "."; private static ArrayList<Map<String, String>> kibanaUrls = new ArrayList<Map<String, String>>(); private static List<Map<String, String>> kibanaScreenCaptures = new ArrayList<Map<String, String>>(); private static String smtpHost = "localhost"; private static String smtpPort = "587"; private static String smtpUsername = "username"; private static String smtpPassword = "password"; private static String smtpSecurity = SMTP_SECURITY_TLS; private static String sourceHost = "localhost"; private static String sourceAddress = "name@mail.com"; private static List<String> destinationAddressList = new ArrayList<String>(); private static String mailTitle = "Title"; private static String mailBody = "Body"; private final static Logger logger = LoggerFactory.getLogger(KibanaEmailer.class); //================================ // Public Methods //================================ public static void main(String[] args) throws Exception { logger.info("Kibana reports generated at : " + new Date(System.currentTimeMillis()).toString()); handleArguments(args); // file based config loadConfig(); // generate screen captures generatePdfReports(); // destination e-mails present if (!destinationAddressList.isEmpty()) { sendFileEmail(smtpSecurity); } } //================================ // Private Methods //================================ /* * utility method to handle program arguments */ private static void handleArguments(String[] args) { String menuString = "Usage: KibanaEmailer " + "[" + CONFIG_FILE_CONFIG_ARGUMENT + " <configfile> [Default: ../config/kibana-emailer.yml]] - Specify config file \n"; if (args.length > 0 && args[0].contains("--help")) { System.err.println(menuString); System.exit(0); } else { int i = 0; String arg; if (args.length > 1) { while (i < args.length && args[i].startsWith("--")) { arg = args[i++]; if (arg.equals(CONFIG_FILE_CONFIG_ARGUMENT)) { if (i < args.length) { kibanaConfigFile = args[i++]; } else { System.err.println(CONFIG_FILE_CONFIG_ARGUMENT + " requires config file path/"); System.exit(0); } } else { System.err.println(menuString); System.exit(0); } } } } } /* * Utility method to load and parse emailer's configuration data */ @SuppressWarnings("unchecked") private static void loadConfig() { try { FileReader fr; fr = new FileReader(kibanaConfigFile); logger.info("Loading configuration from config file: " + kibanaConfigFile); YamlReader reader = new YamlReader(fr); Object object = reader.read(); if (object == null) { logger.info("Can't load config data from: " + kibanaConfigFile + " exiting..."); System.out.println("Can't load config data from: " + kibanaConfigFile + " exiting..."); System.exit(0); } Map<?, ?> map = (Map<?, ?>) object; if (map == null) { logger.info("Can't load config data from: " + kibanaConfigFile + " exiting..."); System.out.println("Can't load config data from: " + kibanaConfigFile + " exiting..."); System.exit(0); } // chromedriver Object driverPathObj = map.get(CHROME_DRIVER_CONFIG); if (driverPathObj != null && driverPathObj instanceof String) { chromeDriverPath = (String) driverPathObj; } else { logger.info("Can't find: " + CHROME_DRIVER_CONFIG + " in " + kibanaConfigFile + " exiting..."); System.out .println("Can't find: " + CHROME_DRIVER_CONFIG + " in " + kibanaConfigFile + " exiting..."); System.exit(0); } // chromebrowser Object browserPathObj = map.get(CHROME_BROWSER_CONFIG); if (browserPathObj != null && browserPathObj instanceof String) { chromeBrowserPath = (String) browserPathObj; } else { logger.info("Can't find: " + CHROME_BROWSER_CONFIG + " in " + kibanaConfigFile + " exiting..."); System.out.println( "Can't find: " + CHROME_BROWSER_CONFIG + " in " + kibanaConfigFile + " exiting..."); System.exit(0); } Object captureDelayObj = map.get(SCREEN_CAPTURE_DELAY); if (captureDelayObj != null && captureDelayObj instanceof String) { screenCaptureDelay = Integer.valueOf((String) captureDelayObj); } else { logger.info("Can't find: " + SCREEN_CAPTURE_DELAY + " in " + kibanaConfigFile + " exiting..."); System.out .println("Can't find: " + SCREEN_CAPTURE_DELAY + " in " + kibanaConfigFile + " exiting..."); System.exit(0); } // Kibana Urls Object urls = map.get(KIBANA_URLS_CONFIG); if (urls != null && urls instanceof ArrayList<?>) { kibanaUrls = (ArrayList<Map<String, String>>) urls; } else { logger.info("Can't find: " + KIBANA_URLS_CONFIG + " in " + kibanaConfigFile + " exiting..."); System.out.println("Can't find: " + KIBANA_URLS_CONFIG + " in " + kibanaConfigFile + " exiting..."); System.exit(0); } // destination path to save screen captures Object destinationObj = map.get(DESTINATION_PATH_CONFIG); if (destinationObj != null && destinationObj instanceof String) { destinationPath = (String) destinationObj; } else { logger.info("Can't find: " + DESTINATION_PATH_CONFIG + " in " + kibanaConfigFile + " exiting..."); System.out.println( "Can't find: " + DESTINATION_PATH_CONFIG + " in " + kibanaConfigFile + " exiting..."); System.exit(0); } // == smtp config == // smtp.host Object smtpHostObj = map.get(SMTP_HOST_CONFIG); if (smtpHostObj != null && smtpHostObj instanceof String) { smtpHost = (String) smtpHostObj; } else { logger.info("Can't find: " + SMTP_HOST_CONFIG + " in " + kibanaConfigFile + " exiting..."); System.out.println("Can't find: " + SMTP_HOST_CONFIG + " in " + kibanaConfigFile + " exiting..."); System.exit(0); } // smtp.port Object smtpPortObj = map.get(SMTP_PORT_CONFIG); if (smtpPortObj != null && smtpPortObj instanceof String) { smtpPort = (String) smtpHostObj; } else { logger.info("Can't find: " + SMTP_PORT_CONFIG + " in " + kibanaConfigFile + " exiting..."); System.out.println("Can't find: " + SMTP_PORT_CONFIG + " in " + kibanaConfigFile + " exiting..."); System.exit(0); } // smtp.username Object smtpUsernameObj = map.get(SMTP_USERNAME_CONFIG); if (smtpUsernameObj != null && smtpUsernameObj instanceof String) { smtpUsername = (String) smtpUsernameObj; } else { logger.info("Can't find: " + SMTP_USERNAME_CONFIG + " in " + kibanaConfigFile + " exiting..."); System.out .println("Can't find: " + SMTP_USERNAME_CONFIG + " in " + kibanaConfigFile + " exiting..."); System.exit(0); } // smtp.password Object smtpPasswordObj = map.get(SMTP_PASSWORD_CONFIG); if (smtpPasswordObj != null && smtpPasswordObj instanceof String) { smtpPassword = (String) smtpPasswordObj; } else { logger.info("Can't find: " + SMTP_PASSWORD_CONFIG + " in " + kibanaConfigFile + " exiting..."); System.out .println("Can't find: " + SMTP_PASSWORD_CONFIG + " in " + kibanaConfigFile + " exiting..."); System.exit(0); } // smtp.security "tls|ssl" Object smtpSecurityObj = map.get(SMTP_SECURITY_CONFIG); if (smtpSecurityObj != null && smtpSecurityObj instanceof String) { smtpSecurity = (String) smtpSecurityObj; } else { logger.info("Can't find: " + SMTP_SECURITY_CONFIG + " in " + kibanaConfigFile + " exiting..."); System.out .println("Can't find: " + SMTP_SECURITY_CONFIG + " in " + kibanaConfigFile + " exiting..."); System.exit(0); } // source.host Object sourceHostObj = map.get(SOURCE_HOST_CONFIG); if (sourceHostObj != null && sourceHostObj instanceof String) { sourceHost = (String) sourceHostObj; } else { logger.info("Can't find: " + SOURCE_HOST_CONFIG + " in " + kibanaConfigFile + " exiting..."); System.out.println("Can't find: " + SOURCE_HOST_CONFIG + " in " + kibanaConfigFile + " exiting..."); System.exit(0); } // e-mail addresses configuration // source.mail Object sourceAddressObj = map.get(SOURCE_ADDRESS_CONFIG); if (sourceAddressObj != null && sourceAddressObj instanceof String) { sourceAddress = (String) sourceAddressObj; } else { logger.info("Can't find: " + SOURCE_ADDRESS_CONFIG + " in " + kibanaConfigFile + " exiting..."); System.out.println( "Can't find: " + SOURCE_ADDRESS_CONFIG + " in " + kibanaConfigFile + " exiting..."); System.exit(0); } // destination.addresses Object destinations = map.get(DESTINATION_ADDRESS_CONFIG); if (destinations != null && destinations instanceof ArrayList<?>) { destinationAddressList = (ArrayList<String>) destinations; } else { logger.info( "Can't find: " + DESTINATION_ADDRESS_CONFIG + " in " + kibanaConfigFile + " exiting..."); System.out.println( "Can't find: " + DESTINATION_ADDRESS_CONFIG + " in " + kibanaConfigFile + " exiting..."); System.exit(0); } // e-mail content // mail.title Object mailTitleObj = map.get(MAIL_TITLE_CONFIG); if (mailTitleObj != null && mailTitleObj instanceof String) { mailTitle = (String) mailTitleObj; } else { logger.info("Can't find: " + MAIL_TITLE_CONFIG + " in " + kibanaConfigFile + " exiting..."); System.out.println("Can't find: " + MAIL_TITLE_CONFIG + " in " + kibanaConfigFile + " exiting..."); System.exit(0); } // mail.body Object mailBodyObj = map.get(MAIL_BODY_CONFIG); if (mailBodyObj != null && mailBodyObj instanceof String) { mailBody = (String) mailBodyObj; } else { logger.info("Can't find: " + MAIL_BODY_CONFIG + " in " + kibanaConfigFile + " exiting..."); System.out.println("Can't find: " + MAIL_BODY_CONFIG + " in " + kibanaConfigFile + " exiting..."); System.exit(0); } } catch (FileNotFoundException e) { throw new RuntimeException(e); } catch (YamlException e) { throw new RuntimeException(e); } logger.info("Loaded config details: " + SMTP_HOST_CONFIG + ": `" + smtpHost + "`, " + SMTP_PORT_CONFIG + ": `" + smtpPort.toString() + "`, " + SMTP_USERNAME_CONFIG + ": `" + smtpUsername + "`, " + SOURCE_HOST_CONFIG + ": `" + sourceHost + "`, " + SOURCE_ADDRESS_CONFIG + ": `" + sourceAddress + "`, " + DESTINATION_ADDRESS_CONFIG + ": `" + destinationAddressList.toString() + "`, " + MAIL_TITLE_CONFIG + ": `" + mailTitle + "`, " + MAIL_BODY_CONFIG + ": `" + mailBody); logger.info("Loaded config details: " + KIBANA_URLS_CONFIG + ": " + kibanaUrls.toString()); } /* * Utility method that uses ChromeDriver to programmatically control * the Chrome Browser to take dashboard screen captures */ private static void generatePdfReports() { try { System.setProperty("webdriver.chrome.driver", chromeDriverPath); Map<String, Object> chromeOptions = new HashMap<String, Object>(); // Specify alternate browser location if (chromeBrowserPath != null && !chromeBrowserPath.isEmpty()) { chromeOptions.put("binary", chromeBrowserPath); } DesiredCapabilities capabilities = DesiredCapabilities.chrome(); capabilities.setCapability(ChromeOptions.CAPABILITY, chromeOptions); int index = 1; Date timestamp = new Date(System.currentTimeMillis()); for (Map<String, String> entry : kibanaUrls) { String dashboardName = entry.get(NAME_KEY); String dashboardUrl = entry.get(URL_KEY); if (dashboardUrl == null) { continue; } String filename; if ((dashboardName != null)) { String invalidCharRemoved = dashboardName.replaceAll("[\\/:\"*?<>|]+", "_").replaceAll(" ", "_"); filename = invalidCharRemoved + ".png"; } else { filename = "dashboard-" + index++ + ".png"; } WebDriver driver = new ChromeDriver(capabilities); driver.manage().window().maximize(); driver.get(dashboardUrl); // let kibana load for x seconds before taking the snapshot Integer delay = (screenCaptureDelay != null) ? (screenCaptureDelay * 1000) : (20000); Thread.sleep(delay); // take screenshot File scrnshot = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE); // generate absolute path filename String absoluteFileName = destinationPath + File.separator + DATA_DATE_FORMAT.format(timestamp) + File.separator + filename; Map<String, String> fileMap = new HashMap<String, String>(); // file name portion fileMap.put(FILE_NAME_KEY, filename); fileMap.put(ABSOLUE_FILE_NAME_KEY, absoluteFileName); kibanaScreenCaptures.add(fileMap); File destFile = new File(absoluteFileName); logger.info("Copying " + scrnshot + " in " + destFile.getAbsolutePath()); FileUtils.copyFile(scrnshot, destFile); driver.close(); } } catch (InterruptedException e) { throw new RuntimeException(e); } catch (IOException e1) { throw new RuntimeException(e1); } } /* * Utility method that grabs png files and send them * to a list of email addresses */ private static void sendFileEmail(String security) { final String username = smtpUsername; final String password = smtpPassword; // Get system properties Properties properties = System.getProperties(); // Setup mail server properties.setProperty("mail.smtp.host", smtpHost); if (security.equals(SMTP_SECURITY_TLS)) { properties.put("mail.smtp.auth", "true"); properties.put("mail.smtp.starttls.enable", "true"); properties.put("mail.smtp.host", smtpHost); properties.put("mail.smtp.port", smtpPort); } else if (security.equals(SMTP_SECURITY_SSL)) { properties.put("mail.smtp.socketFactory.port", smtpPort); properties.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory"); properties.put("mail.smtp.auth", "true"); properties.put("mail.smtp.port", smtpPort); } Session session = Session.getInstance(properties, new javax.mail.Authenticator() { protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication(username, password); } }); try { // Create a default MimeMessage object. MimeMessage message = new MimeMessage(session); // Set From: header field of the header. message.setFrom(new InternetAddress(sourceAddress)); // Set To: header field of the header. for (String destinationAddress : destinationAddressList) { message.addRecipient(Message.RecipientType.TO, new InternetAddress(destinationAddress)); } // Set Subject: header field message.setSubject(mailTitle); // Create the message part BodyPart messageBodyPart = new MimeBodyPart(); StringBuffer bodyBuffer = new StringBuffer(mailBody); if (!kibanaUrls.isEmpty()) { bodyBuffer.append("\n\n"); } // Add urls info to e-mail for (Map<String, String> kibanaUrl : kibanaUrls) { // Add urls to e-mail String urlName = kibanaUrl.get(NAME_KEY); String reportUrl = kibanaUrl.get(URL_KEY); if (urlName != null && reportUrl != null) { bodyBuffer.append("- ").append(urlName).append(": ").append(reportUrl).append("\n\n\n"); } } // Fill the message messageBodyPart.setText(bodyBuffer.toString()); // Create a multipart message Multipart multipart = new MimeMultipart(); // Set text message part multipart.addBodyPart(messageBodyPart); // Part two is attachments for (Map<String, String> kibanaScreenCapture : kibanaScreenCaptures) { messageBodyPart = new MimeBodyPart(); String absoluteFilename = kibanaScreenCapture.get(ABSOLUE_FILE_NAME_KEY); String filename = kibanaScreenCapture.get(FILE_NAME_KEY); DataSource source = new FileDataSource(absoluteFilename); messageBodyPart.setDataHandler(new DataHandler(source)); messageBodyPart.setFileName(filename); multipart.addBodyPart(messageBodyPart); } // Send the complete message parts message.setContent(multipart); // Send message Transport.send(message); logger.info("Sent mail message successfully"); } catch (MessagingException mex) { throw new RuntimeException(mex); } } }