diff --git a/edexOsgi/com.raytheon.uf.edex.datadelivery.bandwidth/res/spring/bandwidth-datadelivery.xml b/edexOsgi/com.raytheon.uf.edex.datadelivery.bandwidth/res/spring/bandwidth-datadelivery.xml index d93d213d4c..3dcdf32da4 100644 --- a/edexOsgi/com.raytheon.uf.edex.datadelivery.bandwidth/res/spring/bandwidth-datadelivery.xml +++ b/edexOsgi/com.raytheon.uf.edex.datadelivery.bandwidth/res/spring/bandwidth-datadelivery.xml @@ -57,6 +57,9 @@ + + + diff --git a/edexOsgi/com.raytheon.uf.edex.datadelivery.bandwidth/src/com/raytheon/uf/edex/datadelivery/bandwidth/BandwidthManager.java b/edexOsgi/com.raytheon.uf.edex.datadelivery.bandwidth/src/com/raytheon/uf/edex/datadelivery/bandwidth/BandwidthManager.java index 96e0f3a819..c0821e61c3 100644 --- a/edexOsgi/com.raytheon.uf.edex.datadelivery.bandwidth/src/com/raytheon/uf/edex/datadelivery/bandwidth/BandwidthManager.java +++ b/edexOsgi/com.raytheon.uf.edex.datadelivery.bandwidth/src/com/raytheon/uf/edex/datadelivery/bandwidth/BandwidthManager.java @@ -100,6 +100,7 @@ import com.raytheon.uf.edex.datadelivery.bandwidth.util.BandwidthUtil; * Jan 28, 2013 1530 djohnson Unschedule all allocations for a subscription that does not fully schedule. * Jan 30, 2013 1501 djohnson Fix broken calculations for determining required latency. * Feb 05, 2013 1580 mpduff EventBus refactor. + * Feb 14, 2013 1595 djohnson Check with BandwidthUtil whether or not to reschedule subscriptions on update. * * * @author dhladky @@ -414,8 +415,8 @@ abstract class BandwidthManager extends // Add the current subscription to the ones BandwidthManager already // knows about. try { - subscriptions.add(bandwidthDao.newBandwidthSubscription(subscription, - retrievalTime)); + subscriptions.add(bandwidthDao.newBandwidthSubscription( + subscription, retrievalTime)); } catch (SerializationException e) { statusHandler.error( "Trapped Exception trying to schedule Subscription[" @@ -434,8 +435,9 @@ abstract class BandwidthManager extends // Retrieve all the current subscriptions by provider, dataset name and // base time. - List subscriptions = bandwidthDao.getBandwidthSubscriptions( - dao.getProvider(), dao.getDataSetName(), retrievalTime); + List subscriptions = bandwidthDao + .getBandwidthSubscriptions(dao.getProvider(), + dao.getDataSetName(), retrievalTime); statusHandler.info("schedule() - Scheduling subscription [" + dao.getName() @@ -480,8 +482,10 @@ abstract class BandwidthManager extends .getStatus().equals(RetrievalStatus.PROCESSING)) && !retrieval.isSubsumed()) { - BandwidthSubscription bandwidthSubscription = retrieval.getBandwidthSubscription(); - Calendar retrievalTime = bandwidthSubscription.getBaseReferenceTime(); + BandwidthSubscription bandwidthSubscription = retrieval + .getBandwidthSubscription(); + Calendar retrievalTime = bandwidthSubscription + .getBaseReferenceTime(); Calendar startTime = BandwidthUtil.copy(retrievalTime); int delayMinutes = retrieval.getDataSetAvailablityDelay(); @@ -516,7 +520,8 @@ abstract class BandwidthManager extends // if so, mark the status of the BandwidthReservation as // READY. List z = bandwidthDao - .getBandwidthDataSetUpdate(bandwidthSubscription.getProvider(), + .getBandwidthDataSetUpdate( + bandwidthSubscription.getProvider(), bandwidthSubscription.getDataSetName(), bandwidthSubscription.getBaseReferenceTime()); if (z.size() > 0) { @@ -621,8 +626,8 @@ abstract class BandwidthManager extends Calendar now = BandwidthUtil.now(); // Store the AdhocSubscription with a base time of now.. try { - subscriptions.add(bandwidthDao - .newBandwidthSubscription(subscription, now)); + subscriptions.add(bandwidthDao.newBandwidthSubscription( + subscription, now)); } catch (SerializationException e) { statusHandler.error( "Trapped Exception trying to schedule AdhocSubscription[" @@ -740,7 +745,8 @@ abstract class BandwidthManager extends // BandwidthReservations // already in place for this subscription. - Subscription old = bandwidthSubscriptions.get(0).getSubscription(); + Subscription old = bandwidthSubscriptions.get(0) + .getSubscription(); // Check to see if estimated size changed. If there was a change // to @@ -750,7 +756,8 @@ abstract class BandwidthManager extends // change the // RetrievalPlan as long as the size stays the same - if (subscriptionRequiresReschedule(subscription, old)) { + if (BandwidthUtil.subscriptionRequiresReschedule(subscription, + old)) { // OK, have to remove the old Subscriptions and add the new // ones.. @@ -796,7 +803,8 @@ abstract class BandwidthManager extends .iterator(); while (itr.hasNext()) { bandwidthSubscription = itr.next(); - if (oldCycles.contains(bandwidthSubscription.getCycle())) { + if (oldCycles.contains(bandwidthSubscription + .getCycle())) { remove.add(bandwidthSubscription); itr.remove(); } @@ -820,29 +828,6 @@ abstract class BandwidthManager extends } } - /** - * Determines when a subscription requires rescheduling. - * - * @param subscription - * the new subscription - * @param old - * the old version - * @return true if it requires rescheduling - */ - protected boolean subscriptionRequiresReschedule(Subscription subscription, - Subscription old) { - // TODO: Do they have to match EXACTLY... probably not but how - // much is 'close enough' in bandwidth terms. - boolean requiresReschedule = (old.getDataSetSize() != subscription - .getDataSetSize()) - // Priority is different - || (old.getPriority() != subscription.getPriority()) - // Latency is different - || (!(old.getLatencyInMinutes() == subscription - .getLatencyInMinutes())); - return requiresReschedule; - } - /** * {@inheritDoc} * @@ -856,8 +841,8 @@ abstract class BandwidthManager extends } /** - * Remove BandwidthSubscription's (and dependent Objects) from any RetrievalPlans - * they are in and adjust the RetrievalPlans accordingly. + * Remove BandwidthSubscription's (and dependent Objects) from any + * RetrievalPlans they are in and adjust the RetrievalPlans accordingly. * * @param bandwidthSubscriptions * The subscriptionDao's to remove. @@ -865,7 +850,8 @@ abstract class BandwidthManager extends * @return */ private List remove( - List bandwidthSubscriptions, boolean reschedule) { + List bandwidthSubscriptions, + boolean reschedule) { List unscheduled = new ArrayList(); @@ -890,7 +876,8 @@ abstract class BandwidthManager extends // For each date, get a unique set of provider & dataset name Set providerDataSet = new HashSet(); - for (BandwidthSubscription bandwidthSubscription : map.get(baseTime)) { + for (BandwidthSubscription bandwidthSubscription : map + .get(baseTime)) { String key = bandwidthSubscription.getProvider() + "::" + bandwidthSubscription.getDataSetName(); providerDataSet.add(key); @@ -903,8 +890,9 @@ abstract class BandwidthManager extends String[] key = providerDataSetName.split("::"); String provider = key[0]; String dataSetName = key[1]; - List m = bandwidthDao.getBandwidthSubscriptions( - provider, dataSetName, baseTime); + List m = bandwidthDao + .getBandwidthSubscriptions(provider, dataSetName, + baseTime); unscheduled.addAll(aggregate(m)); } @@ -980,16 +968,19 @@ abstract class BandwidthManager extends next.add(Calendar.DAY_OF_YEAR, 1); // Since subscriptions are based on cycles in a day, add one day // to the - // completed BandwidthSubscription to get the next days retrieval. + // completed BandwidthSubscription to get the next days + // retrieval. - // Now check if that BandwidthSubscription has already been scheduled. - BandwidthSubscription a = bandwidthDao.getBandwidthSubscription( - dao.getRegistryId(), next); + // Now check if that BandwidthSubscription has already been + // scheduled. + BandwidthSubscription a = bandwidthDao + .getBandwidthSubscription(dao.getRegistryId(), next); if (a == null) { // Create the new BandwidthSubscription record with the next // time.. try { - a = bandwidthDao.newBandwidthSubscription(subscription, next); + a = bandwidthDao.newBandwidthSubscription(subscription, + next); } catch (SerializationException e) { statusHandler.error( @@ -1187,7 +1178,8 @@ abstract class BandwidthManager extends + "]. Ignoring list and using the first item."); } - BandwidthSubscription bandwidthSubscription = bandwidthSubscriptions.get(0); + BandwidthSubscription bandwidthSubscription = bandwidthSubscriptions + .get(0); long id = bandwidthSubscription.getId(); final List bandwidthAllocations = bandwidthDao @@ -1494,7 +1486,8 @@ abstract class BandwidthManager extends IBandwidthDao fromDao = copyFrom.bandwidthDao; Set actualSubscriptions = new HashSet(); - for (BandwidthSubscription subscription : fromDao.getBandwidthSubscriptions()) { + for (BandwidthSubscription subscription : fromDao + .getBandwidthSubscriptions()) { try { Subscription actualSubscription = subscription .getSubscription(); diff --git a/edexOsgi/com.raytheon.uf.edex.datadelivery.bandwidth/src/com/raytheon/uf/edex/datadelivery/bandwidth/util/AlwaysRescheduleSubscriptions.java b/edexOsgi/com.raytheon.uf.edex.datadelivery.bandwidth/src/com/raytheon/uf/edex/datadelivery/bandwidth/util/AlwaysRescheduleSubscriptions.java new file mode 100644 index 0000000000..ccc00d4915 --- /dev/null +++ b/edexOsgi/com.raytheon.uf.edex.datadelivery.bandwidth/src/com/raytheon/uf/edex/datadelivery/bandwidth/util/AlwaysRescheduleSubscriptions.java @@ -0,0 +1,54 @@ +/** + * 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.edex.datadelivery.bandwidth.util; + +import com.raytheon.uf.common.datadelivery.registry.Subscription; + +/** + * Implementation of {@link ISubscriptionRescheduleStrategy} that always + * reschedules subscriptions on an update. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Feb 14, 2013 1595       djohnson     Initial creation
+ * 
+ * 
+ * + * @author djohnson + * @version 1.0 + */ + +public class AlwaysRescheduleSubscriptions implements + ISubscriptionRescheduleStrategy { + + /** + * {@inheritDoc} + */ + @Override + public boolean subscriptionRequiresReschedule(Subscription subscription, + Subscription old) { + return true; + } + +} diff --git a/edexOsgi/com.raytheon.uf.edex.datadelivery.bandwidth/src/com/raytheon/uf/edex/datadelivery/bandwidth/util/BandwidthDaoUtil.java b/edexOsgi/com.raytheon.uf.edex.datadelivery.bandwidth/src/com/raytheon/uf/edex/datadelivery/bandwidth/util/BandwidthDaoUtil.java index 290c7a4026..e8264ae622 100644 --- a/edexOsgi/com.raytheon.uf.edex.datadelivery.bandwidth/src/com/raytheon/uf/edex/datadelivery/bandwidth/util/BandwidthDaoUtil.java +++ b/edexOsgi/com.raytheon.uf.edex.datadelivery.bandwidth/src/com/raytheon/uf/edex/datadelivery/bandwidth/util/BandwidthDaoUtil.java @@ -37,8 +37,8 @@ import com.raytheon.uf.common.status.UFStatus.Priority; import com.raytheon.uf.common.time.util.TimeUtil; import com.raytheon.uf.edex.datadelivery.bandwidth.dao.BandwidthAllocation; import com.raytheon.uf.edex.datadelivery.bandwidth.dao.BandwidthDataSetUpdate; -import com.raytheon.uf.edex.datadelivery.bandwidth.dao.IBandwidthDao; import com.raytheon.uf.edex.datadelivery.bandwidth.dao.BandwidthSubscription; +import com.raytheon.uf.edex.datadelivery.bandwidth.dao.IBandwidthDao; import com.raytheon.uf.edex.datadelivery.bandwidth.retrieval.RetrievalManager; import com.raytheon.uf.edex.datadelivery.bandwidth.retrieval.RetrievalPlan; import com.raytheon.uf.edex.datadelivery.bandwidth.retrieval.RetrievalStatus; @@ -55,6 +55,7 @@ import com.raytheon.uf.edex.datadelivery.bandwidth.retrieval.RetrievalStatus; * ------------ ---------- ----------- -------------------------- * Oct 24, 2012 1286 djohnson Extract methods from {@link BandwidthUtil}. * Dec 11, 2012 1286 djohnson FULFILLED allocations are not in the retrieval plan either. + * Feb 14, 2013 1595 djohnson Fix not using calendar copies, and backwards max/min operations. * * * @@ -186,18 +187,16 @@ public class BandwidthDaoUtil { } else { // If there is a start and end time, then modify the start and // end times to 'fit' within the RetrievalPlan times - subscriptionStartDate = BandwidthUtil.max( - subscription.getSubscriptionEnd(), planEnd); - subscriptionEndDate = BandwidthUtil.min( - subscription.getSubscriptionStart(), planStart); + subscriptionStartDate = BandwidthUtil.copy(BandwidthUtil.max( + subscription.getSubscriptionStart(), planStart)); + subscriptionEndDate = BandwidthUtil.copy(BandwidthUtil.min( + subscription.getSubscriptionEnd(), planEnd)); } // Create a Set of Calendars for all the baseReferenceTimes that a // Subscription can contain... - subscriptionStartDate.set(Calendar.HOUR_OF_DAY, 0); - subscriptionStartDate.set(Calendar.MINUTE, 0); - subscriptionStartDate.set(Calendar.SECOND, 0); - subscriptionStartDate.set(Calendar.MILLISECOND, 0); + TimeUtil.minCalendarFields(subscriptionStartDate, Calendar.MILLISECOND, + Calendar.SECOND, Calendar.MINUTE, Calendar.HOUR_OF_DAY); outerloop: while (!subscriptionStartDate.after(subscriptionEndDate)) { diff --git a/edexOsgi/com.raytheon.uf.edex.datadelivery.bandwidth/src/com/raytheon/uf/edex/datadelivery/bandwidth/util/BandwidthUtil.java b/edexOsgi/com.raytheon.uf.edex.datadelivery.bandwidth/src/com/raytheon/uf/edex/datadelivery/bandwidth/util/BandwidthUtil.java index 4987365f78..d2146baf55 100644 --- a/edexOsgi/com.raytheon.uf.edex.datadelivery.bandwidth/src/com/raytheon/uf/edex/datadelivery/bandwidth/util/BandwidthUtil.java +++ b/edexOsgi/com.raytheon.uf.edex.datadelivery.bandwidth/src/com/raytheon/uf/edex/datadelivery/bandwidth/util/BandwidthUtil.java @@ -25,6 +25,7 @@ import com.raytheon.uf.edex.datadelivery.bandwidth.dao.BandwidthSubscription; * use availability delay to determine which starting hours to schedule. * Nov 09, 2012 1286 djohnson Separate DAO utility methods from general utility. * Dec 11, 2012 1403 djohnson No longer valid to run without bandwidth management. + * Feb 14, 2013 1595 djohnson Use subscription rescheduling strategy. * * * @@ -35,7 +36,7 @@ public class BandwidthUtil { public static final long BYTES_PER_KILOBYTE = 1024; public static final long DEFAULT_IDENTIFIER = -1L; - + public static final int[] MONTHS_OF_YEAR = { Calendar.JANUARY, Calendar.FEBRUARY, Calendar.MARCH, Calendar.APRIL, Calendar.MAY, Calendar.JUNE, Calendar.JULY, Calendar.AUGUST, Calendar.SEPTEMBER, @@ -51,6 +52,8 @@ public class BandwidthUtil { private ISubscriptionLatencyCalculator subscriptionLatencyCalculator; + private ISubscriptionRescheduleStrategy subscriptionRescheduleStrategy; + private BandwidthUtil() { }; @@ -151,6 +154,15 @@ public class BandwidthUtil { this.subscriptionLatencyCalculator = subscriptionLatencyCalculator; } + /** + * @param subscriptionRescheduleStrategy + * the subscriptionRescheduleStrategy to set + */ + public void setSubscriptionRescheduleStrategy( + ISubscriptionRescheduleStrategy subscriptionRescheduleStrategy) { + this.subscriptionRescheduleStrategy = subscriptionRescheduleStrategy; + } + /** * @return the instance */ @@ -277,4 +289,19 @@ public class BandwidthUtil { public static long convertBytesToKilobytes(long bytes) { return bytes / BandwidthUtil.BYTES_PER_KILOBYTE; } + + /** + * Check whether a subscription should be rescheduled on an update. + * + * @param subscription + * the subscription + * @param old + * the old version + * @return true if the subscription should be rescheduled + */ + public static boolean subscriptionRequiresReschedule( + Subscription subscription, Subscription old) { + return instance.subscriptionRescheduleStrategy + .subscriptionRequiresReschedule(subscription, old); + } } diff --git a/edexOsgi/com.raytheon.uf.edex.datadelivery.bandwidth/src/com/raytheon/uf/edex/datadelivery/bandwidth/util/ISubscriptionRescheduleStrategy.java b/edexOsgi/com.raytheon.uf.edex.datadelivery.bandwidth/src/com/raytheon/uf/edex/datadelivery/bandwidth/util/ISubscriptionRescheduleStrategy.java new file mode 100644 index 0000000000..0f3d31af53 --- /dev/null +++ b/edexOsgi/com.raytheon.uf.edex.datadelivery.bandwidth/src/com/raytheon/uf/edex/datadelivery/bandwidth/util/ISubscriptionRescheduleStrategy.java @@ -0,0 +1,54 @@ +/** + * 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.edex.datadelivery.bandwidth.util; + +import com.raytheon.uf.common.datadelivery.registry.Subscription; + +/** + * Interface defining whether a subscription requires a reschedule. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Feb 14, 2013 1595       djohnson     Initial creation
+ * 
+ * 
+ * + * @author djohnson + * @version 1.0 + */ +public interface ISubscriptionRescheduleStrategy { + + /** + * Check whether a subscription should be rescheduled on an update. + * + * @param subscription + * the subscription + * @param old + * the old version + * @return true if the subscription should be rescheduled + */ + boolean subscriptionRequiresReschedule(Subscription subscription, + Subscription old); + +} diff --git a/tests/integration/com/raytheon/uf/edex/datadelivery/bandwidth/BandwidthManagerIntTest.java b/tests/integration/com/raytheon/uf/edex/datadelivery/bandwidth/BandwidthManagerIntTest.java index e6b60f0775..1423001d5a 100644 --- a/tests/integration/com/raytheon/uf/edex/datadelivery/bandwidth/BandwidthManagerIntTest.java +++ b/tests/integration/com/raytheon/uf/edex/datadelivery/bandwidth/BandwidthManagerIntTest.java @@ -19,8 +19,10 @@ **/ package com.raytheon.uf.edex.datadelivery.bandwidth; +import static org.hamcrest.Matchers.empty; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.not; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertThat; @@ -95,6 +97,7 @@ import com.raytheon.uf.edex.datadelivery.retrieval.RetrievalManagerNotifyEvent; * Jan 25, 2013 1528 djohnson Compare priorities as primitive ints. * Jan 28, 2013 1530 djohnson Test that all allocations are unscheduled for subscription that doesn't fully schedule. * Jan 30, 2013 1501 djohnson Fix broken calculations for determining required latency. + * Feb 14, 2013 1595 djohnson Fix expired subscription updates that weren't scheduling retrievals. * * * @@ -395,6 +398,71 @@ public class BandwidthManagerIntTest extends AbstractBandwidthManagerIntTest { } } + /** + * Redmine #1595: A subscription was created...and then expired. The + * subscription was updated by extending the Expiration Date only. The + * subscription, however, was never scheduled (e.g., in the Bandwidth + * Utilization graph). Data displayed in D2D failed to update. However, the + * subscription (and data) did begin updating after editing the subscription + * and adding another parameter. + */ + @Test + public void expiredSubscriptionUpdatedToNonExpiredIsScheduled() + throws Exception { + + final Date yesterday = new Date(TimeUtil.currentTimeMillis() - TimeUtil.MILLIS_PER_DAY); + final Date oneHourAgo = new Date(TimeUtil.currentTimeMillis() - TimeUtil.MILLIS_PER_HOUR); + + Subscription subscription = createSubscriptionThatFillsHalfABucket(); + subscription.setSubscriptionStart(yesterday); + subscription.setSubscriptionEnd(oneHourAgo); + + bandwidthManager.subscriptionUpdated(subscription); + + // Make sure nothing is scheduled when the subscription is expired + assertThat(bandwidthDao.getBandwidthAllocations(subscription.getRoute()), + is(empty())); + + // No longer expired + subscription.setSubscriptionEnd(new Date(TimeUtil.currentTimeMillis() + + TimeUtil.MILLIS_PER_WEEK)); + + bandwidthManager.subscriptionUpdated(subscription); + + assertThat( + bandwidthDao.getBandwidthAllocations(subscription.getRoute()), + is(not(empty()))); + } + + @Test + public void subscriptionUpdatedToExpiredHasAllocationsRemoved() + throws Exception { + + Subscription subscription = createSubscriptionThatFillsHalfABucket(); + + bandwidthManager.subscriptionUpdated(subscription); + + assertThat( + bandwidthDao.getBandwidthAllocations(subscription.getRoute()), + is(not(empty()))); + + final Date yesterday = new Date(TimeUtil.currentTimeMillis() + - TimeUtil.MILLIS_PER_DAY); + final Date oneHourAgo = new Date(TimeUtil.currentTimeMillis() + - TimeUtil.MILLIS_PER_HOUR); + + // Updated to expired + subscription.setSubscriptionStart(yesterday); + subscription.setSubscriptionEnd(oneHourAgo); + + bandwidthManager.subscriptionUpdated(subscription); + + // Make sure nothing is scheduled when the subscription is expired + assertThat( + bandwidthDao.getBandwidthAllocations(subscription.getRoute()), + is(empty())); + } + @Test public void testScheduleSubscriptionWithHigherPrioritySetsOtherAllocationsToUnscheduled() { diff --git a/tests/unit/com/raytheon/uf/edex/datadelivery/bandwidth/util/BandwidthDaoUtilTest.java b/tests/unit/com/raytheon/uf/edex/datadelivery/bandwidth/util/BandwidthDaoUtilTest.java index b43c42a24e..2469b03221 100644 --- a/tests/unit/com/raytheon/uf/edex/datadelivery/bandwidth/util/BandwidthDaoUtilTest.java +++ b/tests/unit/com/raytheon/uf/edex/datadelivery/bandwidth/util/BandwidthDaoUtilTest.java @@ -19,6 +19,7 @@ **/ package com.raytheon.uf.edex.datadelivery.bandwidth.util; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; @@ -27,6 +28,9 @@ import static org.mockito.Mockito.when; import java.util.Arrays; import java.util.Calendar; +import java.util.Collection; +import java.util.Date; +import java.util.List; import java.util.SortedSet; import java.util.TreeSet; @@ -36,7 +40,7 @@ import org.junit.Test; import com.raytheon.uf.common.datadelivery.registry.Network; import com.raytheon.uf.common.datadelivery.registry.Subscription; -import com.raytheon.uf.common.datadelivery.registry.SubscriptionFixture; +import com.raytheon.uf.common.datadelivery.registry.SubscriptionBuilder; import com.raytheon.uf.common.localization.PathManagerFactoryTest; import com.raytheon.uf.common.time.util.TimeUtil; import com.raytheon.uf.common.time.util.TimeUtilTest; @@ -60,6 +64,7 @@ import com.raytheon.uf.edex.datadelivery.bandwidth.retrieval.RetrievalStatus; * ------------ ---------- ----------- -------------------------- * Oct 24, 2012 1286 djohnson Initial creation * Feb 07, 2013 1543 djohnson Remove unnecessary test setup methods. + * Feb 14, 2013 1595 djohnson Fix retrieval plan/subscription time intersections. * * * @@ -104,11 +109,10 @@ public class BandwidthDaoUtilTest { @Test public void testGetRetrievalTimesReturnsBaseReferenceTimesInPlanWindow() { // Make sure the subscription is "active" within the plan period - Subscription subscription = SubscriptionFixture.INSTANCE.get(); - subscription.setActivePeriodStart(plan.getPlanStart().getTime()); - subscription.setActivePeriodEnd(plan.getPlanEnd().getTime()); - subscription.setSubscriptionStart(TimeUtil.newImmutableDate()); - subscription.setSubscriptionEnd(null); + Subscription subscription = new SubscriptionBuilder() + .withActivePeriodStart(plan.getPlanStart().getTime()) + .withActivePeriodEnd(plan.getPlanEnd().getTime()) + .withSubscriptionStart(TimeUtil.newImmutableDate()).build(); subscription.getTime().setCycleTimes( Arrays.asList(Integer.valueOf(9), Integer.valueOf(0))); @@ -117,22 +121,66 @@ public class BandwidthDaoUtilTest { SortedSet subscriptionTimes = new TreeSet(); - subscriptionTimes = bandwidthDaoUtil - .getRetrievalTimes(subscription, cycles, plan, - subscriptionTimes); + subscriptionTimes = bandwidthDaoUtil.getRetrievalTimes(subscription, + cycles, plan, subscriptionTimes); - // Using millis to verify the returned retrieval times is a bit - // unpleasant to look at, but it'll do for now - Calendar cal = TimeUtil.newCalendar(); - for (long millis : new long[] { 194400000L, 226800000L, 280800000L, - 313200000L }) { - cal.setTimeInMillis(millis); - assertTrue( - "Expected to find retrieval time of " - + BandwidthUtil.format(cal), - subscriptionTimes.contains(cal)); - } + final List daysOfTheYear = Arrays.asList(3, 4); + verifySubscriptionTimesContainsCyclesForSpecifiedDays(daysOfTheYear, + cycles, subscriptionTimes); + } + @Test + public void testGetRetrievalTimesUsesSubscriptionStartWhenItIsMostRestrictive() { + final Date startsTwoDaysIntoPlan = new Date(plan.getPlanStart() + .getTimeInMillis() + TimeUtil.MILLIS_PER_DAY * 2); + + Subscription subscription = new SubscriptionBuilder() + .withSubscriptionStart(startsTwoDaysIntoPlan) + .withSubscriptionEnd(plan.getPlanEnd().getTime()).build(); + subscription.getTime().setCycleTimes( + Arrays.asList(Integer.valueOf(9), Integer.valueOf(0))); + + TreeSet cycles = new TreeSet(subscription.getTime() + .getCycleTimes()); + + SortedSet subscriptionTimes = new TreeSet(); + + subscriptionTimes = bandwidthDaoUtil.getRetrievalTimes(subscription, + cycles, plan, subscriptionTimes); + + final List daysOfTheYear = Arrays.asList(4); + verifySubscriptionTimesContainsCyclesForSpecifiedDays(daysOfTheYear, + cycles, subscriptionTimes); + final List notScheduledDays = Arrays.asList(3); + verifySubscriptionTimesDoesNotContainCyclesForSpecifiedDays( + notScheduledDays, cycles, subscriptionTimes); + } + + @Test + public void testGetRetrievalTimesUsesSubscriptionEndWhenItIsMostRestrictive() { + final Date endsOneDayBeforePlan = new Date(plan.getPlanEnd() + .getTimeInMillis() - TimeUtil.MILLIS_PER_DAY); + + Subscription subscription = new SubscriptionBuilder() + .withSubscriptionStart(plan.getPlanStart().getTime()) + .withSubscriptionEnd(endsOneDayBeforePlan).build(); + subscription.getTime().setCycleTimes( + Arrays.asList(Integer.valueOf(9), Integer.valueOf(0))); + + TreeSet cycles = new TreeSet(subscription.getTime() + .getCycleTimes()); + + SortedSet subscriptionTimes = new TreeSet(); + + subscriptionTimes = bandwidthDaoUtil.getRetrievalTimes(subscription, + cycles, plan, subscriptionTimes); + + final List daysOfTheYear = Arrays.asList(3); + verifySubscriptionTimesContainsCyclesForSpecifiedDays(daysOfTheYear, + cycles, subscriptionTimes); + final List notScheduledDays = Arrays.asList(4); + verifySubscriptionTimesDoesNotContainCyclesForSpecifiedDays( + notScheduledDays, cycles, subscriptionTimes); } @Test @@ -158,4 +206,58 @@ public class BandwidthDaoUtilTest { verify(retrievalManager, never()).remove(alloc2); } + /** + * Verifies the subscription times contains the cycles for the specified + * days. + * + * @param daysOfTheYear + * @param cycles + * @param subscriptionTimes + */ + private void verifySubscriptionTimesContainsCyclesForSpecifiedDays( + Collection daysOfTheYear, Collection cycles, + SortedSet subscriptionTimes) { + Calendar cal = TimeUtil.newCalendar(); + TimeUtil.minCalendarFields(cal, Calendar.MILLISECOND, Calendar.SECOND, + Calendar.MINUTE); + + for (Integer dayOfTheYear : daysOfTheYear) { + cal.set(Calendar.DAY_OF_YEAR, dayOfTheYear); + + for (Integer cycle : cycles) { + cal.set(Calendar.HOUR_OF_DAY, cycle); + assertTrue("Expected to find retrieval time of " + + BandwidthUtil.format(cal), + subscriptionTimes.contains(cal)); + } + } + } + + /** + * Verifies the subscription times do not contain the cycles for the + * specified days. + * + * @param daysOfTheYear + * @param cycles + * @param subscriptionTimes + */ + private void verifySubscriptionTimesDoesNotContainCyclesForSpecifiedDays( + Collection daysOfTheYear, Collection cycles, + SortedSet subscriptionTimes) { + Calendar cal = TimeUtil.newCalendar(); + TimeUtil.minCalendarFields(cal, Calendar.MILLISECOND, Calendar.SECOND, + Calendar.MINUTE); + + for (Integer dayOfTheYear : daysOfTheYear) { + cal.set(Calendar.DAY_OF_YEAR, dayOfTheYear); + + for (Integer cycle : cycles) { + cal.set(Calendar.HOUR_OF_DAY, cycle); + assertFalse("Expected not to find retrieval time of " + + BandwidthUtil.format(cal), + subscriptionTimes.contains(cal)); + } + } + + } }