From b9f8daf75123d1b27e70cfe60a7de577bce38abd Mon Sep 17 00:00:00 2001 From: Dave Hladky Date: Thu, 26 Sep 2013 09:53:11 -0500 Subject: [PATCH] Issue #2386 Backend work for adding multiple types to Subscription overlap rules Change-Id: I0779dc7987031999b80ab0859c7f33dca20a5c17 Former-commit-id: e29d10ba4f0686254eba457121f4e0e1e74c3500 [formerly 449c584afc46257671808b921847a621e7020bcf] Former-commit-id: d34882eb49ab3d3611a445d98f4fc87ed7cae058 --- .../system/SubscriptionComposite.java | 32 ++- .../GridSubscriptionOverlapConfig.java | 121 +++++++++ .../ISubscriptionDuplicateChecker.java | 11 + .../ISubscriptionOverlapService.java | 9 +- .../PointSubscriptionOverlapConfig.java | 104 ++++++++ .../SubscriptionDuplicateChecker.java | 12 + .../SubscriptionOverlapConfig.java | 98 ++------ .../SubscriptionOverlapMatchStrategy.java | 133 +++++++--- .../SubscriptionOverlapService.java | 207 ++++++++++++---- ...s.xml => GRIDSubscriptionOverlapRules.xml} | 4 +- .../POINTSubscriptionOverlapRules.xml | 20 ++ ...SubscriptionOverlapMatchStrategyTest.java} | 6 +- ...> GridSubscriptionOverlapServiceTest.java} | 6 +- ...tSubscriptionOverlapMatchStrategyTest.java | 131 ++++++++++ .../PointSubscriptionOverlapServiceTest.java | 230 ++++++++++++++++++ 15 files changed, 947 insertions(+), 177 deletions(-) create mode 100644 edexOsgi/com.raytheon.uf.common.datadelivery.service/src/com/raytheon/uf/common/datadelivery/service/subscription/GridSubscriptionOverlapConfig.java create mode 100644 edexOsgi/com.raytheon.uf.common.datadelivery.service/src/com/raytheon/uf/common/datadelivery/service/subscription/PointSubscriptionOverlapConfig.java rename edexOsgi/com.raytheon.uf.common.datadelivery.service/utility/common_static/base/datadelivery/{subscriptionOverlapRules.xml => GRIDSubscriptionOverlapRules.xml} (93%) create mode 100644 edexOsgi/com.raytheon.uf.common.datadelivery.service/utility/common_static/base/datadelivery/POINTSubscriptionOverlapRules.xml rename tests/unit/com/raytheon/uf/common/datadelivery/service/subscription/{SubscriptionOverlapMatchStrategyTest.java => GridSubscriptionOverlapMatchStrategyTest.java} (96%) rename tests/unit/com/raytheon/uf/common/datadelivery/service/subscription/{SubscriptionOverlapServiceTest.java => GridSubscriptionOverlapServiceTest.java} (98%) create mode 100644 tests/unit/com/raytheon/uf/common/datadelivery/service/subscription/PointSubscriptionOverlapMatchStrategyTest.java create mode 100644 tests/unit/com/raytheon/uf/common/datadelivery/service/subscription/PointSubscriptionOverlapServiceTest.java diff --git a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/system/SubscriptionComposite.java b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/system/SubscriptionComposite.java index b1b49919eb..2896c78fbb 100644 --- a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/system/SubscriptionComposite.java +++ b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/system/SubscriptionComposite.java @@ -20,6 +20,8 @@ package com.raytheon.uf.viz.datadelivery.system; import java.util.EnumMap; +import java.util.HashMap; +import java.util.Map; import java.util.Map.Entry; import org.eclipse.swt.SWT; @@ -30,7 +32,10 @@ import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Spinner; +import com.raytheon.uf.common.datadelivery.registry.DataType; +import com.raytheon.uf.common.datadelivery.service.subscription.GridSubscriptionOverlapConfig; import com.raytheon.uf.common.datadelivery.service.subscription.ISubscriptionOverlapService; +import com.raytheon.uf.common.datadelivery.service.subscription.PointSubscriptionOverlapConfig; import com.raytheon.uf.common.datadelivery.service.subscription.SubscriptionOverlapConfig; import com.raytheon.uf.common.datadelivery.service.subscription.SubscriptionOverlapMatchStrategy; import com.raytheon.uf.common.localization.exception.LocalizationException; @@ -52,6 +57,7 @@ import com.raytheon.viz.ui.widgets.IApplyCancelAction; * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- * Aug 07, 2013 2180 mpduff Initial creation. + * Sept 24, 2013 2386 dhladky Started work on Multiple Type Configs * * * @@ -78,24 +84,26 @@ public class SubscriptionComposite extends Composite implements }, FORECAST_HOURS("Forecast Hours:") { @Override + // TODO: hard coded to Grid for now public int getValue(SubscriptionOverlapConfig config) { - return config.getMaxAllowedForecastHourDuplication(); + return ((GridSubscriptionOverlapConfig)config).getMaxAllowedForecastHourDuplication(); } @Override public void setValue(SubscriptionOverlapConfig config, int value) { - config.setMaxAllowedForecastHourDuplication(value); + ((GridSubscriptionOverlapConfig)config).setMaxAllowedForecastHourDuplication(value); } }, CYCLES("Cycles:") { @Override + // TODO: hard coded to Grid for now public int getValue(SubscriptionOverlapConfig config) { - return config.getMaxAllowedCycleDuplication(); + return ((GridSubscriptionOverlapConfig)config).getMaxAllowedCycleDuplication(); } @Override public void setValue(SubscriptionOverlapConfig config, int value) { - config.setMaxAllowedCycleDuplication(value); + ((GridSubscriptionOverlapConfig)config).setMaxAllowedCycleDuplication(value); } }, SPATIAL("Spatial:") { @@ -255,7 +263,7 @@ public class SubscriptionComposite extends Composite implements * Load configuration data */ private void loadConfiguration() { - SubscriptionOverlapConfig config; + Map config = new HashMap(); try { config = overlapService.readConfig(); } catch (LocalizationException e) { @@ -264,12 +272,16 @@ public class SubscriptionComposite extends Composite implements "Unable to load the subscription overlap rules. " + "Defaulting to configuration that will never overlap.", e); - config = SubscriptionOverlapConfig.NEVER_OVERLAPS; + + config.put(DataType.GRID, new GridSubscriptionOverlapConfig().getNeverOverlaps()); + config.put(DataType.POINT, new PointSubscriptionOverlapConfig().getNeverOverlaps()); } + // TODO: hard coded to Grid for now for (Entry entry : spinnerMap.entrySet()) { final Spinner spinner = entry.getValue(); - final int initialValue = entry.getKey().getValue(config); + // Hard coded to Grid until we change front end design + final int initialValue = entry.getKey().getValue(config.get(DataType.GRID)); DataDeliveryGUIUtils.removeListeners(spinner, SWT.Selection, SWT.DefaultSelection); @@ -283,7 +295,8 @@ public class SubscriptionComposite extends Composite implements DataDeliveryGUIUtils.removeListeners(matchStrategyCombo, SWT.Selection, SWT.DefaultSelection); - final int indexOfConfigValue = matchStrategyCombo.indexOf(config + // TODO: hard coded to Grid for now + final int indexOfConfigValue = matchStrategyCombo.indexOf(config.get(DataType.GRID) .getMatchStrategy().getDisplayString()); matchStrategyCombo.select(indexOfConfigValue); matchStrategyCombo.addSelectionListener(DataDeliveryGUIUtils @@ -298,7 +311,8 @@ public class SubscriptionComposite extends Composite implements * @throws LocalizationException */ private boolean saveConfiguration() throws LocalizationException { - SubscriptionOverlapConfig config = new SubscriptionOverlapConfig(); + // TODO: hard coded to Grid for now + GridSubscriptionOverlapConfig config = new GridSubscriptionOverlapConfig(); for (Entry entry : spinnerMap.entrySet()) { final OverlapSpinners key = entry.getKey(); diff --git a/edexOsgi/com.raytheon.uf.common.datadelivery.service/src/com/raytheon/uf/common/datadelivery/service/subscription/GridSubscriptionOverlapConfig.java b/edexOsgi/com.raytheon.uf.common.datadelivery.service/src/com/raytheon/uf/common/datadelivery/service/subscription/GridSubscriptionOverlapConfig.java new file mode 100644 index 0000000000..31de80602d --- /dev/null +++ b/edexOsgi/com.raytheon.uf.common.datadelivery.service/src/com/raytheon/uf/common/datadelivery/service/subscription/GridSubscriptionOverlapConfig.java @@ -0,0 +1,121 @@ +package com.raytheon.uf.common.datadelivery.service.subscription; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +/** + * Configuration for the {@link ISubscriptionOverlapService}. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Sept 24, 2013 2386       dhladky     Grid Subscription Overlap
+ * 
+ * 
+ * + * @author dhladky + * @version 1.0 + */ +@XmlRootElement +@XmlAccessorType(XmlAccessType.NONE) +public class GridSubscriptionOverlapConfig extends SubscriptionOverlapConfig { + + @XmlElement(required = true) + private int maxAllowedForecastHourDuplication; + + @XmlElement(required = true) + private int maxAllowedCycleDuplication; + + /** + * Constructor. + */ + public GridSubscriptionOverlapConfig() { + + } + + /** + * Constructor. + * + * @param maxAllowedParameterDuplication + * @param maxAllowedForecastHourDuplication + * @param maxAllowedCycleDuplication + * @param maxAllowedSpatialDuplication + * @param matchStrategy + */ + public GridSubscriptionOverlapConfig(int maxAllowedParameterDuplication, + int maxAllowedForecastHourDuplication, + int maxAllowedCycleDuplication, int maxAllowedSpatialDuplication, + SubscriptionOverlapMatchStrategy matchStrategy) { + + this.maxAllowedParameterDuplication = maxAllowedParameterDuplication; + this.maxAllowedForecastHourDuplication = maxAllowedForecastHourDuplication; + this.maxAllowedCycleDuplication = maxAllowedCycleDuplication; + this.maxAllowedSpatialDuplication = maxAllowedSpatialDuplication; + this.matchStrategy = matchStrategy; + } + + /** + * @return the maxAllowedForecastHourDuplication + */ + public int getMaxAllowedForecastHourDuplication() { + return maxAllowedForecastHourDuplication; + } + + /** + * @param maxAllowedForecastHourDuplication + * the maxAllowedForecastHourDuplication to set + */ + public void setMaxAllowedForecastHourDuplication( + int maxAllowedForecastHourDuplication) { + this.maxAllowedForecastHourDuplication = maxAllowedForecastHourDuplication; + } + + /** + * @return the maxAllowedCycleDuplication + */ + public int getMaxAllowedCycleDuplication() { + return maxAllowedCycleDuplication; + } + + /** + * @param maxAllowedCycleDuplication + * the maxAllowedCycleDuplication to set + */ + public void setMaxAllowedCycleDuplication(int maxAllowedCycleDuplication) { + this.maxAllowedCycleDuplication = maxAllowedCycleDuplication; + } + + /** + * Check whether the given duplication percents indicate an overlapping + * subscription. + * + * @param parameterDuplicationPercent + * @param forecastHourDuplicationPercent + * @param cycleDuplicationPercent + * @param spatialDuplicationPercent + * @return true if the subscription should be considered overlapping + */ + public boolean isOverlapping(int parameterDuplicationPercent, + int forecastHourDuplicationPercent, int cycleDuplicationPercent, + int spatialDuplicationPercent) { + + // Pass through to the match strategy + return this.matchStrategy.isOverlapping(this, + parameterDuplicationPercent, forecastHourDuplicationPercent, + cycleDuplicationPercent, spatialDuplicationPercent); + } + + public SubscriptionOverlapConfig getNeverOverlaps() { + return new GridSubscriptionOverlapConfig( + ISubscriptionOverlapService.ONE_HUNDRED_PERCENT, + ISubscriptionOverlapService.ONE_HUNDRED_PERCENT, + ISubscriptionOverlapService.ONE_HUNDRED_PERCENT, + ISubscriptionOverlapService.ONE_HUNDRED_PERCENT, + SubscriptionOverlapMatchStrategy.MATCH_ALL); + } + +} diff --git a/edexOsgi/com.raytheon.uf.common.datadelivery.service/src/com/raytheon/uf/common/datadelivery/service/subscription/ISubscriptionDuplicateChecker.java b/edexOsgi/com.raytheon.uf.common.datadelivery.service/src/com/raytheon/uf/common/datadelivery/service/subscription/ISubscriptionDuplicateChecker.java index d2e5f2f6d3..f80ddae124 100644 --- a/edexOsgi/com.raytheon.uf.common.datadelivery.service/src/com/raytheon/uf/common/datadelivery/service/subscription/ISubscriptionDuplicateChecker.java +++ b/edexOsgi/com.raytheon.uf.common.datadelivery.service/src/com/raytheon/uf/common/datadelivery/service/subscription/ISubscriptionDuplicateChecker.java @@ -31,6 +31,7 @@ import com.raytheon.uf.common.datadelivery.registry.Subscription; * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- * May 02, 2013 2000 djohnson Initial creation + * Sept 24, 2013 2386 dhladky Added a method * * * @@ -60,6 +61,16 @@ public interface ISubscriptionDuplicateChecker { * @return 0-100 */ int getForecastHourDuplicationPercent(Subscription sub1, Subscription sub2); + + /** + * Returns the percent, 0-100, of how similar the time is from sub2 to sub1. + * + * @param sub1 + * @param sub2 + * + * @return 0-100 + */ + int getTimeDuplicationPercent(Subscription sub1, Subscription sub2); /** * Returns the percent, 0-100, of how many cycle hours from sub2 are diff --git a/edexOsgi/com.raytheon.uf.common.datadelivery.service/src/com/raytheon/uf/common/datadelivery/service/subscription/ISubscriptionOverlapService.java b/edexOsgi/com.raytheon.uf.common.datadelivery.service/src/com/raytheon/uf/common/datadelivery/service/subscription/ISubscriptionOverlapService.java index cac7b333b1..34455114c8 100644 --- a/edexOsgi/com.raytheon.uf.common.datadelivery.service/src/com/raytheon/uf/common/datadelivery/service/subscription/ISubscriptionOverlapService.java +++ b/edexOsgi/com.raytheon.uf.common.datadelivery.service/src/com/raytheon/uf/common/datadelivery/service/subscription/ISubscriptionOverlapService.java @@ -19,6 +19,9 @@ **/ package com.raytheon.uf.common.datadelivery.service.subscription; +import java.util.Map; + +import com.raytheon.uf.common.datadelivery.registry.DataType; import com.raytheon.uf.common.datadelivery.registry.Subscription; import com.raytheon.uf.common.localization.exception.LocalizationException; @@ -79,7 +82,7 @@ public interface ISubscriptionOverlapService { Subscription sub2); /** - * Writes the new configuration. + * Writes a new configuration file. * * @param config * the configuration @@ -92,9 +95,9 @@ public interface ISubscriptionOverlapService { /** * Read the configuration. * - * @return the configuration + * @return the configurations * @throws LocalizationException * on error reading the configuration */ - SubscriptionOverlapConfig readConfig() throws LocalizationException; + Map readConfig() throws LocalizationException; } \ No newline at end of file diff --git a/edexOsgi/com.raytheon.uf.common.datadelivery.service/src/com/raytheon/uf/common/datadelivery/service/subscription/PointSubscriptionOverlapConfig.java b/edexOsgi/com.raytheon.uf.common.datadelivery.service/src/com/raytheon/uf/common/datadelivery/service/subscription/PointSubscriptionOverlapConfig.java new file mode 100644 index 0000000000..22309b63e5 --- /dev/null +++ b/edexOsgi/com.raytheon.uf.common.datadelivery.service/src/com/raytheon/uf/common/datadelivery/service/subscription/PointSubscriptionOverlapConfig.java @@ -0,0 +1,104 @@ +package com.raytheon.uf.common.datadelivery.service.subscription; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + +/** + * Configuration for the {@link ISubscriptionOverlapService}. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Sept 24, 2013 2386       dhladky     Point Subscription Overlap
+ * 
+ * 
+ * + * @author dhladky + * @version 1.0 + */ +@XmlRootElement +@XmlAccessorType(XmlAccessType.NONE) +public class PointSubscriptionOverlapConfig extends SubscriptionOverlapConfig { + + @XmlElement(required = true) + private int maxAllowedTimeDuplication; + + /** + * Constructor. + */ + public PointSubscriptionOverlapConfig() { + + } + + /** + * Constructor. + * + * @param maxAllowedParameterDuplication + * @param maxAllowedTimeDuplication + * @param notUsed + * @param maxAllowedSpatialDuplication + * @param matchStrategy + */ + public PointSubscriptionOverlapConfig(int maxAllowedParameterDuplication, + int maxAllowedTimeDuplication, int notUsed, + int maxAllowedSpatialDuplication, + SubscriptionOverlapMatchStrategy matchStrategy) { + + this.maxAllowedParameterDuplication = maxAllowedParameterDuplication; + this.maxAllowedTimeDuplication = maxAllowedTimeDuplication; + this.maxAllowedSpatialDuplication = maxAllowedSpatialDuplication; + this.matchStrategy = matchStrategy; + } + + /** + * @return the maxAllowedTimeDuplication + */ + public int getMaxAllowedTimeDuplication() { + return maxAllowedTimeDuplication; + } + + /** + * @param maxAllowedForecastHourDuplication + * the maxAllowedForecastHourDuplication to set + */ + public void setMaxAllowedTimeDuplication(int maxAllowedTimeDuplication) { + this.maxAllowedTimeDuplication = maxAllowedTimeDuplication; + } + + /** + * Check whether the given duplication percents indicate an overlapping + * subscription. + * + * @param parameterDuplicationPercent + * @param timeDuplicationPercent + * @param notUsed + * @param spatialDuplicationPercent + * @return true if the subscription should be considered overlapping + */ + public boolean isOverlapping(int parameterDuplicationPercent, + int timeDuplicationPercent, int notUsed, + int spatialDuplicationPercent) { + + // Pass through to the match strategy + return this.matchStrategy.isOverlapping(this, + parameterDuplicationPercent, timeDuplicationPercent, notUsed, + spatialDuplicationPercent); + } + + @Override + public SubscriptionOverlapConfig getNeverOverlaps() { + return new PointSubscriptionOverlapConfig( + ISubscriptionOverlapService.ONE_HUNDRED_PERCENT, + ISubscriptionOverlapService.ONE_HUNDRED_PERCENT, + ISubscriptionOverlapService.ONE_HUNDRED_PERCENT, + ISubscriptionOverlapService.ONE_HUNDRED_PERCENT, + SubscriptionOverlapMatchStrategy.MATCH_ALL); + + } + +} diff --git a/edexOsgi/com.raytheon.uf.common.datadelivery.service/src/com/raytheon/uf/common/datadelivery/service/subscription/SubscriptionDuplicateChecker.java b/edexOsgi/com.raytheon.uf.common.datadelivery.service/src/com/raytheon/uf/common/datadelivery/service/subscription/SubscriptionDuplicateChecker.java index dc07449a42..38bc00df23 100644 --- a/edexOsgi/com.raytheon.uf.common.datadelivery.service/src/com/raytheon/uf/common/datadelivery/service/subscription/SubscriptionDuplicateChecker.java +++ b/edexOsgi/com.raytheon.uf.common.datadelivery.service/src/com/raytheon/uf/common/datadelivery/service/subscription/SubscriptionDuplicateChecker.java @@ -25,6 +25,7 @@ import org.geotools.geometry.jts.ReferencedEnvelope; import org.opengis.referencing.operation.TransformException; import com.raytheon.uf.common.datadelivery.registry.Coverage; +import com.raytheon.uf.common.datadelivery.registry.PointTime; import com.raytheon.uf.common.datadelivery.registry.Subscription; import com.raytheon.uf.common.geospatial.MapUtil; import com.raytheon.uf.common.status.IUFStatusHandler; @@ -42,6 +43,7 @@ import com.raytheon.uf.common.util.CollectionUtil; * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- * May 02, 2013 2000 djohnson Initial creation + * Sept 24, 2013 2386 dhladky Made multi-data type * * * @@ -85,6 +87,16 @@ public class SubscriptionDuplicateChecker implements .getTime().getCycleTimes()); } + /** + * {@inheritDoc} + */ + @Override + public int getTimeDuplicationPercent(Subscription sub1, Subscription sub2) { + + return getDuplicationPercent(((PointTime) sub1.getTime()).getTimes(), + ((PointTime) sub2.getTime()).getTimes()); + } + /** * {@inheritDoc} */ diff --git a/edexOsgi/com.raytheon.uf.common.datadelivery.service/src/com/raytheon/uf/common/datadelivery/service/subscription/SubscriptionOverlapConfig.java b/edexOsgi/com.raytheon.uf.common.datadelivery.service/src/com/raytheon/uf/common/datadelivery/service/subscription/SubscriptionOverlapConfig.java index a0f2deedb2..8d6164d73a 100644 --- a/edexOsgi/com.raytheon.uf.common.datadelivery.service/src/com/raytheon/uf/common/datadelivery/service/subscription/SubscriptionOverlapConfig.java +++ b/edexOsgi/com.raytheon.uf.common.datadelivery.service/src/com/raytheon/uf/common/datadelivery/service/subscription/SubscriptionOverlapConfig.java @@ -34,6 +34,7 @@ import javax.xml.bind.annotation.XmlRootElement; * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- * May 08, 2013 2000 djohnson Initial creation + * Sept 24, 2013 2386 dhladky Abstracted for more types * * * @@ -42,54 +43,22 @@ import javax.xml.bind.annotation.XmlRootElement; */ @XmlRootElement @XmlAccessorType(XmlAccessType.NONE) -public class SubscriptionOverlapConfig { - - public static final SubscriptionOverlapConfig NEVER_OVERLAPS = new SubscriptionOverlapConfig( - ISubscriptionOverlapService.ONE_HUNDRED_PERCENT, - ISubscriptionOverlapService.ONE_HUNDRED_PERCENT, - ISubscriptionOverlapService.ONE_HUNDRED_PERCENT, - ISubscriptionOverlapService.ONE_HUNDRED_PERCENT, - SubscriptionOverlapMatchStrategy.MATCH_ALL); +public abstract class SubscriptionOverlapConfig { + + @XmlElement(required = true) + protected int maxAllowedParameterDuplication; @XmlElement(required = true) - private int maxAllowedParameterDuplication; - + protected int maxAllowedSpatialDuplication; + @XmlElement(required = true) - private int maxAllowedForecastHourDuplication; - - @XmlElement(required = true) - private int maxAllowedCycleDuplication; - - @XmlElement(required = true) - private int maxAllowedSpatialDuplication; - - @XmlElement(required = true) - private SubscriptionOverlapMatchStrategy matchStrategy; + protected SubscriptionOverlapMatchStrategy matchStrategy; /** * Constructor. */ public SubscriptionOverlapConfig() { - } - /** - * Constructor. - * - * @param maxAllowedParameterDuplication - * @param maxAllowedForecastHourDuplication - * @param maxAllowedCycleDuplication - * @param maxAllowedSpatialDuplication - * @param matchStrategy - */ - public SubscriptionOverlapConfig(int maxAllowedParameterDuplication, - int maxAllowedForecastHourDuplication, - int maxAllowedCycleDuplication, int maxAllowedSpatialDuplication, - SubscriptionOverlapMatchStrategy matchStrategy) { - this.maxAllowedParameterDuplication = maxAllowedParameterDuplication; - this.maxAllowedForecastHourDuplication = maxAllowedForecastHourDuplication; - this.maxAllowedCycleDuplication = maxAllowedCycleDuplication; - this.maxAllowedSpatialDuplication = maxAllowedSpatialDuplication; - this.matchStrategy = matchStrategy; } /** @@ -108,37 +77,6 @@ public class SubscriptionOverlapConfig { this.maxAllowedParameterDuplication = maxAllowedParameterDuplication; } - /** - * @return the maxAllowedForecastHourDuplication - */ - public int getMaxAllowedForecastHourDuplication() { - return maxAllowedForecastHourDuplication; - } - - /** - * @param maxAllowedForecastHourDuplication - * the maxAllowedForecastHourDuplication to set - */ - public void setMaxAllowedForecastHourDuplication( - int maxAllowedForecastHourDuplication) { - this.maxAllowedForecastHourDuplication = maxAllowedForecastHourDuplication; - } - - /** - * @return the maxAllowedCycleDuplication - */ - public int getMaxAllowedCycleDuplication() { - return maxAllowedCycleDuplication; - } - - /** - * @param maxAllowedCycleDuplication - * the maxAllowedCycleDuplication to set - */ - public void setMaxAllowedCycleDuplication(int maxAllowedCycleDuplication) { - this.maxAllowedCycleDuplication = maxAllowedCycleDuplication; - } - /** * @return the maxAllowedSpatialDuplication */ @@ -174,18 +112,18 @@ public class SubscriptionOverlapConfig { * subscription. * * @param parameterDuplicationPercent - * @param forecastHourDuplicationPercent - * @param cycleDuplicationPercent + * @param forecastHourOrTimeDuplicationPercent + * @param cycleOrNotUsedDuplicationPercent * @param spatialDuplicationPercent * @return true if the subscription should be considered overlapping */ - public boolean isOverlapping(int parameterDuplicationPercent, - int forecastHourDuplicationPercent, int cycleDuplicationPercent, - int spatialDuplicationPercent) { + public abstract boolean isOverlapping(int parameterDuplicationPercent, + int forecastHourOrTimeDuplicationPercent, int cycleOrNotUsedDuplicationPercent, + int spatialDuplicationPercent); + + /** + * setup a default never overlapping config + */ + public abstract SubscriptionOverlapConfig getNeverOverlaps(); - // Pass through to the match strategy - return this.matchStrategy.isOverlapping(this, - parameterDuplicationPercent, forecastHourDuplicationPercent, - cycleDuplicationPercent, spatialDuplicationPercent); - } } diff --git a/edexOsgi/com.raytheon.uf.common.datadelivery.service/src/com/raytheon/uf/common/datadelivery/service/subscription/SubscriptionOverlapMatchStrategy.java b/edexOsgi/com.raytheon.uf.common.datadelivery.service/src/com/raytheon/uf/common/datadelivery/service/subscription/SubscriptionOverlapMatchStrategy.java index 93596fbd72..de47ddc4fb 100644 --- a/edexOsgi/com.raytheon.uf.common.datadelivery.service/src/com/raytheon/uf/common/datadelivery/service/subscription/SubscriptionOverlapMatchStrategy.java +++ b/edexOsgi/com.raytheon.uf.common.datadelivery.service/src/com/raytheon/uf/common/datadelivery/service/subscription/SubscriptionOverlapMatchStrategy.java @@ -1,3 +1,5 @@ +package com.raytheon.uf.common.datadelivery.service.subscription; + /** * This software was developed and / or modified by Raytheon Company, * pursuant to Contract DG133W-05-CQ-1067 with the US Government. @@ -17,8 +19,6 @@ * See the AWIPS II Master Rights File ("Master Rights File.pdf") for * further licensing information. **/ -package com.raytheon.uf.common.datadelivery.service.subscription; - import javax.xml.bind.annotation.XmlEnum; /** @@ -32,6 +32,7 @@ import javax.xml.bind.annotation.XmlEnum; * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- * May 14, 2013 2000 djohnson Initial creation + * Sept 24, 2013 2386 dhladky Added impl for other types besides grid * * * @@ -46,20 +47,43 @@ public enum SubscriptionOverlapMatchStrategy { int parameterDuplicationPercent, int forecastHourDuplicationPercent, int cycleDuplicationPercent, int spatialDuplicationPercent) { + + boolean[] toCheck = null; + final boolean exceedsAllowedParameterDuplication = parameterDuplicationPercent > config .getMaxAllowedParameterDuplication(); - final boolean exceedsAllowedForecastHourDuplication = forecastHourDuplicationPercent > config - .getMaxAllowedForecastHourDuplication(); - final boolean exceedsAllowedCycleDuplication = cycleDuplicationPercent > config - .getMaxAllowedCycleDuplication(); final boolean exceedsAllowedSpatialDuplication = spatialDuplicationPercent > config .getMaxAllowedSpatialDuplication(); - boolean[] toCheck = new boolean[] { - exceedsAllowedParameterDuplication, - exceedsAllowedForecastHourDuplication, - exceedsAllowedCycleDuplication, - exceedsAllowedSpatialDuplication }; + // gridded products + if (config instanceof GridSubscriptionOverlapConfig) { + + GridSubscriptionOverlapConfig gconfig = (GridSubscriptionOverlapConfig) config; + + final boolean exceedsAllowedForecastHourDuplication = forecastHourDuplicationPercent > gconfig + .getMaxAllowedForecastHourDuplication(); + final boolean exceedsAllowedCycleDuplication = cycleDuplicationPercent > gconfig + .getMaxAllowedCycleDuplication(); + + toCheck = new boolean[] { exceedsAllowedParameterDuplication, + exceedsAllowedForecastHourDuplication, + exceedsAllowedCycleDuplication, + exceedsAllowedSpatialDuplication }; + } + // point products + else if (config instanceof PointSubscriptionOverlapConfig) { + PointSubscriptionOverlapConfig pconfig = (PointSubscriptionOverlapConfig) config; + + final boolean exceedsAllowedTimeDuplication = forecastHourDuplicationPercent > pconfig + .getMaxAllowedTimeDuplication(); + + toCheck = new boolean[] { exceedsAllowedParameterDuplication, + exceedsAllowedTimeDuplication, + exceedsAllowedSpatialDuplication }; + } else { + throw new IllegalArgumentException("Data type "+config.getClass()+" has no implementation"); + } + final int numBooleans = toCheck.length; final int halfNumBooleans = numBooleans / 2; @@ -87,19 +111,45 @@ public enum SubscriptionOverlapMatchStrategy { int forecastHourDuplicationPercent, int cycleDuplicationPercent, int spatialDuplicationPercent) { + boolean response = false; + final boolean exceedsAllowedParameterDuplication = parameterDuplicationPercent > config .getMaxAllowedParameterDuplication(); - final boolean exceedsAllowedForecastHourDuplication = forecastHourDuplicationPercent > config - .getMaxAllowedForecastHourDuplication(); - final boolean exceedsAllowedCycleDuplication = cycleDuplicationPercent > config - .getMaxAllowedCycleDuplication(); + final boolean exceedsAllowedSpatialDuplication = spatialDuplicationPercent > config .getMaxAllowedSpatialDuplication(); - return exceedsAllowedParameterDuplication - && exceedsAllowedForecastHourDuplication - && exceedsAllowedCycleDuplication - && exceedsAllowedSpatialDuplication; + // gridded products + if (config instanceof GridSubscriptionOverlapConfig) { + + GridSubscriptionOverlapConfig gconfig = (GridSubscriptionOverlapConfig) config; + + final boolean exceedsAllowedForecastHourDuplication = forecastHourDuplicationPercent > gconfig + .getMaxAllowedForecastHourDuplication(); + final boolean exceedsAllowedCycleDuplication = cycleDuplicationPercent > gconfig + .getMaxAllowedCycleDuplication(); + + response = exceedsAllowedParameterDuplication + && exceedsAllowedForecastHourDuplication + && exceedsAllowedCycleDuplication + && exceedsAllowedSpatialDuplication; + + // point products + } else if (config instanceof PointSubscriptionOverlapConfig) { + PointSubscriptionOverlapConfig pconfig = (PointSubscriptionOverlapConfig) config; + + final boolean exceedsAllowedTimeDuplication = forecastHourDuplicationPercent > pconfig + .getMaxAllowedTimeDuplication(); + + response = exceedsAllowedParameterDuplication + && exceedsAllowedTimeDuplication + && exceedsAllowedSpatialDuplication; + } else { + throw new IllegalArgumentException("Data type "+config.getClass()+" has no implementation"); + } + + + return response; } @Override @@ -113,20 +163,44 @@ public enum SubscriptionOverlapMatchStrategy { int parameterDuplicationPercent, int forecastHourDuplicationPercent, int cycleDuplicationPercent, int spatialDuplicationPercent) { + + boolean response = false; final boolean exceedsAllowedParameterDuplication = parameterDuplicationPercent > config .getMaxAllowedParameterDuplication(); - final boolean exceedsAllowedForecastHourDuplication = forecastHourDuplicationPercent > config - .getMaxAllowedForecastHourDuplication(); - final boolean exceedsAllowedCycleDuplication = cycleDuplicationPercent > config - .getMaxAllowedCycleDuplication(); + final boolean exceedsAllowedSpatialDuplication = spatialDuplicationPercent > config .getMaxAllowedSpatialDuplication(); - return exceedsAllowedParameterDuplication - || exceedsAllowedForecastHourDuplication - || exceedsAllowedCycleDuplication - || exceedsAllowedSpatialDuplication; + // gridded products + if (config instanceof GridSubscriptionOverlapConfig) { + GridSubscriptionOverlapConfig gconfig = (GridSubscriptionOverlapConfig) config; + + final boolean exceedsAllowedForecastHourDuplication = forecastHourDuplicationPercent > gconfig + .getMaxAllowedForecastHourDuplication(); + final boolean exceedsAllowedCycleDuplication = cycleDuplicationPercent > gconfig + .getMaxAllowedCycleDuplication(); + + response = exceedsAllowedParameterDuplication + || exceedsAllowedForecastHourDuplication + || exceedsAllowedCycleDuplication + || exceedsAllowedSpatialDuplication; + } + // point products + else if (config instanceof PointSubscriptionOverlapConfig) { + PointSubscriptionOverlapConfig pconfig = (PointSubscriptionOverlapConfig) config; + + final boolean exceedsAllowedTimeDuplication = forecastHourDuplicationPercent > pconfig + .getMaxAllowedTimeDuplication(); + + response = exceedsAllowedParameterDuplication + || exceedsAllowedTimeDuplication + || exceedsAllowedSpatialDuplication; + } else { + throw new IllegalArgumentException("Data type "+config.getClass()+" has no implementation"); + } + + return response; } @Override @@ -141,8 +215,8 @@ public enum SubscriptionOverlapMatchStrategy { * * @param config * @param parameterDuplicationPercent - * @param forecastHourDuplicationPercent - * @param cycleDuplicationPercent + * @param forecastHourDuplicationPercent or timeDuplicatePercent + * @param cycleDuplicationPercent or notUsed * @param spatialDuplicationPercent * @return true if the subscription should be considered overlapping */ @@ -158,3 +232,4 @@ public enum SubscriptionOverlapMatchStrategy { */ public abstract String getDisplayString(); } + diff --git a/edexOsgi/com.raytheon.uf.common.datadelivery.service/src/com/raytheon/uf/common/datadelivery/service/subscription/SubscriptionOverlapService.java b/edexOsgi/com.raytheon.uf.common.datadelivery.service/src/com/raytheon/uf/common/datadelivery/service/subscription/SubscriptionOverlapService.java index 3db4eda678..f277c17d55 100644 --- a/edexOsgi/com.raytheon.uf.common.datadelivery.service/src/com/raytheon/uf/common/datadelivery/service/subscription/SubscriptionOverlapService.java +++ b/edexOsgi/com.raytheon.uf.common.datadelivery.service/src/com/raytheon/uf/common/datadelivery/service/subscription/SubscriptionOverlapService.java @@ -19,11 +19,13 @@ **/ package com.raytheon.uf.common.datadelivery.service.subscription; +import java.util.HashMap; import java.util.Map; import java.util.MissingResourceException; import javax.xml.bind.JAXBException; +import com.raytheon.uf.common.datadelivery.registry.DataType; import com.raytheon.uf.common.datadelivery.registry.Subscription; import com.raytheon.uf.common.localization.IPathManager; import com.raytheon.uf.common.localization.LocalizationContext; @@ -48,6 +50,7 @@ import com.raytheon.uf.common.status.UFStatus.Priority; * ------------ ---------- ----------- -------------------------- * May 07, 2013 2000 djohnson Initial creation * Jun 04, 2013 223 mpduff Get base file if site doesn't exist. + * Sept 23, 2013 2283 dhladky Updated for multiple configs * * * @@ -103,7 +106,9 @@ public class SubscriptionOverlapService implements ISubscriptionOverlapService { private static final String UNABLE_TO_UNMARSHAL = "Unable to unmarshal the configuration file. " + "No subscriptions will be considered to overlap!"; - private static final String SUBSCRIPTION_OVERLAP_CONFIG_FILE_PATH = "datadelivery/subscriptionOverlapRules.xml"; + private static final String SUBSCRIPTION_OVERLAP_CONFIG_FILE_ROOT = "SubscriptionOverlapRules.xml"; + + private static final String SUBSCRIPTION_OVERLAP_CONFIG_FILE_PATH = "datadelivery/"; private final ISubscriptionDuplicateChecker duplicateChecker; @@ -119,7 +124,11 @@ public class SubscriptionOverlapService implements ISubscriptionOverlapService { this.duplicateChecker = duplicateChecker; try { - jaxbManager = new JAXBManager(SubscriptionOverlapConfig.class); + @SuppressWarnings("rawtypes") + Class[] clazzes = new Class[]{SubscriptionOverlapConfig.class, + GridSubscriptionOverlapConfig.class, + PointSubscriptionOverlapConfig.class}; + jaxbManager = new JAXBManager(clazzes); } catch (JAXBException e) { throw new ExceptionInInitializerError(e); } @@ -135,26 +144,74 @@ public class SubscriptionOverlapService implements ISubscriptionOverlapService { if (sub1.getName().equals(sub2.getName())) { return new SubscriptionOverlapResponse(false, false); } + + // Ignore requests where the two subscriptions are of different types + if (!sub1.getDataSetType().equals(sub2.getDataSetType())) { + return new SubscriptionOverlapResponse(false, false); + } + + SubscriptionOverlapConfig config = getConfigFile(sub1.getDataSetType()); + + return getOverlap(config, sub1, sub2); + } + /** + * {@inheritDoc} + */ + @Override + public void writeConfig(SubscriptionOverlapConfig config) + throws LocalizationException { final IPathManager pathManager = PathManagerFactory.getPathManager(); + LocalizationContext context = pathManager.getContext( + LocalizationType.COMMON_STATIC, LocalizationLevel.SITE); + + String fileName = null; + + if (config instanceof PointSubscriptionOverlapConfig) { + fileName = SUBSCRIPTION_OVERLAP_CONFIG_FILE_PATH+DataType.POINT.name()+SUBSCRIPTION_OVERLAP_CONFIG_FILE_ROOT; + } else if (config instanceof GridSubscriptionOverlapConfig) { + fileName = SUBSCRIPTION_OVERLAP_CONFIG_FILE_PATH+DataType.GRID.name()+SUBSCRIPTION_OVERLAP_CONFIG_FILE_ROOT; + } else { + throw new IllegalArgumentException(config.getClass()+" Doesn't have any implementation in use"); + } + + final LocalizationFile configFile = pathManager + .getLocalizationFile( + context, + fileName); + configFile.jaxbMarshal(config, jaxbManager); + } - final LocalizationFile localizationFile = pathManager - .getStaticLocalizationFile(SUBSCRIPTION_OVERLAP_CONFIG_FILE_PATH); + /** + * {@inheritDoc} + * + * @throws LocalizationException + */ + @Override + public Map readConfig() + throws LocalizationException { - SubscriptionOverlapConfig config; - try { - if (!localizationFile.exists()) { - throw new MissingResourceException(localizationFile.getName() - + " does not exist.", - SubscriptionOverlapConfig.class.getName(), ""); + HashMap configs = new HashMap(); + + for (DataType type : DataType.values()) { + SubscriptionOverlapConfig config = getConfigFile(type); + if (config != null) { + configs.put(type, config); } - config = localizationFile.jaxbUnmarshal( - SubscriptionOverlapConfig.class, jaxbManager); - } catch (Exception e) { - statusHandler.handle(Priority.PROBLEM, UNABLE_TO_UNMARSHAL, e); - config = SubscriptionOverlapConfig.NEVER_OVERLAPS; } + return configs; + } + + /** + * Process a set of Gridded subscriptions for duplication; + * @param config + * @param sub1 + * @param sub2 + * @return + */ + private SubscriptionOverlapResponse processGriddedSubscriptionOverlap(GridSubscriptionOverlapConfig config, Subscription sub1, Subscription sub2) { + final int parameterDuplicationPercent = duplicateChecker .getParameterDuplicationPercent(sub1, sub2); final int forecastHourDuplicationPercent = duplicateChecker @@ -175,46 +232,100 @@ public class SubscriptionOverlapService implements ISubscriptionOverlapService { return new SubscriptionOverlapResponse(duplicate, overlaps); } - - /** - * {@inheritDoc} + + /*** + * Process a set of Point subscriptions for duplication + * @param config + * @param sub1 + * @param sub2 + * @return */ - @Override - public void writeConfig(SubscriptionOverlapConfig config) - throws LocalizationException { - final IPathManager pathManager = PathManagerFactory.getPathManager(); - LocalizationContext context = pathManager.getContext( - LocalizationType.COMMON_STATIC, LocalizationLevel.SITE); - final LocalizationFile configFile = pathManager - .getLocalizationFile( - context, - SubscriptionOverlapService.SUBSCRIPTION_OVERLAP_CONFIG_FILE_PATH); - configFile.jaxbMarshal(config, jaxbManager); + private SubscriptionOverlapResponse processPointSubscriptionOverlap(PointSubscriptionOverlapConfig config, Subscription sub1, Subscription sub2) { + + final int parameterDuplicationPercent = duplicateChecker + .getParameterDuplicationPercent(sub1, sub2); + final int timeDuplicationPercent = duplicateChecker + .getTimeDuplicationPercent(sub1, sub2); + final int spatialDuplicationPercent = duplicateChecker + .getSpatialDuplicationPercent(sub1, sub2); + + final boolean overlaps = config.isOverlapping( + parameterDuplicationPercent, timeDuplicationPercent, + 0, spatialDuplicationPercent); + + final boolean duplicate = (parameterDuplicationPercent == ONE_HUNDRED_PERCENT) + && (timeDuplicationPercent == ONE_HUNDRED_PERCENT) + && (spatialDuplicationPercent == ONE_HUNDRED_PERCENT); + + return new SubscriptionOverlapResponse(duplicate, overlaps); } - + /** - * {@inheritDoc} - * - * @throws LocalizationException + * Gets the overlap config file by type + * @param type + * @return */ - @Override - public SubscriptionOverlapConfig readConfig() throws LocalizationException { + private SubscriptionOverlapConfig getConfigFile(DataType type) { + final IPathManager pathManager = PathManagerFactory.getPathManager(); - Map configFileMap = pathManager - .getTieredLocalizationFile( - LocalizationType.COMMON_STATIC, - SubscriptionOverlapService.SUBSCRIPTION_OVERLAP_CONFIG_FILE_PATH); + LocalizationFile localizationFile = null; + SubscriptionOverlapConfig config = null; + localizationFile = pathManager + .getStaticLocalizationFile(SUBSCRIPTION_OVERLAP_CONFIG_FILE_PATH+type.name()+SUBSCRIPTION_OVERLAP_CONFIG_FILE_ROOT); + + try { + if (!localizationFile.exists()) { + throw new MissingResourceException(localizationFile.getName() + + " does not exist.", + SubscriptionOverlapConfig.class.getName(), "Not yet implemented!"); + } - LocalizationFile configFile = null; + if (type == DataType.GRID) { + config = localizationFile.jaxbUnmarshal( + GridSubscriptionOverlapConfig.class, jaxbManager); - if (configFileMap.containsKey(LocalizationLevel.SITE)) { - configFile = configFileMap.get(LocalizationLevel.SITE); - } else { - configFile = configFileMap.get(LocalizationLevel.BASE); + } else if (type == DataType.POINT) { + config = localizationFile.jaxbUnmarshal( + PointSubscriptionOverlapConfig.class, jaxbManager); + + } + + } catch (Exception e) { + statusHandler.handle(Priority.PROBLEM, UNABLE_TO_UNMARSHAL, e.getLocalizedMessage()); + // this a fall back so at least some checking gets done + if (type == DataType.GRID) { + config = new GridSubscriptionOverlapConfig().getNeverOverlaps(); + } else if (type == DataType.POINT) { + config = new PointSubscriptionOverlapConfig().getNeverOverlaps(); + } } - - return configFile.jaxbUnmarshal(SubscriptionOverlapConfig.class, - jaxbManager); + + return config; + } + + /** + * Gets the SubscriptionOverlapResponse by type + * @param config + * @param sub1 + * @param sub2 + * @return + */ + private SubscriptionOverlapResponse getOverlap(SubscriptionOverlapConfig config, Subscription sub1, Subscription sub2) { + + SubscriptionOverlapResponse response = null; + DataType type = sub1.getDataSetType(); + + if (type == DataType.GRID) { + response = processGriddedSubscriptionOverlap( + (GridSubscriptionOverlapConfig) config, sub1, sub2); + } else if (type == DataType.POINT) { + response = processPointSubscriptionOverlap( + (PointSubscriptionOverlapConfig) config, sub1, sub2); + } else { + throw new IllegalArgumentException(type + + " Config not yet Implemented!"); + } + + return response; } - } diff --git a/edexOsgi/com.raytheon.uf.common.datadelivery.service/utility/common_static/base/datadelivery/subscriptionOverlapRules.xml b/edexOsgi/com.raytheon.uf.common.datadelivery.service/utility/common_static/base/datadelivery/GRIDSubscriptionOverlapRules.xml similarity index 93% rename from edexOsgi/com.raytheon.uf.common.datadelivery.service/utility/common_static/base/datadelivery/subscriptionOverlapRules.xml rename to edexOsgi/com.raytheon.uf.common.datadelivery.service/utility/common_static/base/datadelivery/GRIDSubscriptionOverlapRules.xml index 93b7226aa0..49a28d781e 100644 --- a/edexOsgi/com.raytheon.uf.common.datadelivery.service/utility/common_static/base/datadelivery/subscriptionOverlapRules.xml +++ b/edexOsgi/com.raytheon.uf.common.datadelivery.service/utility/common_static/base/datadelivery/GRIDSubscriptionOverlapRules.xml @@ -1,5 +1,5 @@ - + 65 65 @@ -18,4 +18,4 @@ overlapping. --> MATCH_ANY - \ No newline at end of file + \ No newline at end of file diff --git a/edexOsgi/com.raytheon.uf.common.datadelivery.service/utility/common_static/base/datadelivery/POINTSubscriptionOverlapRules.xml b/edexOsgi/com.raytheon.uf.common.datadelivery.service/utility/common_static/base/datadelivery/POINTSubscriptionOverlapRules.xml new file mode 100644 index 0000000000..3da69d8bb2 --- /dev/null +++ b/edexOsgi/com.raytheon.uf.common.datadelivery.service/utility/common_static/base/datadelivery/POINTSubscriptionOverlapRules.xml @@ -0,0 +1,20 @@ + + + + 65 + 65 + 65 + + MATCH_ANY + \ No newline at end of file diff --git a/tests/unit/com/raytheon/uf/common/datadelivery/service/subscription/SubscriptionOverlapMatchStrategyTest.java b/tests/unit/com/raytheon/uf/common/datadelivery/service/subscription/GridSubscriptionOverlapMatchStrategyTest.java similarity index 96% rename from tests/unit/com/raytheon/uf/common/datadelivery/service/subscription/SubscriptionOverlapMatchStrategyTest.java rename to tests/unit/com/raytheon/uf/common/datadelivery/service/subscription/GridSubscriptionOverlapMatchStrategyTest.java index e256ebd9d3..5602cf6ce2 100644 --- a/tests/unit/com/raytheon/uf/common/datadelivery/service/subscription/SubscriptionOverlapMatchStrategyTest.java +++ b/tests/unit/com/raytheon/uf/common/datadelivery/service/subscription/GridSubscriptionOverlapMatchStrategyTest.java @@ -28,7 +28,7 @@ import static org.junit.Assert.assertThat; import org.junit.Test; /** - * Test {@link SubscriptionOverlapMatchStrategy}. + * Test {@link GridSubscriptionOverlapMatchStrategy}. * *
  * 
@@ -43,9 +43,9 @@ import org.junit.Test;
  * @author djohnson
  * @version 1.0
  */
-public class SubscriptionOverlapMatchStrategyTest {
+public class GridSubscriptionOverlapMatchStrategyTest {
 
-    private static final SubscriptionOverlapConfig MUST_EXCEED_FIFTY_PERCENT = new SubscriptionOverlapConfig(
+    private static final SubscriptionOverlapConfig MUST_EXCEED_FIFTY_PERCENT = new GridSubscriptionOverlapConfig(
             50, 50, 50, 50, null);
 
     @Test
diff --git a/tests/unit/com/raytheon/uf/common/datadelivery/service/subscription/SubscriptionOverlapServiceTest.java b/tests/unit/com/raytheon/uf/common/datadelivery/service/subscription/GridSubscriptionOverlapServiceTest.java
similarity index 98%
rename from tests/unit/com/raytheon/uf/common/datadelivery/service/subscription/SubscriptionOverlapServiceTest.java
rename to tests/unit/com/raytheon/uf/common/datadelivery/service/subscription/GridSubscriptionOverlapServiceTest.java
index abc5767e28..7824ec68bb 100644
--- a/tests/unit/com/raytheon/uf/common/datadelivery/service/subscription/SubscriptionOverlapServiceTest.java
+++ b/tests/unit/com/raytheon/uf/common/datadelivery/service/subscription/GridSubscriptionOverlapServiceTest.java
@@ -52,12 +52,12 @@ import com.raytheon.uf.common.localization.exception.LocalizationException;
  * @version 1.0
  */
 
-public class SubscriptionOverlapServiceTest {
+public class GridSubscriptionOverlapServiceTest {
 
-    private static final SubscriptionOverlapConfig ANY_MUST_EXCEED_65_PERCENT = new SubscriptionOverlapConfig(
+    private static final SubscriptionOverlapConfig ANY_MUST_EXCEED_65_PERCENT = new GridSubscriptionOverlapConfig(
             65, 65, 65, 65, MATCH_ANY);
 
-    private static final SubscriptionOverlapConfig ALL_MUST_EXCEED_65_PERCENT = new SubscriptionOverlapConfig(
+    private static final SubscriptionOverlapConfig ALL_MUST_EXCEED_65_PERCENT = new GridSubscriptionOverlapConfig(
             65, 65, 65, 65, MATCH_ALL);
 
     private final ISubscriptionDuplicateChecker duplicateChecker = mock(ISubscriptionDuplicateChecker.class);
diff --git a/tests/unit/com/raytheon/uf/common/datadelivery/service/subscription/PointSubscriptionOverlapMatchStrategyTest.java b/tests/unit/com/raytheon/uf/common/datadelivery/service/subscription/PointSubscriptionOverlapMatchStrategyTest.java
new file mode 100644
index 0000000000..0f366b3618
--- /dev/null
+++ b/tests/unit/com/raytheon/uf/common/datadelivery/service/subscription/PointSubscriptionOverlapMatchStrategyTest.java
@@ -0,0 +1,131 @@
+/**
+ * This software was developed and / or modified by Raytheon Company,
+ * pursuant to Contract DG133W-05-CQ-1067 with the US Government.
+ * 
+ * U.S. EXPORT CONTROLLED TECHNICAL DATA
+ * This software product contains export-restricted data whose
+ * export/transfer/disclosure is restricted by U.S. law. Dissemination
+ * to non-U.S. persons whether in the United States or abroad requires
+ * an export license or other authorization.
+ * 
+ * Contractor Name:        Raytheon Company
+ * Contractor Address:     6825 Pine Street, Suite 340
+ *                         Mail Stop B8
+ *                         Omaha, NE 68106
+ *                         402.291.0100
+ * 
+ * See the AWIPS II Master Rights File ("Master Rights File.pdf") for
+ * further licensing information.
+ **/
+package com.raytheon.uf.common.datadelivery.service.subscription;
+
+import static com.raytheon.uf.common.datadelivery.service.subscription.SubscriptionOverlapMatchStrategy.AT_LEAST_HALF;
+import static com.raytheon.uf.common.datadelivery.service.subscription.SubscriptionOverlapMatchStrategy.MATCH_ALL;
+import static com.raytheon.uf.common.datadelivery.service.subscription.SubscriptionOverlapMatchStrategy.MATCH_ANY;
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertThat;
+
+import org.junit.Test;
+
+/**
+ * Test {@link PointSubscriptionOverlapMatchStrategy}.
+ * 
+ * 
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * May 14, 2013 2000       djohnson     Initial creation
+ * Sept 24, 2012 2386      dhladky      Made point specific
+ * 
+ * 
+ * 
+ * + * @author djohnson + * @version 1.0 + */ +public class PointSubscriptionOverlapMatchStrategyTest { + + private static final SubscriptionOverlapConfig MUST_EXCEED_FIFTY_PERCENT = new PointSubscriptionOverlapConfig( + 50, 50, 50, 50, null); + + @Test + public void matchAnyReturnsTrueIfAnyExceedMaxAllowed() { + + assertThat(MATCH_ANY.isOverlapping(MUST_EXCEED_FIFTY_PERCENT, 55, 45, + 45, 45), is(true)); + assertThat(MATCH_ANY.isOverlapping(MUST_EXCEED_FIFTY_PERCENT, 45, 55, + 45, 45), is(true)); + assertThat(MATCH_ANY.isOverlapping(MUST_EXCEED_FIFTY_PERCENT, 45, 45, + 55, 45), is(true)); + assertThat(MATCH_ANY.isOverlapping(MUST_EXCEED_FIFTY_PERCENT, 45, 45, + 45, 55), is(true)); + } + + @Test + public void matchAnyReturnsFalseIfNoneExceedMaxAllowed() { + + assertThat(MATCH_ANY.isOverlapping(MUST_EXCEED_FIFTY_PERCENT, 50, 50, + 50, 50), is(false)); + assertThat( + MATCH_ANY.isOverlapping(MUST_EXCEED_FIFTY_PERCENT, 0, 0, 0, 0), + is(false)); + assertThat(MATCH_ANY.isOverlapping(MUST_EXCEED_FIFTY_PERCENT, 25, 25, + 25, 25), is(false)); + } + + @Test + public void matchAllReturnsTrueIfAllExceedMaxAllowed() { + + assertThat(MATCH_ALL.isOverlapping(MUST_EXCEED_FIFTY_PERCENT, 55, 55, + 55, 55), is(true)); + assertThat(MATCH_ALL.isOverlapping(MUST_EXCEED_FIFTY_PERCENT, 100, 100, + 100, 100), is(true)); + } + + @Test + public void matchAllReturnsFalseIfNotAllExceedMaxAllowed() { + + assertThat(MATCH_ALL.isOverlapping(MUST_EXCEED_FIFTY_PERCENT, 55, 55, + 55, 45), is(false)); + assertThat(MATCH_ALL.isOverlapping(MUST_EXCEED_FIFTY_PERCENT, 55, 55, + 45, 55), is(false)); + assertThat(MATCH_ALL.isOverlapping(MUST_EXCEED_FIFTY_PERCENT, 55, 45, + 55, 55), is(false)); + assertThat(MATCH_ALL.isOverlapping(MUST_EXCEED_FIFTY_PERCENT, 45, 55, + 55, 55), is(false)); + } + + @Test + public void atLeastHalfReturnsTrueIfAllExceedMaxAllowed() { + + assertThat(AT_LEAST_HALF.isOverlapping(MUST_EXCEED_FIFTY_PERCENT, 55, + 55, 55, 55), is(true)); + assertThat(AT_LEAST_HALF.isOverlapping(MUST_EXCEED_FIFTY_PERCENT, 100, + 100, 100, 100), is(true)); + } + + @Test + public void atLeastHalfReturnsTrueIfHalfExceedMaxAllowed() { + + assertThat(AT_LEAST_HALF.isOverlapping(MUST_EXCEED_FIFTY_PERCENT, 45, + 45, 55, 55), is(true)); + assertThat(AT_LEAST_HALF.isOverlapping(MUST_EXCEED_FIFTY_PERCENT, 55, + 55, 45, 45), is(true)); + } + + @Test + public void atLeastHalfReturnsFalseIfLessThanHalfExceedMaxAllowed() { + + assertThat(AT_LEAST_HALF.isOverlapping(MUST_EXCEED_FIFTY_PERCENT, 45, + 45, 45, 55), is(false)); + assertThat(AT_LEAST_HALF.isOverlapping(MUST_EXCEED_FIFTY_PERCENT, 45, + 45, 55, 45), is(false)); + assertThat(AT_LEAST_HALF.isOverlapping(MUST_EXCEED_FIFTY_PERCENT, 45, + 55, 45, 45), is(false)); + assertThat(AT_LEAST_HALF.isOverlapping(MUST_EXCEED_FIFTY_PERCENT, 55, + 45, 45, 45), is(false)); + } + +} diff --git a/tests/unit/com/raytheon/uf/common/datadelivery/service/subscription/PointSubscriptionOverlapServiceTest.java b/tests/unit/com/raytheon/uf/common/datadelivery/service/subscription/PointSubscriptionOverlapServiceTest.java new file mode 100644 index 0000000000..b959421d0a --- /dev/null +++ b/tests/unit/com/raytheon/uf/common/datadelivery/service/subscription/PointSubscriptionOverlapServiceTest.java @@ -0,0 +1,230 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.common.datadelivery.service.subscription; + +import static com.raytheon.uf.common.datadelivery.service.subscription.SubscriptionOverlapMatchStrategy.MATCH_ALL; +import static com.raytheon.uf.common.datadelivery.service.subscription.SubscriptionOverlapMatchStrategy.MATCH_ANY; +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import org.junit.Before; +import org.junit.Test; +import org.opengis.referencing.operation.TransformException; + +import com.raytheon.uf.common.datadelivery.registry.Subscription; +import com.raytheon.uf.common.datadelivery.registry.SiteSubscriptionFixture; +import com.raytheon.uf.common.localization.PathManagerFactoryTest; +import com.raytheon.uf.common.localization.exception.LocalizationException; + +/** + * Test {@link PointSubscriptionOverlapService}. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * May 07, 2013 2000       djohnson     Initial creation
+ * Sept, 24 2013 2386      dhladky      Made point specific
+ * 
+ * 
+ * + * @author djohnson + * @version 1.0 + */ + +public class PointSubscriptionOverlapServiceTest { + + private static final SubscriptionOverlapConfig ANY_MUST_EXCEED_65_PERCENT = new PointSubscriptionOverlapConfig( + 65, 65, 65, 65, MATCH_ANY); + + private static final SubscriptionOverlapConfig ALL_MUST_EXCEED_65_PERCENT = new PointSubscriptionOverlapConfig( + 65, 65, 65, 65, MATCH_ALL); + + private final ISubscriptionDuplicateChecker duplicateChecker = mock(ISubscriptionDuplicateChecker.class); + + private final SubscriptionOverlapService service = new SubscriptionOverlapService( + duplicateChecker); + + private final Subscription sub1 = SiteSubscriptionFixture.INSTANCE.get(1); + + private final Subscription sub2 = SiteSubscriptionFixture.INSTANCE.get(2); + + @Before + public void setUp() { + PathManagerFactoryTest.initLocalization(); + } + + @Test + public void moreParametersInCommonThanAllowedOverlaps() { + when(duplicateChecker.getParameterDuplicationPercent(sub1, sub2)) + .thenReturn(66); + + assertThat(service.isOverlapping(sub1, sub2).isOverlapping(), is(true)); + } + + @Test + public void lessParametersInCommonThanAllowedDoesNotOverlap() { + when(duplicateChecker.getParameterDuplicationPercent(sub1, sub2)) + .thenReturn(64); + + assertThat(service.isOverlapping(sub1, sub2).isOverlapping(), is(false)); + } + + @Test + public void moreForecastHoursInCommonThanAllowedOverlaps() { + when(duplicateChecker.getForecastHourDuplicationPercent(sub1, sub2)) + .thenReturn(66); + + assertThat(service.isOverlapping(sub1, sub2).isOverlapping(), is(true)); + } + + @Test + public void lessForecastHoursInCommonThanAllowedDoesNotOverlap() { + when(duplicateChecker.getForecastHourDuplicationPercent(sub1, sub2)) + .thenReturn(64); + + assertThat(service.isOverlapping(sub1, sub2).isOverlapping(), is(false)); + } + + @Test + public void moreCyclesInCommonThanAllowedOverlaps() { + when(duplicateChecker.getCycleDuplicationPercent(sub1, sub2)) + .thenReturn(66); + + assertThat(service.isOverlapping(sub1, sub2).isOverlapping(), is(true)); + } + + @Test + public void lessCyclesInCommonThanAllowedDoesNotOverlap() { + when(duplicateChecker.getCycleDuplicationPercent(sub1, sub2)) + .thenReturn(64); + + assertThat(service.isOverlapping(sub1, sub2).isOverlapping(), is(false)); + } + + @Test + public void moreSpatialInCommonThanAllowedOverlaps() + throws TransformException { + when(duplicateChecker.getSpatialDuplicationPercent(sub1, sub2)) + .thenReturn(66); + + assertThat(service.isOverlapping(sub1, sub2).isOverlapping(), is(true)); + } + + @Test + public void lessSpatialInCommonThanAllowedDoesNotOverlap() + throws TransformException { + when(duplicateChecker.getSpatialDuplicationPercent(sub1, sub2)) + .thenReturn(64); + + assertThat(service.isOverlapping(sub1, sub2).isOverlapping(), is(false)); + } + + @Test + public void matchesAnyTrueWillConsiderOneExceededValueAsOverlaps() + throws LocalizationException { + service.writeConfig(ANY_MUST_EXCEED_65_PERCENT); + + when(duplicateChecker.getCycleDuplicationPercent(sub1, sub2)) + .thenReturn(66); + + assertThat(service.isOverlapping(sub1, sub2).isOverlapping(), is(true)); + } + + @Test + public void matchesAnyFalseWillNotConsiderOneExceededValueAsOverlaps() + throws LocalizationException { + service.writeConfig(ALL_MUST_EXCEED_65_PERCENT); + + when(duplicateChecker.getCycleDuplicationPercent(sub1, sub2)) + .thenReturn(66); + + assertThat(service.isOverlapping(sub1, sub2).isOverlapping(), is(false)); + } + + @Test + public void matchesAnyTrueWillConsiderAllExceededValuesAsOverlaps() + throws LocalizationException, TransformException { + service.writeConfig(ANY_MUST_EXCEED_65_PERCENT); + + when(duplicateChecker.getCycleDuplicationPercent(sub1, sub2)) + .thenReturn(66); + when(duplicateChecker.getForecastHourDuplicationPercent(sub1, sub2)) + .thenReturn(66); + when(duplicateChecker.getParameterDuplicationPercent(sub1, sub2)) + .thenReturn(66); + when(duplicateChecker.getSpatialDuplicationPercent(sub1, sub2)) + .thenReturn(66); + + assertThat(service.isOverlapping(sub1, sub2).isOverlapping(), is(true)); + } + + @Test + public void matchesAnyFalseWillConsiderAllExceededValuesAsOverlaps() + throws LocalizationException, TransformException { + service.writeConfig(ALL_MUST_EXCEED_65_PERCENT); + + when(duplicateChecker.getCycleDuplicationPercent(sub1, sub2)) + .thenReturn(66); + when(duplicateChecker.getForecastHourDuplicationPercent(sub1, sub2)) + .thenReturn(66); + when(duplicateChecker.getParameterDuplicationPercent(sub1, sub2)) + .thenReturn(66); + when(duplicateChecker.getSpatialDuplicationPercent(sub1, sub2)) + .thenReturn(66); + + assertThat(service.isOverlapping(sub1, sub2).isOverlapping(), is(true)); + } + + @Test + public void whenAllComparisonsReturnOneHundredPercentReturnsDuplicate() + throws LocalizationException, TransformException { + when(duplicateChecker.getCycleDuplicationPercent(sub1, sub2)) + .thenReturn(100); + when(duplicateChecker.getForecastHourDuplicationPercent(sub1, sub2)) + .thenReturn(100); + when(duplicateChecker.getParameterDuplicationPercent(sub1, sub2)) + .thenReturn(100); + when(duplicateChecker.getSpatialDuplicationPercent(sub1, sub2)) + .thenReturn(100); + + assertThat(service.isOverlapping(sub1, sub2).isDuplicate(), is(true)); + } + + @Test + public void whenAllComparisonsDontReturnOneHundredPercentReturnsNotDuplicate() + throws LocalizationException, TransformException { + when(duplicateChecker.getCycleDuplicationPercent(sub1, sub2)) + .thenReturn(100); + when(duplicateChecker.getForecastHourDuplicationPercent(sub1, sub2)) + .thenReturn(100); + when(duplicateChecker.getParameterDuplicationPercent(sub1, sub2)) + .thenReturn(100); + when(duplicateChecker.getSpatialDuplicationPercent(sub1, sub2)) + .thenReturn(99); + + assertThat(service.isOverlapping(sub1, sub2).isDuplicate(), is(false)); + } + +}