Revert "Checkstyle enforcer"
[controller.git] / opendaylight / protocol_plugins / openflow / src / main / java / org / opendaylight / controller / protocol_plugin / openflow / internal / OFStatisticsManager.java
index 98a296260628d0e4b303217af344390a3ec43cc6..78fddc773637c8aefb338b729d4e416e66e85441 100644 (file)
@@ -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<Long, List<OFStatistics>> flowStatistics;
     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;
@@ -164,6 +168,7 @@ public class OFStatisticsManager implements IOFStatisticsManager,
         flowStatistics = new ConcurrentHashMap<Long, List<OFStatistics>>();
         descStatistics = new ConcurrentHashMap<Long, List<OFStatistics>>();
         portStatistics = new ConcurrentHashMap<Long, List<OFStatistics>>();
+        tableStatistics = new ConcurrentHashMap<Long, List<OFStatistics>>();
         dummyList = new ArrayList<OFStatistics>(1);
         statisticsTimerTicks = new ConcurrentHashMap<Long, StatisticsTicks>(
                 initialSize);
@@ -175,6 +180,8 @@ public class OFStatisticsManager implements IOFStatisticsManager,
         txRates = new HashMap<Long, Map<Short, TxRates>>(initialSize);
         descriptionListeners = new HashSet<IStatisticsListener>();
 
+        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<OFStatistics> getOFTableStatistics(Long switchId) {
+        if (!tableStatistics.containsKey(switchId)) {
+            return this.dummyList;
+        }
+
+        return tableStatistics.get(switchId);
+    }
+
+    @Override
+    public List<OFStatistics> getOFTableStatistics(Long switchId, Byte tableId) {
+        if (!tableStatistics.containsKey(switchId)) {
+            return this.dummyList;
+        }
+
+        List<OFStatistics> list = new ArrayList<OFStatistics>(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 <fP> <pP> <dP>(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 <fP> <pP> (in seconds)");
+        if (flowStatsInterv == null || portStatsInterv == null
+                || descStatsInterv == null) {
+            ci.println("Usage: ostatsmgrintervals <fP> <pP> <dP>(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) {
+            }
+        }
+    }
 }