CORD-13:Table Statistics support along with CLI and REST

Change-Id: Ic7facc73754c4b1e7c9c5a9eecd217f89a67e135
diff --git a/openflow/ctl/src/main/java/org/onosproject/openflow/controller/impl/OpenFlowControllerImpl.java b/openflow/ctl/src/main/java/org/onosproject/openflow/controller/impl/OpenFlowControllerImpl.java
index a25b7a8..d042994 100644
--- a/openflow/ctl/src/main/java/org/onosproject/openflow/controller/impl/OpenFlowControllerImpl.java
+++ b/openflow/ctl/src/main/java/org/onosproject/openflow/controller/impl/OpenFlowControllerImpl.java
@@ -47,6 +47,8 @@
 import org.projectfloodlight.openflow.protocol.OFFactories;
 import org.projectfloodlight.openflow.protocol.OFFlowStatsEntry;
 import org.projectfloodlight.openflow.protocol.OFFlowStatsReply;
+import org.projectfloodlight.openflow.protocol.OFTableStatsEntry;
+import org.projectfloodlight.openflow.protocol.OFTableStatsReply;
 import org.projectfloodlight.openflow.protocol.OFGroupDescStatsEntry;
 import org.projectfloodlight.openflow.protocol.OFGroupDescStatsReply;
 import org.projectfloodlight.openflow.protocol.OFGroupStatsEntry;
@@ -129,6 +131,9 @@
     protected Multimap<Dpid, OFFlowStatsEntry> fullFlowStats =
             ArrayListMultimap.create();
 
+    protected Multimap<Dpid, OFTableStatsEntry> fullTableStats =
+            ArrayListMultimap.create();
+
     protected Multimap<Dpid, OFGroupStatsEntry> fullGroupStats =
             ArrayListMultimap.create();
 
@@ -230,6 +235,7 @@
     @Override
     public void processPacket(Dpid dpid, OFMessage msg) {
         Collection<OFFlowStatsEntry> flowStats;
+        Collection<OFTableStatsEntry> tableStats;
         Collection<OFGroupStatsEntry> groupStats;
         Collection<OFGroupDescStatsEntry> groupDescStats;
         Collection<OFPortStatsEntry> portStats;
@@ -277,6 +283,15 @@
                         executorMsgs.submit(new OFMessageHandler(dpid, rep.build()));
                     }
                     break;
+                case TABLE:
+                    tableStats = publishTableStats(dpid, (OFTableStatsReply) reply);
+                    if (tableStats != null) {
+                        OFTableStatsReply.Builder rep =
+                                OFFactories.getFactory(msg.getVersion()).buildTableStatsReply();
+                        rep.setEntries(Lists.newLinkedList(tableStats));
+                        executorMsgs.submit(new OFMessageHandler(dpid, rep.build()));
+                    }
+                    break;
                 case GROUP:
                     groupStats = publishGroupStats(dpid, (OFGroupStatsReply) reply);
                     if (groupStats != null) {
@@ -395,6 +410,16 @@
         return null;
     }
 
+    private synchronized Collection<OFTableStatsEntry> publishTableStats(Dpid dpid,
+                                                                       OFTableStatsReply reply) {
+        //TODO: Get rid of synchronized
+        fullTableStats.putAll(dpid, reply.getEntries());
+        if (!reply.getFlags().contains(OFStatsReplyFlags.REPLY_MORE)) {
+            return fullTableStats.removeAll(dpid);
+        }
+        return null;
+    }
+
     private synchronized Collection<OFGroupStatsEntry> publishGroupStats(Dpid dpid,
                                                                       OFGroupStatsReply reply) {
         //TODO: Get rid of synchronized