import org.opendaylight.controller.protocol_plugin.openflow.vendorextension.v6extension.V6Match;
import org.opendaylight.controller.protocol_plugin.openflow.vendorextension.v6extension.V6StatsReply;
import org.opendaylight.controller.protocol_plugin.openflow.vendorextension.v6extension.V6StatsRequest;
+import org.opendaylight.controller.sal.connection.IPluginOutConnectionService;
import org.opendaylight.controller.sal.core.Node;
import org.opendaylight.controller.sal.core.NodeConnector;
import org.opendaylight.controller.sal.core.Property;
import org.slf4j.LoggerFactory;
/**
- * It periodically polls the different OF statistics from the OF switches and
- * caches them for quick retrieval for the above layers' modules It also
- * provides an API to directly query the switch about the statistics
+ * Periodically polls the different OF statistics from the OF switches, caches
+ * them, and publishes results towards SAL. It also provides an API to directly
+ * query the switch for any specific statistics.
*/
-public class OFStatisticsManager implements IOFStatisticsManager,
-IInventoryShimExternalListener, CommandProvider {
+public class OFStatisticsManager implements IOFStatisticsManager, IInventoryShimExternalListener, CommandProvider {
private static final Logger log = LoggerFactory.getLogger(OFStatisticsManager.class);
private static final int INITIAL_SIZE = 64;
private static final long FLOW_STATS_PERIOD = 10000;
private ConcurrentMap<Long, List<OFStatistics>> descStatistics;
private ConcurrentMap<Long, List<OFStatistics>> portStatistics;
private ConcurrentMap<Long, List<OFStatistics>> tableStatistics;
- private List<OFStatistics> dummyList;
private ConcurrentMap<Long, StatisticsTicks> statisticsTimerTicks;
protected BlockingQueue<StatsRequest> pendingStatsRequests;
protected BlockingQueue<Long> switchPortStatsUpdated;
private ConcurrentMap<Long, Boolean> switchSupportsVendorExtStats;
// Per port sampled (every portStatsPeriod) transmit rate
private Map<Long, Map<Short, TxRates>> txRates;
- private Set<IOFStatisticsListener> statisticsListeners;
+ private Set<IOFStatisticsListener> statisticsListeners = new CopyOnWriteArraySet<IOFStatisticsListener>();
/**
* The object containing the latest factoredSamples tx rate samples for a
}
return statsQueueSize;
}
+
+ IPluginOutConnectionService connectionPluginOutService;
+ void setIPluginOutConnectionService(IPluginOutConnectionService s) {
+ connectionPluginOutService = s;
+ }
+
+ void unsetIPluginOutConnectionService(IPluginOutConnectionService s) {
+ if (connectionPluginOutService == s) {
+ connectionPluginOutService = null;
+ }
+ }
+
/**
* Function called by the dependency manager when all the required
* dependencies are satisfied
descStatistics = new ConcurrentHashMap<Long, List<OFStatistics>>();
portStatistics = new ConcurrentHashMap<Long, List<OFStatistics>>();
tableStatistics = new ConcurrentHashMap<Long, List<OFStatistics>>();
- dummyList = new ArrayList<OFStatistics>(1);
pendingStatsRequests = new LinkedBlockingQueue<StatsRequest>(getStatsQueueSize());
statisticsTimerTicks = new ConcurrentHashMap<Long, StatisticsTicks>(INITIAL_SIZE);
switchPortStatsUpdated = new LinkedBlockingQueue<Long>(INITIAL_SIZE);
switchSupportsVendorExtStats = new ConcurrentHashMap<Long, Boolean>(INITIAL_SIZE);
txRates = new HashMap<Long, Map<Short, TxRates>>(INITIAL_SIZE);
- statisticsListeners = new CopyOnWriteArraySet<IOFStatisticsListener>();
configStatsPollIntervals();
// Initialize managed timers
- statisticsTimer = new Timer();
+ statisticsTimer = new Timer("Statistics Timer Ticks");
statisticsTimerTask = new TimerTask() {
@Override
public void run() {
} catch (InterruptedException e) {
log.warn("Flow Statistics Collector thread "
+ "interrupted", e);
+ return;
}
}
}
updatePortsTxRate(switchId);
} catch (InterruptedException e) {
log.warn("TX Rate Updater thread interrupted", e);
+ return;
}
}
}
*
*/
void destroy() {
+ statisticsListeners.clear();
}
/**
}
private void printInfoMessage(String type, StatsRequest request) {
- log.info("{} stats request not inserted for switch: {}. Queue size: {}. Collector state: {}.",
+ log.trace("{} stats request not inserted for switch: {}. Queue size: {}. Collector state: {}.",
new Object[] {type, HexString.toHexString(request.switchId), pendingStatsRequests.size(),
statisticsCollector.getState().toString() });
}
List<OFStatistics> values = this.fetchStatisticsFromSwitch(switchId, statType, null);
// If got a valid response update local cache and notify listeners
- if (values != null && !values.isEmpty()) {
+ if (!values.isEmpty()) {
switch (statType) {
case FLOW:
case VENDOR:
@SuppressWarnings("unchecked")
private List<OFStatistics> fetchStatisticsFromSwitch(Long switchId,
OFStatisticsType statsType, Object target) {
- List<OFStatistics> values = null;
+ List<OFStatistics> values = Collections.emptyList();
String type = null;
ISwitch sw = controller.getSwitch(switchId);
// Malformed request
log.warn("Invalid target type for Flow stats request: {}",
target.getClass());
- return null;
+ return Collections.emptyList();
} else {
// Specific flow request
match = (OFMatch) target;
// Malformed request
log.warn("Invalid target type for Port stats request: {}",
target.getClass());
- return null;
+ return Collections.emptyList();
} else {
// Specific port request
targetPort = (Short) target;
// Malformed request
log.warn("Invalid table id for table stats request: {}",
target.getClass());
- return null;
+ return Collections.emptyList();
}
byte targetTable = (Byte) target;
OFTableStatistics specificReq = new OFTableStatistics();
* Check on emptiness as interference between add and get is still
* possible on the inner list (the concurrentMap entry's value)
*/
- return (list == null || list.isEmpty()) ? this.dummyList
+ return (list == null || list.isEmpty()) ? Collections.<OFStatistics>emptyList()
: (list.get(0) instanceof OFVendorStatistics) ? this
.v6StatsListToOFStatsList(list) : list;
}
* possible on the inner list (the concurrentMap entry's value)
*/
if (statsList == null || statsList.isEmpty()) {
- return this.dummyList;
+ return Collections.emptyList();
}
if (statsList.get(0) instanceof OFVendorStatistics) {
for (OFStatistics stats : targetList) {
V6StatsReply v6Stats = (V6StatsReply) stats;
V6Match v6Match = v6Stats.getMatch();
- if (v6Stats.getPriority() == priority && v6Match.equals(targetMatch)) {
+ if (v6Stats.getPriority() == priority && targetMatch.equals(v6Match)) {
List<OFStatistics> list = new ArrayList<OFStatistics>();
list.add(stats);
return list;
} else {
for (OFStatistics stats : statsList) {
OFFlowStatisticsReply flowStats = (OFFlowStatisticsReply) stats;
- if (flowStats.getPriority() == priority && flowStats.getMatch().equals(ofMatch)) {
+ if (flowStats.getPriority() == priority && ofMatch.equals(flowStats.getMatch())) {
List<OFStatistics> list = new ArrayList<OFStatistics>();
list.add(stats);
return list;
}
}
}
- return this.dummyList;
+ return Collections.emptyList();
}
/*
* Converts the v6 vendor statistics to the OFStatistics
*/
- private List<OFStatistics> v6StatsListToOFStatsList(
- List<OFStatistics> statistics) {
+ private List<OFStatistics> v6StatsListToOFStatsList(List<OFStatistics> statistics) {
+ if (statistics == null || statistics.isEmpty()) {
+ return Collections.emptyList();
+ }
List<OFStatistics> v6statistics = new ArrayList<OFStatistics>();
- if (statistics != null && !statistics.isEmpty()) {
- for (OFStatistics stats : statistics) {
- if (stats instanceof OFVendorStatistics) {
- List<OFStatistics> r = getV6ReplyStatistics((OFVendorStatistics) stats);
- if (r != null) {
- v6statistics.addAll(r);
- }
+ for (OFStatistics stats : statistics) {
+ if (stats instanceof OFVendorStatistics) {
+ List<OFStatistics> r = getV6ReplyStatistics((OFVendorStatistics) stats);
+ if (r != null) {
+ v6statistics.addAll(r);
}
}
}
OFVendorStatistics stat) {
int length = stat.getLength();
List<OFStatistics> results = new ArrayList<OFStatistics>();
- if (length < 12)
- return null; // Nicira Hdr is 12 bytes. We need atleast that much
+ if (length < 12) {
+ // Nicira Hdr is 12 bytes. We need at least that much
+ return Collections.emptyList();
+ }
ByteBuffer data = ByteBuffer.allocate(length);
stat.writeTo(data);
data.rewind();
int vendor = data.getInt(); // first 4 bytes is vendor id.
if (vendor != V6StatsRequest.NICIRA_VENDOR_ID) {
log.warn("Unexpected vendor id: 0x{}", Integer.toHexString(vendor));
- return null;
+ return Collections.emptyList();
} else {
// go ahead by 8 bytes which is 8 bytes of 0
data.getLong(); // should be all 0's
while (length > 0) {
v6statsreply = new V6StatsReply();
min_len = v6statsreply.getLength();
- if (length < v6statsreply.getLength())
+ if (length < v6statsreply.getLength()) {
break;
+ }
v6statsreply.setActionFactory(stat.getActionFactory());
v6statsreply.readFrom(data);
- if (v6statsreply.getLength() < min_len)
+ if (v6statsreply.getLength() < min_len) {
break;
+ }
v6statsreply.setVendorId(vendor);
log.trace("V6StatsReply: {}", v6statsreply);
length -= v6statsreply.getLength();
}
}
- List<OFStatistics> list = this.fetchStatisticsFromSwitch(switchId, statType,
- target);
+ List<OFStatistics> list = this.fetchStatisticsFromSwitch(switchId, statType, target);
- return (list == null) ? null :
- (statType == OFStatisticsType.VENDOR) ? v6StatsListToOFStatsList(list) : list;
+ return (statType == OFStatisticsType.VENDOR) ? v6StatsListToOFStatsList(list) : list;
}
@Override
public List<OFStatistics> getOFDescStatistics(Long switchId) {
- if (!descStatistics.containsKey(switchId))
- return this.dummyList;
+ if (!descStatistics.containsKey(switchId)) {
+ return Collections.emptyList();
+ }
return descStatistics.get(switchId);
}
@Override
public List<OFStatistics> getOFPortStatistics(Long switchId) {
if (!portStatistics.containsKey(switchId)) {
- return this.dummyList;
+ return Collections.emptyList();
}
return portStatistics.get(switchId);
@Override
public List<OFStatistics> getOFPortStatistics(Long switchId, short portId) {
if (!portStatistics.containsKey(switchId)) {
- return this.dummyList;
+ return Collections.emptyList();
}
List<OFStatistics> list = new ArrayList<OFStatistics>(1);
for (OFStatistics stats : portStatistics.get(switchId)) {
@Override
public List<OFStatistics> getOFTableStatistics(Long switchId) {
if (!tableStatistics.containsKey(switchId)) {
- return this.dummyList;
+ return Collections.emptyList();
}
return tableStatistics.get(switchId);
@Override
public List<OFStatistics> getOFTableStatistics(Long switchId, Byte tableId) {
if (!tableStatistics.containsKey(switchId)) {
- return this.dummyList;
+ return Collections.emptyList();
}
List<OFStatistics> list = new ArrayList<OFStatistics>(1);