EIDSNotificationReceiver.java

  1. /*
  2.  * EIDSNotificationReceiver
  3.  */
  4. package gov.usgs.earthquake.distribution;

  5. import java.io.InputStream;
  6. import java.util.logging.Level;
  7. import java.util.logging.Logger;
  8. import java.util.regex.Pattern;

  9. import gov.usgs.earthquake.eidsutil.EIDSClient;
  10. import gov.usgs.earthquake.eidsutil.EIDSListener;
  11. import gov.usgs.earthquake.eidsutil.EIDSMessageEvent;
  12. import gov.usgs.util.Config;
  13. import gov.usgs.util.StreamUtils;

  14. /**
  15.  * Receive XML notifications using EIDS.
  16.  *
  17.  *
  18.  * This class implements the Configurable interface, and has the following
  19.  * options:
  20.  * <dl>
  21.  * <dt>serverHost</dt>
  22.  * <dd>The EIDS Server hostname or IP address.</dd>
  23.  * <dt>serverPort</dt>
  24.  * <dd>The EIDS Server listen port, usually 39977.</dd>
  25.  * <dt>alternateServers</dt>
  26.  * <dd>A comma separated list of HOST:PORT pairs. The EIDSClient will attempt to
  27.  * connect to these servers when unable to connect to the primary
  28.  * serverHost:serverPort.</dd>
  29.  * <dt>trackingFile</dt>
  30.  * <dd>A file name used for tracking connection state. This is used to receive
  31.  * missed messages when (re)connecting.</dd>
  32.  * </dl>
  33.  */
  34. public class EIDSNotificationReceiver extends DefaultNotificationReceiver implements EIDSListener {

  35.   /** Logging object. */
  36.   private static final Logger LOGGER = Logger.getLogger(EIDSNotificationReceiver.class.getName());

  37.   /** Property name for eids server host address. */
  38.   public static final String EIDS_SERVER_HOST_PROPERTY = "serverHost";

  39.   /** Property name for eids server port. */
  40.   public static final String EIDS_SERVER_PORT = "serverPort";

  41.   /** Property name for eids server alternate servers list. */
  42.   public static final String EIDS_ALTERNATE_SERVERS = "alternateServers";

  43.   /** Property name for eids client tracking file. */
  44.   public static final String EIDS_TRACKING_FILE = "trackingfile";

  45.   /** Property name for eids client log level. */
  46.   public static final String EIDS_DEBUG = "eidsDebug";

  47.   /** Property name for eids max server event age. */
  48.   public static final String EIDS_MAX_EVENT_AGE = "maxServerEventAgeDays";

  49.   /** EIDSClient that receives notifications. */
  50.   private EIDSClient client;

  51.   // TODO: Change condition using URLNotificationParser
  52.   /**
  53.    * Implement the EIDSListener interface to process messages from EIDS.
  54.    *
  55.    * Checks to make sure message has Correct namespace and root element before
  56.    * parsing.
  57.    */
  58.   public void onEIDSMessage(EIDSMessageEvent event) {
  59.     if (URLNotificationParser.PRODUCT_XML_NAMESPACE.equals(event.getRootNamespace())
  60.         && URLNotificationParser.NOTIFICATION_ELEMENT.equals(event.getRootElement())) {
  61.       InputStream in = null;
  62.       try {
  63.         in = StreamUtils.getInputStream(event.getMessage());
  64.         // this is a notification message
  65.         URLNotification notification = URLNotificationXMLConverter.parseXML(in);
  66.         // process the notification
  67.         receiveNotification(notification);
  68.       } catch (Exception e) {
  69.         LOGGER.log(Level.WARNING, "[" + getName() + "] exception while parsing URLNotification", e);
  70.       } finally {
  71.         StreamUtils.closeStream(in);
  72.       }
  73.     } else {
  74.       LOGGER
  75.           .info("[" + getName() + "] ignoring message type " + event.getRootNamespace() + ":" + event.getRootElement());
  76.       LOGGER.info("[" + getName() + "] message content: " + event.getMessage());
  77.     }
  78.   }

  79.   public void configure(Config config) throws Exception {
  80.     super.configure(config);
  81.     // configure eids client
  82.     client = new EIDSClient();
  83.     client.addListener(this);

  84.     String serverHost = config.getProperty(EIDS_SERVER_HOST_PROPERTY, EIDSClient.DEFAULT_SERVER_HOST);
  85.     LOGGER.config("[" + getName() + "] EIDS server host is '" + serverHost + "'");
  86.     client.setServerHost(serverHost);

  87.     Integer serverPort = Integer
  88.         .valueOf(config.getProperty(EIDS_SERVER_PORT, Integer.toString(EIDSClient.DEFAULT_SERVER_PORT)));
  89.     LOGGER.config("[" + getName() + "] EIDS server port is '" + serverPort + "'");
  90.     client.setServerPort(serverPort);

  91.     String alternateServers = config.getProperty(EIDS_ALTERNATE_SERVERS, "");
  92.     if (isAlternateServersValid(alternateServers)) {
  93.       LOGGER.config("[" + getName() + "] EIDS alternate servers '" + alternateServers + "'");
  94.       client.setAlternateServersList(alternateServers);
  95.     } else {
  96.       String message = "[" + getName() + "] EIDS alternate servers are not configured correctly, "
  97.           + "a port number is missing.";
  98.       LOGGER.severe(message);
  99.       throw new ConfigurationException(message);
  100.     }

  101.     String trackingFile = config.getProperty(EIDS_TRACKING_FILE);
  102.     if (trackingFile != null) {
  103.       LOGGER.config("[" + getName() + "] EIDS tracking file is '" + trackingFile + "'");
  104.       client.setTrackingFileName(trackingFile);
  105.     }

  106.     String debug = config.getProperty(EIDS_DEBUG);
  107.     if (debug != null) {
  108.       LOGGER.config("[" + getName() + "] EIDS debug mode = '" + debug + "'");
  109.       client.setDebug(Boolean.parseBoolean(debug));
  110.     }

  111.     String maxEventAgeString = config.getProperty(EIDS_MAX_EVENT_AGE);
  112.     if (maxEventAgeString != null) {
  113.       LOGGER.config("[" + getName() + "] EIDS max event age is " + maxEventAgeString + " days");
  114.       client.setMaxServerEventAgeDays(Double.parseDouble(maxEventAgeString));
  115.     }
  116.   }

  117.   public void shutdown() throws Exception {
  118.     client.shutdown();
  119.     super.shutdown();
  120.   }

  121.   public void startup() throws Exception {
  122.     super.startup();
  123.     if (client == null) {
  124.       throw new ConfigurationException("[" + getName() + "] EIDS client is not properly configured");
  125.     }
  126.     client.startup();
  127.   }

  128.   /**
  129.    * Checks alternateServers configuration parameter for correct syntax -
  130.    * (correct) "host:port, host:port"
  131.    *
  132.    * @param alternateServers comma separated list of host:port combinations
  133.    * @return boolean
  134.    */
  135.   public boolean isAlternateServersValid(String alternateServers) {
  136.     Boolean match = true;
  137.     if (alternateServers == "") {
  138.       return match;
  139.     }
  140.     Pattern portPattern = Pattern.compile("[0-9]{1,5}");
  141.     String[] servers = alternateServers.split(",");
  142.     for (String server : servers) {
  143.       String[] hostPort = server.split(":");
  144.       boolean hostnameExists = !hostPort[0].trim().isEmpty();
  145.       // host and port exist, and a valid port was used
  146.       if (hostPort.length != 2 || !hostnameExists || !portPattern.matcher(hostPort[1]).find()) {
  147.         match = false;
  148.         break;
  149.       }
  150.     }
  151.     return match;
  152.   }

  153.   /** @return EIDSClient */
  154.   public EIDSClient getClient() {
  155.     return client;
  156.   }

  157.   /** @param client set EIDSClient */
  158.   public void setClient(EIDSClient client) {
  159.     this.client = client;
  160.   }

  161. }