X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=blobdiff_plain;f=opendaylight%2Fprotocol_plugins%2Fopenflow%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fprotocol_plugin%2Fopenflow%2Finternal%2FOFStatisticsManager.java;h=78fddc773637c8aefb338b729d4e416e66e85441;hp=98a296260628d0e4b303217af344390a3ec43cc6;hb=e2f7aaa41e482815ca1d4495eb85c8653cd903ab;hpb=40baffab6be9315bd15c3d59dfd6b8e6685e659a diff --git a/opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/internal/OFStatisticsManager.java b/opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/internal/OFStatisticsManager.java index 98a2962606..78fddc7736 100644 --- a/opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/internal/OFStatisticsManager.java +++ b/opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/internal/OFStatisticsManager.java @@ -54,6 +54,7 @@ import org.openflow.protocol.statistics.OFPortStatisticsRequest; import org.openflow.protocol.statistics.OFQueueStatisticsRequest; import org.openflow.protocol.statistics.OFStatistics; import org.openflow.protocol.statistics.OFStatisticsType; +import org.openflow.protocol.statistics.OFTableStatistics; import org.openflow.protocol.statistics.OFVendorStatistics; import org.openflow.util.HexString; import org.osgi.framework.BundleContext; @@ -67,23 +68,26 @@ import org.slf4j.LoggerFactory; * provides an API to directly query the switch about the statistics */ public class OFStatisticsManager implements IOFStatisticsManager, - IInventoryShimExternalListener, CommandProvider { +IInventoryShimExternalListener, CommandProvider { private static final Logger log = LoggerFactory .getLogger(OFStatisticsManager.class); private static final int initialSize = 64; private static final long flowStatsPeriod = 10000; private static final long descriptionStatsPeriod = 60000; private static final long portStatsPeriod = 5000; + private static final long tableStatsPeriod = 10000; private static final long tickPeriod = 1000; private static short statisticsTickNumber = (short) (flowStatsPeriod / tickPeriod); private static short descriptionTickNumber = (short) (descriptionStatsPeriod / tickPeriod); private static short portTickNumber = (short) (portStatsPeriod / tickPeriod); + private static short tableTickNumber = (short) (tableStatsPeriod / tickPeriod); private static short factoredSamples = (short) 2; private static short counter = 1; private IController controller = null; private ConcurrentMap> flowStatistics; private ConcurrentMap> descStatistics; private ConcurrentMap> portStatistics; + private ConcurrentMap> tableStatistics; private List dummyList; private ConcurrentMap statisticsTimerTicks; protected BlockingQueue pendingStatsRequests; @@ -164,6 +168,7 @@ public class OFStatisticsManager implements IOFStatisticsManager, flowStatistics = new ConcurrentHashMap>(); descStatistics = new ConcurrentHashMap>(); portStatistics = new ConcurrentHashMap>(); + tableStatistics = new ConcurrentHashMap>(); dummyList = new ArrayList(1); statisticsTimerTicks = new ConcurrentHashMap( initialSize); @@ -175,6 +180,8 @@ public class OFStatisticsManager implements IOFStatisticsManager, txRates = new HashMap>(initialSize); descriptionListeners = new HashSet(); + configStatsPollIntervals(); + // Initialize managed timers statisticsTimer = new Timer(); statisticsTimerTask = new TimerTask() { @@ -281,6 +288,7 @@ public class OFStatisticsManager implements IOFStatisticsManager, type = t; } + @Override public String toString() { return "SReq = {switchId=" + switchId + ", type=" + type + "}"; } @@ -337,6 +345,7 @@ public class OFStatisticsManager implements IOFStatisticsManager, private short flowStatisticsTicks; private short descriptionTicks; private short portStatisticsTicks; + private short tableStatisticsTicks; public StatisticsTicks(boolean scattered) { if (scattered) { @@ -348,10 +357,12 @@ public class OFStatisticsManager implements IOFStatisticsManager, % statisticsTickNumber); descriptionTicks = (short) (1 + counter % descriptionTickNumber); portStatisticsTicks = (short) (1 + counter % portTickNumber); + tableStatisticsTicks = (short) (1 + counter % tableTickNumber); } else { flowStatisticsTicks = statisticsTickNumber; descriptionTicks = descriptionTickNumber; portStatisticsTicks = portTickNumber; + tableStatisticsTicks = tableTickNumber; } } @@ -385,9 +396,20 @@ public class OFStatisticsManager implements IOFStatisticsManager, return false; } + public boolean decrementTableTicksIsZero() { + // Please ensure no code is inserted between the if check and the + // descriptionTicks reset + if(--tableStatisticsTicks == 0) { + tableStatisticsTicks = tableTickNumber; + return true; + } + return false; + } + + @Override public String toString() { return "{fT=" + flowStatisticsTicks + ",dT=" + descriptionTicks - + ",pT=" + portStatisticsTicks + "}"; + + ",pT=" + portStatisticsTicks + ",tT=" + tableStatisticsTicks + "}"; } } @@ -436,6 +458,16 @@ public class OFStatisticsManager implements IOFStatisticsManager, printInfoMessage("Port", request); } } + + if(clock.decrementTableTicksIsZero() == true) { + request = new StatsRequest(switchId, OFStatisticsType.TABLE); + // If a request for this switch is already in the queue, skip to + // add this new request + if (!pendingStatsRequests.contains(request) + && false == pendingStatsRequests.offer(request)) { + printInfoMessage("Table", request); + } + } } } @@ -452,6 +484,8 @@ public class OFStatisticsManager implements IOFStatisticsManager, OFStatisticsType.DESC)); pendingStatsRequests.remove(new StatsRequest(switchId, OFStatisticsType.PORT)); + pendingStatsRequests.remove(new StatsRequest(switchId, + OFStatisticsType.TABLE)); // Take care of the TX rate databases switchPortStatsUpdated.remove(switchId); txRates.remove(switchId); @@ -489,6 +523,9 @@ public class OFStatisticsManager implements IOFStatisticsManager, // Wake up the thread which maintains the TX byte counters for // each port switchPortStatsUpdated.offer(switchId); + } else if (statType == OFStatisticsType.TABLE) { + // Overwrite cache + tableStatistics.put(switchId, values); } } } @@ -589,6 +626,20 @@ public class OFStatisticsManager implements IOFStatisticsManager, } else if (statsType == OFStatisticsType.DESC) { type = "DESC"; } else if (statsType == OFStatisticsType.TABLE) { + if(target != null){ + if (!(target instanceof Byte)) { + // Malformed request + log.warn("Invalid table id for table stats request: {}", + target.getClass()); + return null; + } + byte targetTable = (Byte) target; + OFTableStatistics specificReq = new OFTableStatistics(); + specificReq.setTableId(targetTable); + req.setStatistics(Collections + .singletonList((OFStatistics) specificReq)); + requestLength += specificReq.getLength(); + } type = "TABLE"; } req.setLengthU(requestLength); @@ -600,7 +651,7 @@ public class OFStatisticsManager implements IOFStatisticsManager, } else if (result instanceof OFError) { log.warn("Switch {} failed to handle ({}) stats request: {}", new Object[] { HexString.toHexString(switchId), type, - Utils.getOFErrorString((OFError) result) }); + Utils.getOFErrorString((OFError) result) }); if (this.switchSupportsVendorExtStats.get(switchId) == Boolean.TRUE) { log.warn( "Switching back to regular Flow stats requests for switch {}", @@ -701,8 +752,10 @@ public class OFStatisticsManager implements IOFStatisticsManager, ByteBuffer data = ByteBuffer.allocate(length); stat.writeTo(data); data.rewind(); - log.trace("getV6ReplyStatistics: Buffer BYTES ARE {}", - HexString.toHexString(data.array())); + if (log.isTraceEnabled()) { + log.trace("getV6ReplyStatistics: Buffer BYTES ARE {}", + HexString.toHexString(data.array())); + } int vendor = data.getInt(); // first 4 bytes is vendor id. if (vendor != V6StatsRequest.NICIRA_VENDOR_ID) { @@ -787,6 +840,31 @@ public class OFStatisticsManager implements IOFStatisticsManager, return list; } + @Override + public List getOFTableStatistics(Long switchId) { + if (!tableStatistics.containsKey(switchId)) { + return this.dummyList; + } + + return tableStatistics.get(switchId); + } + + @Override + public List getOFTableStatistics(Long switchId, Byte tableId) { + if (!tableStatistics.containsKey(switchId)) { + return this.dummyList; + } + + List list = new ArrayList(1); + for (OFStatistics stats : tableStatistics.get(switchId)) { + if (((OFTableStatistics) stats).getTableId() == tableId) { + list.add(stats); + break; + } + } + return list; + } + @Override public int getFlowsNumber(long switchId) { return this.flowStatistics.get(switchId).size(); @@ -876,6 +954,8 @@ public class OFStatisticsManager implements IOFStatisticsManager, help.append("---OF Statistics Manager utilities---\n"); help.append("\t ofdumpstatsmgr - " + "Print Internal Stats Mgr db\n"); + help.append("\t ofstatsmgrintervals (in seconds) - " + + "Set/Show flow/port/dedscription stats poll intervals\n"); return help.toString(); } @@ -932,6 +1012,7 @@ public class OFStatisticsManager implements IOFStatisticsManager, ci.println("Flow Stats Period: " + statisticsTickNumber + " s"); ci.println("Desc Stats Period: " + descriptionTickNumber + " s"); ci.println("Port Stats Period: " + portTickNumber + " s"); + ci.println("Table Stats Period: " + tableTickNumber + " s"); } public void _resetSwitchCapability(CommandInterpreter ci) { @@ -1001,33 +1082,91 @@ public class OFStatisticsManager implements IOFStatisticsManager, public void _ofstatsmgrintervals(CommandInterpreter ci) { String flowStatsInterv = ci.nextArgument(); String portStatsInterv = ci.nextArgument(); + String descStatsInterv = ci.nextArgument(); + String tableStatsInterv = ci.nextArgument(); - if (flowStatsInterv == null || portStatsInterv == null) { - - ci.println("Usage: ostatsmgrintervals (in seconds)"); + if (flowStatsInterv == null || portStatsInterv == null + || descStatsInterv == null) { + ci.println("Usage: ostatsmgrintervals (in seconds)"); ci.println("Current Values: fP=" + statisticsTickNumber + "s pP=" - + portTickNumber + "s"); + + portTickNumber + "s dP=" + descriptionTickNumber + "s"); return; } - Short fP, pP; + Short fP, pP, dP, tP; try { fP = Short.parseShort(flowStatsInterv); pP = Short.parseShort(portStatsInterv); + dP = Short.parseShort(descStatsInterv); + tP = Short.parseShort(tableStatsInterv); } catch (Exception e) { ci.println("Invalid format values: " + e.getMessage()); return; } - if (pP <= 1 || fP <= 1) { - ci.println("Invalid values. fP and pP have to be greater than 1."); + if (pP <= 1 || fP <= 1 || dP <= 1 || tP <= 1) { + ci.println("Invalid values. fP, pP, dP, tP have to be greater than 1."); return; } statisticsTickNumber = fP; portTickNumber = pP; + descriptionTickNumber = dP; + tableTickNumber = tP; ci.println("New Values: fP=" + statisticsTickNumber + "s pP=" - + portTickNumber + "s"); + + portTickNumber + "s dP=" + descriptionTickNumber + "s tP=" + + tableTickNumber + "s"); } + /** + * This method retrieves user configurations from config.ini and updates + * statisticsTickNumber/portTickNumber/descriptionTickNumber accordingly. + */ + private void configStatsPollIntervals() { + String fsStr = System.getProperty("of.flowStatsPollInterval"); + String psStr = System.getProperty("of.portStatsPollInterval"); + String dsStr = System.getProperty("of.descStatsPollInterval"); + String tsStr = System.getProperty("of.tableStatsPollInterval"); + Short fs, ps, ds, ts; + + if (fsStr != null) { + try { + fs = Short.parseShort(fsStr); + if (fs > 0) { + statisticsTickNumber = fs; + } + } catch (Exception e) { + } + } + + if (psStr != null) { + try { + ps = Short.parseShort(psStr); + if (ps > 0) { + portTickNumber = ps; + } + } catch (Exception e) { + } + } + + if (dsStr != null) { + try { + ds = Short.parseShort(dsStr); + if (ds > 0) { + descriptionTickNumber = ds; + } + } catch (Exception e) { + } + } + + if (tsStr != null) { + try{ + ts = Short.parseShort(tsStr); + if (ts > 0) { + tableTickNumber = ts; + } + } catch (Exception e) { + } + } + } }