Merge "Issue #2636 - Fix scheduling gaps at start and end of retrieval plan" into omaha_14.2.1
Former-commit-id:5e8866a859
[formerly a332d62d6fddc831599bd1e0a6e2d1844e038953] Former-commit-id:fc223f594a
This commit is contained in:
commit
6c03781d17
7 changed files with 252 additions and 262 deletions
|
@ -20,16 +20,14 @@
|
||||||
package com.raytheon.uf.common.datadelivery.bandwidth.data;
|
package com.raytheon.uf.common.datadelivery.bandwidth.data;
|
||||||
|
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.TimeZone;
|
import java.util.TimeZone;
|
||||||
|
|
||||||
import com.raytheon.uf.common.datadelivery.registry.Network;
|
import com.raytheon.uf.common.datadelivery.registry.Network;
|
||||||
import com.raytheon.uf.common.serialization.annotations.DynamicSerialize;
|
import com.raytheon.uf.common.serialization.annotations.DynamicSerialize;
|
||||||
import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement;
|
import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement;
|
||||||
import com.raytheon.uf.common.time.util.TimeUtil;
|
import com.raytheon.uf.common.time.util.TimeUtil;
|
||||||
|
import com.raytheon.uf.common.util.StringUtil;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Time Window Data object.
|
* Time Window Data object.
|
||||||
|
@ -44,6 +42,7 @@ import com.raytheon.uf.common.time.util.TimeUtil;
|
||||||
* Dec 06, 2012 1397 djohnson Add dynamic serialize class annotation.
|
* Dec 06, 2012 1397 djohnson Add dynamic serialize class annotation.
|
||||||
* Jan 07, 2013 1451 djohnson Use TimeUtil.newGmtCalendar().
|
* Jan 07, 2013 1451 djohnson Use TimeUtil.newGmtCalendar().
|
||||||
* Nov 25, 2013 2545 mpduff Add Network.
|
* Nov 25, 2013 2545 mpduff Add Network.
|
||||||
|
* Jan 23, 2014 2636 mpduff Removed binStartTimes, add base time and offset.
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
|
@ -60,14 +59,16 @@ public class TimeWindowData implements Comparable<TimeWindowData> {
|
||||||
@DynamicSerializeElement
|
@DynamicSerializeElement
|
||||||
private long timeWindowEndTime = 0L;
|
private long timeWindowEndTime = 0L;
|
||||||
|
|
||||||
/** Array of bin start times for this time window. */
|
|
||||||
@DynamicSerializeElement
|
|
||||||
private List<Long> binStartTimes;
|
|
||||||
|
|
||||||
/** The network for the data */
|
/** The network for the data */
|
||||||
@DynamicSerializeElement
|
@DynamicSerializeElement
|
||||||
private Network network;
|
private Network network;
|
||||||
|
|
||||||
|
@DynamicSerializeElement
|
||||||
|
private long baseTime;
|
||||||
|
|
||||||
|
@DynamicSerializeElement
|
||||||
|
private int offset;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
*
|
*
|
||||||
|
@ -98,50 +99,6 @@ public class TimeWindowData implements Comparable<TimeWindowData> {
|
||||||
* TimeUtil.MILLIS_PER_MINUTE;
|
* TimeUtil.MILLIS_PER_MINUTE;
|
||||||
this.timeWindowEndTime = (windowEndTime / TimeUtil.MILLIS_PER_MINUTE)
|
this.timeWindowEndTime = (windowEndTime / TimeUtil.MILLIS_PER_MINUTE)
|
||||||
* TimeUtil.MILLIS_PER_MINUTE;
|
* TimeUtil.MILLIS_PER_MINUTE;
|
||||||
binStartTimes = new ArrayList<Long>();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the bin times.
|
|
||||||
*
|
|
||||||
* @param binTimesArray
|
|
||||||
*/
|
|
||||||
public void setBinTimes(List<Long> binTimesArray) {
|
|
||||||
binStartTimes = binTimesArray;
|
|
||||||
sortBinStartTimes();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add a bin time.
|
|
||||||
*
|
|
||||||
* @param binStartTime
|
|
||||||
*/
|
|
||||||
public void addBinTime(Long binStartTime) {
|
|
||||||
if (validBinStartTime(binStartTime)) {
|
|
||||||
long roundedBinTime = (binStartTime / TimeUtil.MILLIS_PER_MINUTE)
|
|
||||||
* TimeUtil.MILLIS_PER_MINUTE;
|
|
||||||
binStartTimes.add(roundedBinTime);
|
|
||||||
sortBinStartTimes();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Validate the bin time.
|
|
||||||
*
|
|
||||||
* @param binStartTime
|
|
||||||
* @return true if bin time is within the time window
|
|
||||||
*/
|
|
||||||
private boolean validBinStartTime(Long binStartTime) {
|
|
||||||
return binStartTime >= timeWindowStartTime
|
|
||||||
&& binStartTime <= timeWindowEndTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sort the bin times.
|
|
||||||
*/
|
|
||||||
public void sortBinStartTimes() {
|
|
||||||
Collections.sort(binStartTimes);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -176,15 +133,6 @@ public class TimeWindowData implements Comparable<TimeWindowData> {
|
||||||
return timeWindowEndTime;
|
return timeWindowEndTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the time window end time.
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public List<Long> getBinStartTimes() {
|
|
||||||
return binStartTimes;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param timeWindowStartTime
|
* @param timeWindowStartTime
|
||||||
* the timeWindowStartTime to set
|
* the timeWindowStartTime to set
|
||||||
|
@ -201,14 +149,6 @@ public class TimeWindowData implements Comparable<TimeWindowData> {
|
||||||
this.timeWindowEndTime = timeWindowEndTime;
|
this.timeWindowEndTime = timeWindowEndTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param binStartTimes
|
|
||||||
* the binStartTimes to set
|
|
||||||
*/
|
|
||||||
public void setBinStartTimes(List<Long> binStartTimes) {
|
|
||||||
this.binStartTimes = binStartTimes;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the network
|
* @return the network
|
||||||
*/
|
*/
|
||||||
|
@ -224,6 +164,36 @@ public class TimeWindowData implements Comparable<TimeWindowData> {
|
||||||
this.network = network;
|
this.network = network;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the offset
|
||||||
|
*/
|
||||||
|
public int getOffset() {
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param offset
|
||||||
|
* the offset to set
|
||||||
|
*/
|
||||||
|
public void setOffset(int offset) {
|
||||||
|
this.offset = offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the baseTime
|
||||||
|
*/
|
||||||
|
public long getBaseTime() {
|
||||||
|
return baseTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param baseTime
|
||||||
|
* the baseTime to set
|
||||||
|
*/
|
||||||
|
public void setBaseTime(long baseTime) {
|
||||||
|
this.baseTime = baseTime;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
|
@ -237,9 +207,15 @@ public class TimeWindowData implements Comparable<TimeWindowData> {
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
sb.append("Start Time:\t").append(sdf.format(cal.getTime()))
|
sb.append("Start Time:\t").append(sdf.format(cal.getTime()))
|
||||||
.append(" Z");
|
.append(" Z");
|
||||||
sb.append("\n");
|
sb.append(StringUtil.NEWLINE);
|
||||||
cal.setTimeInMillis(this.timeWindowEndTime);
|
cal.setTimeInMillis(this.timeWindowEndTime);
|
||||||
sb.append("End Time:\t").append(sdf.format(cal.getTime())).append(" Z");
|
sb.append("End Time:\t").append(sdf.format(cal.getTime())).append(" Z");
|
||||||
|
cal.setTimeInMillis(this.baseTime);
|
||||||
|
sb.append(StringUtil.NEWLINE);
|
||||||
|
sb.append("Base Time:\t").append(sdf.format(cal.getTime()))
|
||||||
|
.append(" Z");
|
||||||
|
sb.append(StringUtil.NEWLINE).append("Availability Offset: ")
|
||||||
|
.append(offset).append(" minutes");
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
package com.raytheon.uf.edex.datadelivery.bandwidth;
|
package com.raytheon.uf.edex.datadelivery.bandwidth;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Calendar;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -41,7 +42,6 @@ import com.raytheon.uf.edex.datadelivery.bandwidth.dao.BandwidthAllocation;
|
||||||
import com.raytheon.uf.edex.datadelivery.bandwidth.dao.BandwidthBucket;
|
import com.raytheon.uf.edex.datadelivery.bandwidth.dao.BandwidthBucket;
|
||||||
import com.raytheon.uf.edex.datadelivery.bandwidth.dao.BandwidthSubscription;
|
import com.raytheon.uf.edex.datadelivery.bandwidth.dao.BandwidthSubscription;
|
||||||
import com.raytheon.uf.edex.datadelivery.bandwidth.dao.SubscriptionRetrieval;
|
import com.raytheon.uf.edex.datadelivery.bandwidth.dao.SubscriptionRetrieval;
|
||||||
import com.raytheon.uf.edex.datadelivery.bandwidth.retrieval.BandwidthReservation;
|
|
||||||
import com.raytheon.uf.edex.datadelivery.bandwidth.retrieval.RetrievalManager;
|
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.RetrievalPlan;
|
||||||
|
|
||||||
|
@ -63,6 +63,7 @@ import com.raytheon.uf.edex.datadelivery.bandwidth.retrieval.RetrievalPlan;
|
||||||
* Nov 27, 2013 2545 mpduff Get data by network
|
* Nov 27, 2013 2545 mpduff Get data by network
|
||||||
* Dec 11, 2013 2566 bgonzale handle case when there are no reservations.
|
* Dec 11, 2013 2566 bgonzale handle case when there are no reservations.
|
||||||
* Dec 17, 2013 2636 bgonzale Refactored bucket fill in edex.
|
* Dec 17, 2013 2636 bgonzale Refactored bucket fill in edex.
|
||||||
|
* Jan 23, 2014 2636 mpduff Changed download window generation.
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
|
@ -96,9 +97,8 @@ class BandwidthGraphDataAdapter {
|
||||||
|
|
||||||
Collection<RetrievalPlan> retrievalPlans = retrievalManager
|
Collection<RetrievalPlan> retrievalPlans = retrievalManager
|
||||||
.getRetrievalPlans().values();
|
.getRetrievalPlans().values();
|
||||||
Map<Long, SubscriptionRetrieval> retrievals = new HashMap<Long, SubscriptionRetrieval>();
|
|
||||||
Map<Long, List<BandwidthReservation>> reservations = new HashMap<Long, List<BandwidthReservation>>();
|
|
||||||
Map<Network, List<SubscriptionWindowData>> networkMap = new HashMap<Network, List<SubscriptionWindowData>>();
|
Map<Network, List<SubscriptionWindowData>> networkMap = new HashMap<Network, List<SubscriptionWindowData>>();
|
||||||
|
SubscriptionAllocationMapping subAllocationMapping = new SubscriptionAllocationMapping();
|
||||||
|
|
||||||
// One retrieval plan per network
|
// One retrieval plan per network
|
||||||
for (RetrievalPlan retrievalPlan : retrievalPlans) {
|
for (RetrievalPlan retrievalPlan : retrievalPlans) {
|
||||||
|
@ -118,79 +118,71 @@ class BandwidthGraphDataAdapter {
|
||||||
SortedSet<BandwidthBucketDescription> buckets = toDescriptions(bandwidthBuckets);
|
SortedSet<BandwidthBucketDescription> buckets = toDescriptions(bandwidthBuckets);
|
||||||
bandwidthGraphData.addBucketDescriptions(network, buckets);
|
bandwidthGraphData.addBucketDescriptions(network, buckets);
|
||||||
|
|
||||||
// Latency window data - accumulate all the reservations
|
// Latency window data
|
||||||
for (BandwidthBucket bucket : bandwidthBuckets) {
|
List<BandwidthAllocation> allocationList = EdexBandwidthContextFactory
|
||||||
final List<BandwidthAllocation> requests = retrievalPlan
|
.getInstance().bandwidthDao
|
||||||
.getBandwidthAllocationsForBucket(bucket);
|
.getBandwidthAllocations(network);
|
||||||
for (BandwidthAllocation allocation : requests) {
|
|
||||||
if (allocation instanceof SubscriptionRetrieval) {
|
|
||||||
final SubscriptionRetrieval subRetrieval = (SubscriptionRetrieval) allocation;
|
|
||||||
retrievals.put(allocation.getId(), subRetrieval);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
final List<BandwidthReservation> bandwidthReservations = retrievalPlan
|
for (BandwidthAllocation allocation : allocationList) {
|
||||||
.getBandwidthReservationsForBucket(bucket);
|
if (allocation instanceof SubscriptionRetrieval) {
|
||||||
|
final SubscriptionRetrieval subRetrieval = (SubscriptionRetrieval) allocation;
|
||||||
if (bandwidthReservations != null) {
|
String subName = subRetrieval.getBandwidthSubscription()
|
||||||
for (BandwidthReservation reservation : bandwidthReservations) {
|
.getName();
|
||||||
if (!reservations.containsKey(reservation.getId())) {
|
subAllocationMapping.addAllocationForSubscription(subName,
|
||||||
reservations.put(reservation.getId(),
|
allocation);
|
||||||
new ArrayList<BandwidthReservation>());
|
|
||||||
}
|
|
||||||
reservations.get(reservation.getId()).add(reservation);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create time windows for each subscription retrieval by aggregating
|
Map<String, List<BandwidthAllocation>> subAllocationMap = subAllocationMapping
|
||||||
// them with any reservations they have
|
.getSubAllocationMap();
|
||||||
for (Long key : retrievals.keySet()) {
|
for (Map.Entry<String, List<BandwidthAllocation>> entry : subAllocationMap
|
||||||
final SubscriptionRetrieval retrieval = retrievals.get(key);
|
.entrySet()) {
|
||||||
BandwidthSubscription dao = retrieval.getBandwidthSubscription();
|
String sub = entry.getKey();
|
||||||
String subName = dao.getName();
|
for (BandwidthAllocation ba : entry.getValue()) {
|
||||||
SubscriptionPriority priority = dao.getPriority();
|
if (ba instanceof SubscriptionRetrieval) {
|
||||||
String registryId = retrieval.getBandwidthSubscription()
|
((SubscriptionRetrieval) ba).getBandwidthSubscription()
|
||||||
.getRegistryId();
|
.getBaseReferenceTime();
|
||||||
Network network = retrieval.getNetwork();
|
SubscriptionRetrieval sr = (SubscriptionRetrieval) ba;
|
||||||
|
BandwidthSubscription dao = sr.getBandwidthSubscription();
|
||||||
|
SubscriptionPriority priority = dao.getPriority();
|
||||||
|
Calendar baseRefTime = ((SubscriptionRetrieval) ba)
|
||||||
|
.getBandwidthSubscription().getBaseReferenceTime();
|
||||||
|
int offset = ((SubscriptionRetrieval) ba)
|
||||||
|
.getDataSetAvailablityDelay();
|
||||||
|
String registryId = sr.getBandwidthSubscription()
|
||||||
|
.getRegistryId();
|
||||||
|
Network network = sr.getNetwork();
|
||||||
|
|
||||||
SubscriptionWindowData windowData = null;
|
SubscriptionWindowData windowData = null;
|
||||||
|
List<SubscriptionWindowData> subList = networkMap
|
||||||
|
.get(network);
|
||||||
|
for (SubscriptionWindowData subData : subList) {
|
||||||
|
if (subData.getRegistryId().equals(registryId)) {
|
||||||
|
windowData = subData;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
List<SubscriptionWindowData> subList = networkMap.get(network);
|
if (windowData == null) {
|
||||||
for (SubscriptionWindowData subData : subList) {
|
windowData = new SubscriptionWindowData();
|
||||||
if (subData.getRegistryId().equals(registryId)) {
|
windowData.setNetwork(network);
|
||||||
windowData = subData;
|
windowData.setPriority(priority);
|
||||||
break;
|
windowData.setRegistryId(registryId);
|
||||||
|
windowData.setSubscriptionName(sub);
|
||||||
|
networkMap.get(network).add(windowData);
|
||||||
|
}
|
||||||
|
|
||||||
|
final long startMillis = sr.getStartTime()
|
||||||
|
.getTimeInMillis();
|
||||||
|
final long endMillis = sr.getEndTime().getTimeInMillis();
|
||||||
|
TimeWindowData window = new TimeWindowData(startMillis,
|
||||||
|
endMillis);
|
||||||
|
window.setBaseTime(baseRefTime.getTimeInMillis());
|
||||||
|
window.setOffset(offset);
|
||||||
|
windowData.addTimeWindow(window);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (windowData == null) {
|
|
||||||
windowData = new SubscriptionWindowData();
|
|
||||||
windowData.setNetwork(network);
|
|
||||||
windowData.setPriority(priority);
|
|
||||||
windowData.setRegistryId(registryId);
|
|
||||||
windowData.setSubscriptionName(subName);
|
|
||||||
networkMap.get(network).add(windowData);
|
|
||||||
}
|
|
||||||
|
|
||||||
final long startMillis = retrieval.getStartTime().getTimeInMillis();
|
|
||||||
final long endMillis = startMillis
|
|
||||||
+ (retrieval.getSubscriptionLatency() * TimeUtil.MILLIS_PER_MINUTE);
|
|
||||||
TimeWindowData window = new TimeWindowData(startMillis, endMillis);
|
|
||||||
|
|
||||||
List<Long> binStartTimes = new ArrayList<Long>();
|
|
||||||
binStartTimes.add(retrieval.getStartTime().getTimeInMillis());
|
|
||||||
List<BandwidthReservation> retrievalReservations = reservations
|
|
||||||
.get(retrieval.getIdentifier());
|
|
||||||
|
|
||||||
if (retrievalReservations != null) {
|
|
||||||
for (BandwidthReservation reservation : retrievalReservations) {
|
|
||||||
binStartTimes.add(reservation.getBandwidthBucket());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
window.setBinStartTimes(binStartTimes);
|
|
||||||
windowData.addTimeWindow(window);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bandwidthGraphData.setNetworkDataMap(networkMap);
|
bandwidthGraphData.setNetworkDataMap(networkMap);
|
||||||
|
|
|
@ -138,6 +138,7 @@ import com.raytheon.uf.edex.registry.ebxml.exception.EbxmlRegistryException;
|
||||||
* handlePoint method now schedules most recent.
|
* handlePoint method now schedules most recent.
|
||||||
* Jan 14, 2014 2692 dhladky Bad Point scheduling final Empty list.
|
* Jan 14, 2014 2692 dhladky Bad Point scheduling final Empty list.
|
||||||
* Jan 14, 2014 2459 mpduff Change to subscription status.
|
* Jan 14, 2014 2459 mpduff Change to subscription status.
|
||||||
|
* Jan 25, 2014 2636 mpduff Don't do an initial adhoc query for a new subscription.
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
|
@ -639,7 +640,6 @@ public abstract class BandwidthManager<T extends Time, C extends Coverage>
|
||||||
.getCycleTimes();
|
.getCycleTimes();
|
||||||
final boolean subscribedToCycles = !CollectionUtil
|
final boolean subscribedToCycles = !CollectionUtil
|
||||||
.isNullOrEmpty(cycles);
|
.isNullOrEmpty(cycles);
|
||||||
final boolean useMostRecentDataSetUpdate = !subscribedToCycles;
|
|
||||||
|
|
||||||
// The subscription has cycles, so we can allocate bandwidth at
|
// The subscription has cycles, so we can allocate bandwidth at
|
||||||
// expected times
|
// expected times
|
||||||
|
@ -648,8 +648,6 @@ public abstract class BandwidthManager<T extends Time, C extends Coverage>
|
||||||
unscheduled = schedule(subscription, Sets.newTreeSet(cycles));
|
unscheduled = schedule(subscription, Sets.newTreeSet(cycles));
|
||||||
}
|
}
|
||||||
|
|
||||||
unscheduled.addAll(getMostRecent(subscription,
|
|
||||||
useMostRecentDataSetUpdate));
|
|
||||||
return unscheduled;
|
return unscheduled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,100 @@
|
||||||
|
/**
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import com.raytheon.uf.edex.datadelivery.bandwidth.dao.BandwidthAllocation;
|
||||||
|
import com.raytheon.uf.edex.datadelivery.bandwidth.dao.SubscriptionRetrieval;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data class to hold Subscription to download allocations map
|
||||||
|
* BandwidthAllocation id to SubscriptionRetrieval map
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
*
|
||||||
|
* SOFTWARE HISTORY
|
||||||
|
*
|
||||||
|
* Date Ticket# Engineer Description
|
||||||
|
* ------------ ---------- ----------- --------------------------
|
||||||
|
* Jan 23, 2014 2636 mpduff Initial creation.
|
||||||
|
*
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @author mpduff
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class SubscriptionAllocationMapping {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Subscription name to list of BandwidthAllocations for the subscription.
|
||||||
|
*/
|
||||||
|
private final Map<String, List<BandwidthAllocation>> subAllocationMap = new HashMap<String, List<BandwidthAllocation>>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BandwidthAllocation id to SubscriptionRetrieval map.
|
||||||
|
*/
|
||||||
|
private final Map<Long, SubscriptionRetrieval> subRetrievalMap = new HashMap<Long, SubscriptionRetrieval>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*/
|
||||||
|
public SubscriptionAllocationMapping() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add the allocation to the subscription list.
|
||||||
|
*
|
||||||
|
* @param subName
|
||||||
|
* The subscription name for the allocation
|
||||||
|
* @param allocation
|
||||||
|
* The allocation to add to the subscription list
|
||||||
|
*/
|
||||||
|
public void addAllocationForSubscription(String subName,
|
||||||
|
BandwidthAllocation allocation) {
|
||||||
|
if (subAllocationMap.get(subName) == null) {
|
||||||
|
subAllocationMap
|
||||||
|
.put(subName, new ArrayList<BandwidthAllocation>(8));
|
||||||
|
}
|
||||||
|
|
||||||
|
subAllocationMap.get(subName).add(allocation);
|
||||||
|
subRetrievalMap.put(allocation.getId(),
|
||||||
|
(SubscriptionRetrieval) allocation);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the subAllocationMap
|
||||||
|
*/
|
||||||
|
public Map<String, List<BandwidthAllocation>> getSubAllocationMap() {
|
||||||
|
return subAllocationMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the subRetrievalMap
|
||||||
|
*/
|
||||||
|
public Map<Long, SubscriptionRetrieval> getSubRetrievalMap() {
|
||||||
|
return subRetrievalMap;
|
||||||
|
}
|
||||||
|
}
|
|
@ -22,7 +22,6 @@ package com.raytheon.uf.edex.datadelivery.bandwidth.util;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.SortedSet;
|
import java.util.SortedSet;
|
||||||
import java.util.TreeSet;
|
import java.util.TreeSet;
|
||||||
|
@ -79,6 +78,7 @@ import com.raytheon.uf.edex.datadelivery.bandwidth.retrieval.RetrievalStatus;
|
||||||
* Dec 20, 2013 2636 mpduff Fix dataset offset.
|
* Dec 20, 2013 2636 mpduff Fix dataset offset.
|
||||||
* Jan 08, 2014 2615 bgonzale Refactored getRetrievalTimes into RecurringSubscription
|
* Jan 08, 2014 2615 bgonzale Refactored getRetrievalTimes into RecurringSubscription
|
||||||
* calculateStart and calculateEnd methods.
|
* calculateStart and calculateEnd methods.
|
||||||
|
* Jan 24, 2014 2636 mpduff Refactored retrieval time generation.
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @author djohnson
|
* @author djohnson
|
||||||
|
@ -179,40 +179,77 @@ public class BandwidthDaoUtil<T extends Time, C extends Coverage> {
|
||||||
// end time when when subscription is last valid for scheduling based on
|
// end time when when subscription is last valid for scheduling based on
|
||||||
// plan end, subscription end, and active period end.
|
// plan end, subscription end, and active period end.
|
||||||
Calendar subscriptionCalculatedEnd = subscription.calculateEnd(planEnd);
|
Calendar subscriptionCalculatedEnd = subscription.calculateEnd(planEnd);
|
||||||
|
if (statusHandler.isPriorityEnabled(Priority.DEBUG)) {
|
||||||
|
statusHandler.debug("**** PlanStart: " + planStart.getTime());
|
||||||
|
statusHandler.debug("**** PlanEnd : " + planEnd.getTime());
|
||||||
|
statusHandler.debug("**** CalculatedStart: "
|
||||||
|
+ subscriptionCalculatedStart.getTime());
|
||||||
|
statusHandler.debug("**** CalculatedEnd : "
|
||||||
|
+ subscriptionCalculatedEnd.getTime());
|
||||||
|
}
|
||||||
|
|
||||||
|
// drop the start time by 6 hours to account for 4 cycle/day models
|
||||||
|
subscriptionCalculatedStart = TimeUtil.minCalendarFields(
|
||||||
|
subscriptionCalculatedStart, Calendar.MINUTE, Calendar.SECOND,
|
||||||
|
Calendar.MILLISECOND);
|
||||||
|
subscriptionCalculatedStart.add(Calendar.HOUR_OF_DAY, -6);
|
||||||
|
|
||||||
Calendar start = (Calendar) subscriptionCalculatedStart.clone();
|
Calendar start = (Calendar) subscriptionCalculatedStart.clone();
|
||||||
|
int availabilityOffset = 0;
|
||||||
|
try {
|
||||||
|
availabilityOffset = BandwidthUtil.getDataSetAvailablityOffset(
|
||||||
|
subscription, start);
|
||||||
|
} catch (RegistryHandlerException e) {
|
||||||
|
// Error occurred querying the registry. Log and continue on
|
||||||
|
statusHandler
|
||||||
|
.handle(Priority.PROBLEM,
|
||||||
|
"Unable to retrieve data availability offset, using 0 for the offset.",
|
||||||
|
e);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check the offset times against the start time and the base time
|
||||||
|
* against the end time. This prevents a missing download window at the
|
||||||
|
* beginning and the end
|
||||||
|
*/
|
||||||
outerloop: while (!start.after(subscriptionCalculatedEnd)) {
|
outerloop: while (!start.after(subscriptionCalculatedEnd)) {
|
||||||
|
|
||||||
for (Integer cycle : hours) {
|
for (Integer cycle : hours) {
|
||||||
start.set(Calendar.HOUR_OF_DAY, cycle);
|
start.set(Calendar.HOUR_OF_DAY, cycle);
|
||||||
|
Calendar baseTime = (Calendar) start.clone();
|
||||||
|
|
||||||
|
Calendar retrievalTime = TimeUtil.newCalendar(start);
|
||||||
// start base equal-to-or-after subscriptionStart
|
// start base equal-to-or-after subscriptionStart
|
||||||
if (start.compareTo(subscriptionCalculatedStart) >= 0) {
|
if (retrievalTime.compareTo(subscriptionCalculatedStart) >= 0) {
|
||||||
for (Integer minute : minutes) {
|
for (Integer minute : minutes) {
|
||||||
|
retrievalTime.set(Calendar.MINUTE, minute);
|
||||||
start.set(Calendar.MINUTE, minute);
|
start.set(Calendar.MINUTE, minute);
|
||||||
|
|
||||||
|
retrievalTime.add(Calendar.MINUTE, availabilityOffset);
|
||||||
|
|
||||||
// start minutes equal-to-or-after subscriptionStart
|
// start minutes equal-to-or-after subscriptionStart
|
||||||
if (start.compareTo(subscriptionCalculatedStart) >= 0) {
|
if (retrievalTime
|
||||||
|
.compareTo(subscriptionCalculatedStart) >= 0) {
|
||||||
// Check for nonsense
|
// Check for nonsense
|
||||||
if (start.after(subscriptionCalculatedEnd)) {
|
if (start.after(subscriptionCalculatedEnd)) {
|
||||||
break outerloop;
|
break outerloop;
|
||||||
} else {
|
} else {
|
||||||
Calendar time = TimeUtil.newCalendar();
|
Calendar time = TimeUtil.newCalendar();
|
||||||
time.setTimeInMillis(start.getTimeInMillis());
|
time.setTimeInMillis(retrievalTime
|
||||||
|
.getTimeInMillis());
|
||||||
/**
|
/**
|
||||||
* Fine grain check by hour and minute, for
|
* Fine grain check by hour and minute, for
|
||||||
* subscription(start/end),
|
* subscription(start/end),
|
||||||
* activePeriod(start/end)
|
* activePeriod(start/end)
|
||||||
**/
|
**/
|
||||||
// Subscription Start and End time first
|
// Subscription Start and End time first
|
||||||
if (time.after(subscriptionCalculatedEnd)
|
if (start.after(subscriptionCalculatedEnd)
|
||||||
|| time.before(start)) {
|
|| time.before(start)) {
|
||||||
// don't schedule this retrieval time,
|
// don't schedule this retrieval time,
|
||||||
// outside subscription window
|
// outside subscription window
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
subscriptionTimes.add(baseTime);
|
||||||
subscriptionTimes.add(time);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -224,35 +261,6 @@ public class BandwidthDaoUtil<T extends Time, C extends Coverage> {
|
||||||
start.set(Calendar.HOUR_OF_DAY, hours.first());
|
start.set(Calendar.HOUR_OF_DAY, hours.first());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now walk the subscription times and throw away anything outside the
|
|
||||||
// plan hours, taking into account the availability delay...
|
|
||||||
int availabilityOffset = 0;
|
|
||||||
Iterator<Calendar> itr = subscriptionTimes.iterator();
|
|
||||||
while (itr.hasNext()) {
|
|
||||||
availabilityOffset = 0;
|
|
||||||
Calendar time = itr.next();
|
|
||||||
|
|
||||||
try {
|
|
||||||
availabilityOffset = BandwidthUtil.getDataSetAvailablityOffset(
|
|
||||||
subscription, time);
|
|
||||||
} catch (RegistryHandlerException e) {
|
|
||||||
// Error occurred querying the registry. Log and continue on
|
|
||||||
statusHandler
|
|
||||||
.handle(Priority.PROBLEM,
|
|
||||||
"Unable to retrieve data availability offset, using 0 for the offset.",
|
|
||||||
e);
|
|
||||||
}
|
|
||||||
|
|
||||||
Calendar withAvailabilityOffset = TimeUtil.newCalendar(time);
|
|
||||||
withAvailabilityOffset.add(Calendar.MINUTE, availabilityOffset);
|
|
||||||
|
|
||||||
// We allow base reference times that are still possible to retrieve
|
|
||||||
// within the availability window to be included
|
|
||||||
if (withAvailabilityOffset.before(planStart) || time.after(planEnd)) {
|
|
||||||
itr.remove();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return subscriptionTimes;
|
return subscriptionTimes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,6 @@ import java.io.File;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.SortedSet;
|
import java.util.SortedSet;
|
||||||
|
@ -89,6 +88,7 @@ import com.raytheon.uf.edex.datadelivery.bandwidth.util.BandwidthUtil;
|
||||||
* Sept 25, 2013 1797 dhladky separated time from gridded time
|
* Sept 25, 2013 1797 dhladky separated time from gridded time
|
||||||
* Oct 21, 2013 2292 mpduff Implement multiple data types.
|
* Oct 21, 2013 2292 mpduff Implement multiple data types.
|
||||||
* Dec 02, 2013 2545 mpduff Get data by network.
|
* Dec 02, 2013 2545 mpduff Get data by network.
|
||||||
|
* Jan 23, 2014 2636 mpduff Removed TimeWindow individual bin code.
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @author djohnson
|
* @author djohnson
|
||||||
|
@ -583,59 +583,6 @@ public class BandwidthServiceIntTest<T extends Time, C extends Coverage>
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"Expected there to be two time windows for this subscription over 2 days",
|
"Expected there to be two time windows for this subscription over 2 days",
|
||||||
2, subscriptionOneTimeWindows.size());
|
2, subscriptionOneTimeWindows.size());
|
||||||
final TimeWindowData firstTimeWindow = subscriptionOneTimeWindows
|
|
||||||
.get(0);
|
|
||||||
final TimeWindowData secondTimeWindow = subscriptionOneTimeWindows
|
|
||||||
.get(1);
|
|
||||||
|
|
||||||
final List<Long> firstWindowBinStartTimes = firstTimeWindow
|
|
||||||
.getBinStartTimes();
|
|
||||||
final List<Long> secondWindowBinStartTimes = secondTimeWindow
|
|
||||||
.getBinStartTimes();
|
|
||||||
|
|
||||||
assertEquals("Incorrect number of bin start times found.", 2,
|
|
||||||
firstWindowBinStartTimes.size());
|
|
||||||
assertEquals("Incorrect number of bin start times found.", 2,
|
|
||||||
secondWindowBinStartTimes.size());
|
|
||||||
|
|
||||||
final List<SubscriptionRetrieval> subscriptionRetrievals = bandwidthDao
|
|
||||||
.getSubscriptionRetrievals(subscription.getProvider(),
|
|
||||||
subscription.getDataSetName());
|
|
||||||
|
|
||||||
final Iterator<SubscriptionRetrieval> iter = subscriptionRetrievals
|
|
||||||
.iterator();
|
|
||||||
|
|
||||||
// First retrieval window
|
|
||||||
long expectedBinStartTime = iter.next().getStartTime()
|
|
||||||
.getTimeInMillis();
|
|
||||||
|
|
||||||
assertEquals(
|
|
||||||
"Incorrect first bin start time in the first time window.",
|
|
||||||
expectedBinStartTime, firstWindowBinStartTimes.get(0)
|
|
||||||
.longValue());
|
|
||||||
|
|
||||||
expectedBinStartTime += (TimeUtil.MILLIS_PER_MINUTE * 3);
|
|
||||||
assertEquals(
|
|
||||||
"Incorrect second bin start time in the first time window.",
|
|
||||||
expectedBinStartTime, firstWindowBinStartTimes.get(1)
|
|
||||||
.longValue());
|
|
||||||
|
|
||||||
// Second retrieval window
|
|
||||||
expectedBinStartTime = iter.next().getStartTime().getTimeInMillis();
|
|
||||||
|
|
||||||
assertEquals(
|
|
||||||
"Incorrect first bin start time in the second time window.",
|
|
||||||
expectedBinStartTime, secondWindowBinStartTimes.get(0)
|
|
||||||
.longValue());
|
|
||||||
|
|
||||||
// The middle bucket was already reserved, so we went ahead six minutes
|
|
||||||
// and used that bucket
|
|
||||||
expectedBinStartTime += (TimeUtil.MILLIS_PER_MINUTE * 6);
|
|
||||||
|
|
||||||
assertEquals(
|
|
||||||
"Incorrect second bin start time in the second time window.",
|
|
||||||
expectedBinStartTime, secondWindowBinStartTimes.get(1)
|
|
||||||
.longValue());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -34,7 +34,6 @@ import com.raytheon.uf.common.datadelivery.registry.Network;
|
||||||
import com.raytheon.uf.common.time.util.TimeUtil;
|
import com.raytheon.uf.common.time.util.TimeUtil;
|
||||||
import com.raytheon.uf.edex.datadelivery.bandwidth.dao.BandwidthBucket;
|
import com.raytheon.uf.edex.datadelivery.bandwidth.dao.BandwidthBucket;
|
||||||
import com.raytheon.uf.edex.datadelivery.bandwidth.retrieval.RetrievalManager;
|
import com.raytheon.uf.edex.datadelivery.bandwidth.retrieval.RetrievalManager;
|
||||||
import com.raytheon.uf.edex.datadelivery.bandwidth.retrieval.RetrievalPlan;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test class for {@link BandwidthGraphdataAdapter}.
|
* Test class for {@link BandwidthGraphdataAdapter}.
|
||||||
|
@ -45,7 +44,8 @@ import com.raytheon.uf.edex.datadelivery.bandwidth.retrieval.RetrievalPlan;
|
||||||
*
|
*
|
||||||
* Date Ticket# Engineer Description
|
* Date Ticket# Engineer Description
|
||||||
* ------------ ---------- ----------- --------------------------
|
* ------------ ---------- ----------- --------------------------
|
||||||
* Nov 25, 2013 mpduff Initial creation
|
* Nov 25, 2013 mpduff Initial creation.
|
||||||
|
* Jan 25, 2014 2636 mpduff Removed test that has since become invalid.
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
|
@ -59,8 +59,6 @@ public class BandwidthGraphDataAdapterTest {
|
||||||
|
|
||||||
private static final RetrievalManager retrievalManagerMock = mock(RetrievalManager.class);
|
private static final RetrievalManager retrievalManagerMock = mock(RetrievalManager.class);
|
||||||
|
|
||||||
private static final RetrievalPlan retrievalPlan = new RetrievalPlan();
|
|
||||||
|
|
||||||
private static final SortedSet<BandwidthBucket> bucketSet = new TreeSet<BandwidthBucket>();
|
private static final SortedSet<BandwidthBucket> bucketSet = new TreeSet<BandwidthBucket>();
|
||||||
|
|
||||||
private static final BandwidthGraphDataAdapter adapter = new BandwidthGraphDataAdapter(
|
private static final BandwidthGraphDataAdapter adapter = new BandwidthGraphDataAdapter(
|
||||||
|
@ -141,33 +139,4 @@ public class BandwidthGraphDataAdapterTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testOverfilledBucketsOverflowToLaterBuckets() {
|
|
||||||
Iterator<BandwidthBucket> iter = bucketSet.iterator();
|
|
||||||
|
|
||||||
// Get the first bucket and fill it 4.5 buckets worth
|
|
||||||
BandwidthBucket bucket = iter.next();
|
|
||||||
bucket.setCurrentSize((BUCKET_SIZE * 4) + (BUCKET_SIZE / 2));
|
|
||||||
|
|
||||||
int idx = 0;
|
|
||||||
SortedSet<BandwidthBucketDescription> descriptions = adapter
|
|
||||||
.toDescriptions(bucketSet);
|
|
||||||
|
|
||||||
Iterator<BandwidthBucketDescription> it = descriptions.iterator();
|
|
||||||
while (it.hasNext()) {
|
|
||||||
BandwidthBucketDescription bbd = it.next();
|
|
||||||
if (idx <= 3) {
|
|
||||||
assertTrue("First four buckets should be full",
|
|
||||||
bbd.getUsedBytes() == bucket.getBucketSize());
|
|
||||||
idx++;
|
|
||||||
} else if (idx == 4) {
|
|
||||||
assertTrue("Bucket should be half full",
|
|
||||||
bbd.getUsedBytes() == bucket.getBucketSize() / 2);
|
|
||||||
idx++;
|
|
||||||
} else {
|
|
||||||
assertTrue("Bucket should be empty", bbd.getUsedBytes() == 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue