ArchivePolicy.java

  1. package gov.usgs.earthquake.indexer;

  2. import gov.usgs.earthquake.distribution.ConfigurationException;
  3. import gov.usgs.earthquake.util.ISO8601;
  4. import gov.usgs.util.Config;
  5. import gov.usgs.util.DefaultConfigurable;

  6. import java.math.BigDecimal;
  7. import java.util.Date;
  8. import java.util.logging.Logger;

  9. /**
  10.  * A policy for the Indexer to clean up Events in its ProductIndex.
  11.  *
  12.  * The policy is created by configuration parameters and generates
  13.  * a ProductIndexQuery. Any product/event matching the product index query is
  14.  * archived. Generally, archiving means the data for that product/event is
  15.  * removed from the index as well as the storage. Upon archiving, an
  16.  * EVENT_ARCHIVED type of IndexerEvent is sent to interested listeners.
  17.  *
  18.  * All archive policies run in their own thread (one thread separate from
  19.  * indexing for all archive policies, not one each) and execute at configured
  20.  * intervals.
  21.  *
  22.  * @author emartinez
  23.  *
  24.  */
  25. public class ArchivePolicy extends DefaultConfigurable {

  26.     private static final Logger LOGGER = Logger.getLogger(ArchivePolicy.class
  27.             .getName());

  28.     // --------------------------------------------------------------------
  29.     // Names of configurable parameters
  30.     // --------------------------------------------------------------------

  31.     /** @deprecated */
  32.     public static final String ARCHIVE_MIN_AGE_PROPERTY = "minAge";
  33.     /** @deprecated */
  34.     public static final String ARCHIVE_MAX_AGE_PROPERTY = "maxAge";

  35.     /** Property for archive minimum event age */
  36.     public static final String ARCHIVE_MIN_EVENT_AGE_PROPERTY = "minEventAge";
  37.     /** Property for archive maximum event age */
  38.     public static final String ARCHIVE_MAX_EVENT_AGE_PROPERTY = "maxEventAge";

  39.     /** Property for archive minimum event time */
  40.     public static final String ARCHIVE_MIN_EVENT_TIME_PROPERTY = "minEventTime";
  41.     /** Property for archive maximum event time */
  42.     public static final String ARCHIVE_MAX_EVENT_TIME_PROPERTY = "maxEventTime";

  43.     /** Property for archive minimum mag */
  44.     public static final String ARCHIVE_MIN_MAG_PROPERTY = "minMag";
  45.     /** Property for archive maximum mag */
  46.     public static final String ARCHIVE_MAX_MAG_PROPERTY = "maxMag";

  47.     /** Property for archive minimum latitude */
  48.     public static final String ARCHIVE_MIN_LAT_PROPERTY = "minLat";
  49.     /** Property for archive maximum latitude */
  50.     public static final String ARCHIVE_MAX_LAT_PROPERTY = "maxLat";

  51.     /** Property for archive minimum longitude */
  52.     public static final String ARCHIVE_MIN_LNG_PROPERTY = "minLng";
  53.     /** Property for archive maximum longitude */
  54.     public static final String ARCHIVE_MAX_LNG_PROPERTY = "maxLng";

  55.     /** Property for archive minimum depth */
  56.     public static final String ARCHIVE_MIN_DEPTH_PROPERTY = "minDepth";
  57.     /** Property for archive maximum depth */
  58.     public static final String ARCHIVE_MAX_DEPTH_PROPERTY = "maxDepth";

  59.     /** Property for archive event source */
  60.     public static final String ARCHIVE_EVENT_SOURCE_PROPERTY = "eventSource";

  61.     // --------------------------------------------------------------------
  62.     // Configured parameters.
  63.     // --------------------------------------------------------------------

  64.     /** @deprecated */
  65.     protected Long minAge = null;
  66.     /** @deprecated */
  67.     protected Long maxAge = null;

  68.     /** Configured parameter var for minEventAge */
  69.     protected Long minEventAge = null;
  70.     /** Configured parameter var for maxEventAge */
  71.     protected Long maxEventAge = null;

  72.     /** Configured parameter var for minEventTime */
  73.     protected Long minEventTime = null;
  74.     /** Configured parameter var for maxEventTime */
  75.     protected Long maxEventTime = null;

  76.     /** Configured parameter var for minMag */
  77.     protected BigDecimal minMag = null;
  78.     /** Configured parameter var for maxMag */
  79.     protected BigDecimal maxMag = null;

  80.     /** Configured parameter var for minLat */
  81.     protected BigDecimal minLat = null;
  82.     /** Configured parameter var for maxLat */
  83.     protected BigDecimal maxLat = null;

  84.     /** Configured parameter var for minLng */
  85.     protected BigDecimal minLng = null;
  86.     /** Configured parameter var for maxLng */
  87.     protected BigDecimal maxLng = null;

  88.     /** Configured parameter var for minDepth */
  89.     protected BigDecimal minDepth = null;
  90.     /** Configured parameter var for maxDepth */
  91.     protected BigDecimal maxDepth = null;

  92.     /** Configured parameter var for eventSource */
  93.     protected String eventSource = null;

  94.     /** Default Constructor */
  95.     public ArchivePolicy() {
  96.         // Default constructor
  97.     }

  98.     @Override
  99.     public void configure(Config config) throws Exception {
  100.         minEventAge = parseLong(config, ARCHIVE_MIN_EVENT_AGE_PROPERTY);
  101.         maxEventAge = parseLong(config, ARCHIVE_MAX_EVENT_AGE_PROPERTY);

  102.         minEventTime = parseDateOrLong(config, ARCHIVE_MIN_EVENT_TIME_PROPERTY);
  103.         maxEventTime = parseDateOrLong(config, ARCHIVE_MAX_EVENT_TIME_PROPERTY);

  104.         minAge = parseLong(config, ARCHIVE_MIN_AGE_PROPERTY);
  105.         if (minAge != null) {
  106.             LOGGER.config("Use of minAge property is deprecated.");
  107.         }
  108.         maxAge = parseLong(config, ARCHIVE_MAX_AGE_PROPERTY);
  109.         if (maxAge != null) {
  110.             LOGGER.config("Use of maxAge property is deprecated.");
  111.         }

  112.         if (minEventAge != null && maxEventTime != null) {
  113.             LOGGER.config("Both minEventAge and maxEventTime were specified. "
  114.                     + "Ignoring minEventAge. Only maxEventTime will be used.");
  115.         }
  116.         if (maxEventAge != null && minEventTime != null) {
  117.             LOGGER.config("Both maxEventAge and minEventTime were specified. "
  118.                     + "Ignoring maxEventAge. Only minEventTime will be used.");
  119.         }

  120.         if ((minAge != null || maxAge != null)
  121.                 && (minEventAge != null || maxEventAge != null
  122.                         || minEventTime != null || maxEventTime != null)) {

  123.             ConfigurationException ce = new ConfigurationException(
  124.                     "Configuration mismatch. Can not specify both "
  125.                             + "minAge/maxAge (legacy) properties as well as "
  126.                             + "minEventAge/maxEventAge or minEventTime/maxEventTime.");

  127.             ce.fillInStackTrace();
  128.             throw ce;
  129.         }

  130.         if ((minEventAge != null && maxEventAge != null)
  131.                 && (minEventAge > maxEventAge)) {

  132.             ConfigurationException ce = new ConfigurationException(
  133.                     "Configuration mismatch. minEventAge "
  134.                             + "greater than maxEventAge.");
  135.             ce.fillInStackTrace();
  136.             throw ce;
  137.         }

  138.         if ((minEventTime != null && maxEventTime != null)
  139.                 && (minEventTime > maxEventTime)) {

  140.             ConfigurationException ce = new ConfigurationException(
  141.                     "Configuration mismatch. minEventTime "
  142.                             + "greater than maxEventTime.");
  143.             ce.fillInStackTrace();
  144.             throw ce;
  145.         }

  146.         minMag = parseBigDecimal(config, ARCHIVE_MIN_MAG_PROPERTY);
  147.         maxMag = parseBigDecimal(config, ARCHIVE_MAX_MAG_PROPERTY);
  148.         minLat = parseBigDecimal(config, ARCHIVE_MIN_LAT_PROPERTY);
  149.         maxLat = parseBigDecimal(config, ARCHIVE_MAX_LAT_PROPERTY);
  150.         minLng = parseBigDecimal(config, ARCHIVE_MIN_LNG_PROPERTY);
  151.         maxLng = parseBigDecimal(config, ARCHIVE_MAX_LNG_PROPERTY);
  152.         minDepth = parseBigDecimal(config, ARCHIVE_MIN_DEPTH_PROPERTY);
  153.         maxDepth = parseBigDecimal(config, ARCHIVE_MAX_DEPTH_PROPERTY);
  154.         eventSource = config.getProperty(ARCHIVE_EVENT_SOURCE_PROPERTY);
  155.     }

  156.     @Override
  157.     public void shutdown() throws Exception {
  158.         // Nothing to do
  159.     }

  160.     @Override
  161.     public void startup() throws Exception {
  162.         // Nothing to do
  163.     }

  164.     /** @return a ProductIndexQuery */
  165.     public ProductIndexQuery getIndexQuery() {
  166.         ProductIndexQuery productIndexQuery = new ProductIndexQuery();
  167.         Date now = new Date();

  168.         if (minAge != null) {
  169.             // min age corresponds to minimum event time
  170.             productIndexQuery.setMinEventTime(new Date(now.getTime()
  171.                     - minAge.longValue()));
  172.         }
  173.         if (maxAge != null) {
  174.             // max age corresponds to maximum event time
  175.             productIndexQuery.setMaxEventTime(new Date(now.getTime()
  176.                     - maxAge.longValue()));
  177.         }

  178.         /*-
  179.          Epoch                                                            Now
  180.            |------------------- maxAge <---------------------------------- |
  181.            |                       |                                       |
  182.            |                       |                minAge <---------------|
  183.            |                       |                   |                   |
  184.            |-----------------------|-------------------|-------------------|
  185.            |                       |                   |
  186.            |------------------> minTime                |
  187.            |                                           |
  188.            |--------------------------------------> maxTime

  189.          Simple Example (not to scale)

  190.            0 (Epoch)                                              (Now) 100,000
  191.            |------------------- maxAge <--- (10,000) --------------------- |
  192.            |                       |                                       |
  193.            |                       |                minAge <--- (1,000) ---|
  194.            |                       |                   |                   |
  195.            |-------------------- 90,000 ************ 99,000 ---------------|
  196.            |                       |                   |
  197.            |----- (90,000) ---> minTime                |
  198.            |                                           |
  199.            |------------------------- (99,000) ---> maxTime

  200.            Events occurring in the *** time span will match the query and be
  201.            archived.
  202.          */

  203.         if (maxEventAge != null) {
  204.             productIndexQuery.setMinEventTime(new Date(now.getTime()
  205.                     - maxEventAge.longValue()));
  206.         }
  207.         if (minEventAge != null) {
  208.             productIndexQuery.setMaxEventTime(new Date(now.getTime()
  209.                     - minEventAge.longValue()));
  210.         }

  211.         if (minEventTime != null) {
  212.             productIndexQuery
  213.                     .setMinEventTime(new Date(minEventTime.longValue()));
  214.         }
  215.         if (maxEventTime != null) {
  216.             productIndexQuery
  217.                     .setMaxEventTime(new Date(maxEventTime.longValue()));
  218.         }

  219.         productIndexQuery.setMinEventMagnitude(minMag);
  220.         productIndexQuery.setMaxEventMagnitude(maxMag);
  221.         productIndexQuery.setMinEventLatitude(minLat);
  222.         productIndexQuery.setMaxEventLatitude(maxLat);
  223.         productIndexQuery.setMinEventLongitude(minLng);
  224.         productIndexQuery.setMaxEventLongitude(maxLng);
  225.         productIndexQuery.setMinEventDepth(minDepth);
  226.         productIndexQuery.setMaxEventDepth(maxDepth);
  227.         productIndexQuery.setEventSource(eventSource);

  228.         // this archive policy is only for events, only remove events based on
  229.         // their preferred properties
  230.         productIndexQuery
  231.                 .setEventSearchType(ProductIndexQuery.SEARCH_EVENT_PREFERRED);

  232.         productIndexQuery.setResultType(ProductIndexQuery.RESULT_TYPE_ALL);

  233.         return productIndexQuery;
  234.     }

  235.     /** @return boolean if the policy is valid */
  236.     public boolean isValidPolicy() {
  237.         // Not valid if using both old and new configuration methods
  238.         boolean valid = !((minAge != null || maxAge != null) && (minEventAge != null || maxEventAge != null));

  239.         return valid
  240.                 && (minAge != null || maxAge != null || minEventAge != null
  241.                         || maxEventAge != null || minEventTime != null
  242.                         || maxEventTime != null || minMag != null
  243.                         || maxMag != null || minLat != null || maxLat != null
  244.                         || minLng != null || maxLng != null || minDepth != null
  245.                         || maxDepth != null || eventSource != null);
  246.     }

  247.     /**
  248.      * Gets the property 'name' from config and returns a BigDecimal of it
  249.      * @param config Config file
  250.      * @param name name of property from config
  251.      * @return BigDecimal of property
  252.      */
  253.     protected BigDecimal parseBigDecimal(Config config, String name) {
  254.         BigDecimal property = null;
  255.         try {
  256.             String buffer = config.getProperty(name);
  257.             if (buffer != null) {
  258.                 property = new BigDecimal(buffer);
  259.             }
  260.         } catch (NumberFormatException npx) {
  261.             property = null;
  262.         }
  263.         return property;
  264.     }

  265.     /**
  266.      * Gets the property 'name' from config and returns a Date/Long of it
  267.      * @param config Config file
  268.      * @param name name of property from config
  269.      * @return Date/Long of property
  270.      */
  271.     protected Long parseDateOrLong(Config config, String name) {
  272.         Long property = null;
  273.         try {
  274.             String buffer = config.getProperty(name);
  275.             if (buffer != null) {
  276.                 if (buffer.indexOf("T") != -1) {
  277.                     // try parsing as date
  278.                     Date date = ISO8601.parse(buffer);
  279.                     if (date != null) {
  280.                         property = date.getTime();
  281.                     }
  282.                 } else {
  283.                     property = Long.valueOf(buffer);
  284.                 }
  285.             }
  286.         } catch (NumberFormatException npx) {
  287.             property = null;
  288.         }
  289.         return property;
  290.     }

  291.     /**
  292.      * Gets the property 'name' from config and returns a Long of it
  293.      * @param config Config file
  294.      * @param name name of property from config
  295.      * @return Long of property
  296.      */
  297.     protected Long parseLong(Config config, String name) {
  298.         Long property = null;
  299.         try {
  300.             String buffer = config.getProperty(name);
  301.             if (buffer != null) {
  302.                 property = Long.valueOf(buffer);
  303.             }
  304.         } catch (NumberFormatException npx) {
  305.             property = null;
  306.         }
  307.         return property;
  308.     }

  309.     /** @deprecated
  310.      * @return minAge
  311.      */
  312.     public Long getMinAge() {
  313.         return minAge;
  314.     }

  315.     /** @deprecated
  316.      * @param minAge to set
  317.      */
  318.     public void setMinAge(Long minAge) {
  319.         this.minAge = minAge;
  320.     }

  321.     /** @deprecated
  322.      * @return maxAge
  323.      */
  324.     public Long getMaxAge() {
  325.         return maxAge;
  326.     }

  327.     /** @deprecated
  328.      * @param maxAge to set
  329.      */
  330.     public void setMaxAge(Long maxAge) {
  331.         this.maxAge = maxAge;
  332.     }

  333.     /** @return minEventAge */
  334.     public Long getMinEventAge() {
  335.         return minEventAge;
  336.     }

  337.     /** @param minEventAge to set */
  338.     public void setMinEventAge(Long minEventAge) {
  339.         this.minEventAge = minEventAge;
  340.     }

  341.     /** @return maxEventAge */
  342.     public Long getMaxEventAge() {
  343.         return maxEventAge;
  344.     }

  345.     /** @param maxEventAge to set */
  346.     public void setMaxEventAge(Long maxEventAge) {
  347.         this.maxEventAge = maxEventAge;
  348.     }

  349.     /** @return minEventTime */
  350.     public Long getMinEventTime() {
  351.         return minEventTime;
  352.     }

  353.     /** @param minEventTime to set */
  354.     public void setMinEventTime(Long minEventTime) {
  355.         this.minEventTime = minEventTime;
  356.     }

  357.     /** @return maxEventTime */
  358.     public Long getMaxEventTime() {
  359.         return maxEventTime;
  360.     }

  361.     /** @param maxEventTime to set  */
  362.     public void setMaxEventTime(Long maxEventTime) {
  363.         this.maxEventTime = maxEventTime;
  364.     }

  365.     /** @return minMag */
  366.     public BigDecimal getMinMag() {
  367.         return minMag;
  368.     }

  369.     /** @param minMag to set  */
  370.     public void setMinMag(BigDecimal minMag) {
  371.         this.minMag = minMag;
  372.     }

  373.     /** @return maxMag */
  374.     public BigDecimal getMaxMag() {
  375.         return maxMag;
  376.     }

  377.     /** @param maxMag to set */
  378.     public void setMaxMag(BigDecimal maxMag) {
  379.         this.maxMag = maxMag;
  380.     }

  381.     /** @return minLat */
  382.     public BigDecimal getMinLat() {
  383.         return minLat;
  384.     }

  385.     /** @param minLat to set */
  386.     public void setMinLat(BigDecimal minLat) {
  387.         this.minLat = minLat;
  388.     }

  389.     /** @return maxLat */
  390.     public BigDecimal getMaxLat() {
  391.         return maxLat;
  392.     }

  393.     /** @param maxLat to set */
  394.     public void setMaxLat(BigDecimal maxLat) {
  395.         this.maxLat = maxLat;
  396.     }

  397.     /** @return minLng */
  398.     public BigDecimal getMinLng() {
  399.         return minLng;
  400.     }

  401.     /** @param minLng to set */
  402.     public void setMinLng(BigDecimal minLng) {
  403.         this.minLng = minLng;
  404.     }

  405.     /** @return maxLng */
  406.     public BigDecimal getMaxLng() {
  407.         return maxLng;
  408.     }

  409.     /** @param maxLng to set */
  410.     public void setMaxLng(BigDecimal maxLng) {
  411.         this.maxLng = maxLng;
  412.     }

  413.     /** @return minDepth */
  414.     public BigDecimal getMinDepth() {
  415.         return minDepth;
  416.     }

  417.     /** @param minDepth to set */
  418.     public void setMinDepth(BigDecimal minDepth) {
  419.         this.minDepth = minDepth;
  420.     }

  421.     /** @return maxDepth */
  422.     public BigDecimal getMaxDepth() {
  423.         return maxDepth;
  424.     }

  425.     /** @param maxDepth to set */
  426.     public void setMaxDepth(BigDecimal maxDepth) {
  427.         this.maxDepth = maxDepth;
  428.     }

  429.     /** @return eventSource */
  430.     public String getEventSource() {
  431.         return eventSource;
  432.     }

  433.     /** @param eventSource to set */
  434.     public void setEventSource(String eventSource) {
  435.         this.eventSource = eventSource;
  436.     }
  437. }