MD-SAL Statistics Manager: Added support for queue statistics collection 65/3765/1
authorAnil Vishnoi <avishnoi@in.ibm.com>
Mon, 16 Dec 2013 10:51:51 +0000 (16:21 +0530)
committerAnil Vishnoi <avishnoi@in.ibm.com>
Mon, 16 Dec 2013 20:59:07 +0000 (02:29 +0530)
Change-Id: I173d7722a8d1684e069c34733fdca0613c1d6530
Signed-off-by: Anil Vishnoi <avishnoi@in.ibm.com>
opendaylight/md-sal/model/model-flow-base/src/main/yang/port-types.yang
opendaylight/md-sal/model/model-flow-base/src/main/yang/queue-types.yang
opendaylight/md-sal/model/model-flow-statistics/src/main/yang/queue-statistics.yang [new file with mode: 0644]
opendaylight/md-sal/model/model-flow-statistics/src/main/yang/statistics-types.yang
opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/NodeStatistics.java
opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/StatisticsProvider.java
opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/StatisticsUpdateCommiter.java

index f0b7e97..bc05894 100644 (file)
@@ -4,6 +4,7 @@ module opendaylight-port-types {
 
     import ietf-inet-types {prefix inet; revision-date "2010-09-24";}
     import ietf-yang-types {prefix yang; revision-date "2010-09-24";}
+    import opendaylight-queue-types {prefix queue-types; revision-date "2013-09-25";}
     
     revision "2013-09-25" {
         description "Initial revision of Port Inventory model";
@@ -86,6 +87,13 @@ module opendaylight-port-types {
         uses flow-capable-port;
     }
     
+    grouping queues {
+       list queue {
+               key "queue-id";
+               uses queue-types:queue-packet;
+       }
+    }
+    
     grouping flow-capable-port {    
                 
         uses common-port;
@@ -126,6 +134,8 @@ module opendaylight-port-types {
             units "kbps";
             description "Max port bit rate in kbps";            
         }
+        
+        uses queues;
     }    
     
     grouping port-mod {
index 57a9237..06f832e 100644 (file)
@@ -9,6 +9,11 @@ module opendaylight-queue-types {
         description "Initial revision of Queue Inventory model";
     }
     
+    typedef queue-id {
+            type yang:counter32;
+            description "id for the specific queue.";  
+        }
+    
     typedef queue-properties {
         type enumeration {
             enum min_rate;
@@ -37,8 +42,6 @@ module opendaylight-queue-types {
         }
            
     }
-    
-    
       
     grouping queue-prop-max-rate       {
                
@@ -54,7 +57,7 @@ module opendaylight-queue-types {
                
                
         leaf queue-id {
-            type uint32;
+            type queue-id;
             description "id for the specific queue.";  
         }
         
diff --git a/opendaylight/md-sal/model/model-flow-statistics/src/main/yang/queue-statistics.yang b/opendaylight/md-sal/model/model-flow-statistics/src/main/yang/queue-statistics.yang
new file mode 100644 (file)
index 0000000..7665ef7
--- /dev/null
@@ -0,0 +1,101 @@
+module opendaylight-queue-statistics {
+    namespace "urn:opendaylight:queue:statistics";
+    prefix queuestat;
+
+       import flow-capable-transaction {prefix tr;}
+    import yang-ext {prefix ext; revision-date "2013-07-09";}
+    import ietf-yang-types {prefix yang; revision-date "2010-09-24";}   
+    import opendaylight-inventory {prefix inv;revision-date "2013-08-19";}
+    import flow-node-inventory {prefix flow-node;revision-date "2013-08-19";}
+    import opendaylight-queue-types {prefix queue-types;revision-date "2013-09-25";}
+    import opendaylight-statistics-types {prefix stat-types;revision-date "2013-09-25";}
+
+    contact
+        "Anilkumar Vishnoi
+        Email: avishnoi@in.ibm.com";
+
+    revision "2013-12-16" {
+        description "Initial revision of queue statistics model";
+    }
+    
+    //Augment queue statistics data to the flow-capable-node-connector
+       augment "/inv:nodes/inv:node/inv:node-connector/flow-node:queue" {
+        ext:augment-identifier "flow-capable-node-connector-queue-statistics-data";
+        uses flow-capable-node-connector-queue-statistics;
+    }
+       
+       grouping flow-capable-node-connector-queue-statistics {
+        container flow-capable-node-connector-queue-statistics {
+            //config "false";
+            uses stat-types:generic-queue-statistics;
+        }
+       }    
+       
+       //RPC calls to fetch queue statistics
+    grouping queue-id-and-statistics-map {
+       list queue-id-and-statistics-map {
+               key "queue-id node-connector-id";
+               leaf queue-id {
+                       type queue-types:queue-id;
+               }
+               leaf node-connector-id {
+                       type inv:node-connector-id;
+               }
+               
+            uses stat-types:generic-queue-statistics;
+       }
+    }
+    
+    rpc get-all-queues-statistics-from-all-ports {
+       description "Get statistics for all the queues attached to all the ports from the node";
+        input {
+            uses inv:node-context-ref;
+        }
+        output {
+            uses queue-id-and-statistics-map;
+            uses tr:transaction-aware;
+        }
+    }
+    
+    rpc get-all-queues-statistics-from-given-port {
+       description "Get statistics for all queues for given port of the node";
+       input {
+               uses inv:node-context-ref;
+               leaf node-connector-id {
+                       type inv:node-connector-id;
+               }
+       }
+       output {
+            uses queue-id-and-statistics-map;
+            uses tr:transaction-aware;
+       }
+    }
+    
+    rpc get-queue-statistics-from-given-port {
+       description "Get statistics for given queues from given port of the node";
+       input {
+               uses inv:node-context-ref;
+               leaf node-connector-id {
+                       type inv:node-connector-id;
+               }
+               leaf queue-id {
+                       type queue-types:queue-id;
+               }
+       }
+       output {
+            uses queue-id-and-statistics-map;
+            uses tr:transaction-aware;
+       }
+    }
+
+    //Notification for port statistics update
+
+       notification queue-statistics-update {
+        leaf moreReplies {
+            type boolean;
+        }
+        uses inv:node;
+               uses queue-id-and-statistics-map;
+        uses tr:transaction-aware;
+    }
+}
index 6d5bec1..7bde486 100644 (file)
@@ -7,7 +7,18 @@ module opendaylight-statistics-types {
     
     revision "2013-09-25" {
         description "Initial revision of flow service";
-    }    
+    }
+    
+    grouping duration {
+        container duration {
+            leaf second {
+                type yang:counter32;
+            }
+            leaf nanosecond {
+                type yang:counter32;
+            }
+        }
+    }
 
     grouping node-connector-statistics {
        container packets {
@@ -50,15 +61,7 @@ module opendaylight-statistics-types {
         leaf collision-count {
             type uint64;
         }
-        
-        container duration {
-            leaf second {
-                type yang:counter32;
-            }
-            leaf nanosecond {
-                type yang:counter32;
-            }
-        }
+        uses duration;
     }
     
     grouping generic-statistics {
@@ -70,16 +73,8 @@ module opendaylight-statistics-types {
         leaf byte-count {
             type yang:counter64;
         }
-
-        container duration {
-            leaf second {
-                type yang:counter64;
-            }
-            leaf nanosecond {
-                type yang:counter64;
-            }
-        }
-    }
+       uses duration;
+       }
     
     grouping generic-table-statistics {
        description "Generic grouping holding generic statistics related to switch table";
@@ -108,4 +103,20 @@ module opendaylight-statistics-types {
         }
     }
     
+    grouping generic-queue-statistics {
+       description "Generic statistics of switch port attached queues.";
+       leaf transmitted-bytes {
+                       type yang:counter64;
+       }
+       
+       leaf transmitted-packets {
+                       type yang:counter64;
+       }
+       
+       leaf transmission-errors {
+                       type yang:counter64;
+       }
+               uses duration;          
+    }
+    
 }
\ No newline at end of file
index a659a40..e84b437 100644 (file)
@@ -14,6 +14,7 @@ import java.util.concurrent.ConcurrentHashMap;
 
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.aggregate.flow.statistics.AggregateFlowStatistics;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.queue.rev130925.QueueId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.group.features.GroupFeatures;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.desc.stats.reply.GroupDescStats;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.statistics.reply.GroupStats;
@@ -22,6 +23,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef
 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.nodes.node.MeterFeatures;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.meter.config.stats.reply.MeterConfigStats;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.meter.statistics.reply.MeterStats;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.GenericQueueStatistics;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.GenericStatistics;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.GenericTableStatistics;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.NodeConnectorStatistics;
@@ -54,6 +56,9 @@ public class NodeStatistics {
     private final Map<Short,GenericTableStatistics> flowTableAndStatisticsMap = 
             new HashMap<Short,GenericTableStatistics>();
     
+    private final Map<NodeConnectorId,Map<QueueId,GenericQueueStatistics>> NodeConnectorAndQueuesStatsMap = 
+            new HashMap<NodeConnectorId,Map<QueueId,GenericQueueStatistics>>();
+    
     public NodeStatistics(){
         
     }
@@ -128,4 +133,8 @@ public class NodeStatistics {
     public Map<NodeConnectorId, NodeConnectorStatistics> getNodeConnectorStats() {
         return nodeConnectorStats;
     }
+
+    public Map<NodeConnectorId, Map<QueueId, GenericQueueStatistics>> getNodeConnectorAndQueuesStatsMap() {
+        return NodeConnectorAndQueuesStatsMap;
+    }
 }
index b7b4082..6dafa58 100644 (file)
@@ -46,6 +46,9 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.
 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.GetAllPortsStatisticsInputBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.GetAllPortsStatisticsOutput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.OpendaylightPortStatisticsService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.GetAllQueuesStatisticsFromAllPortsInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.GetAllQueuesStatisticsFromAllPortsOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.OpendaylightQueueStatisticsService;
 import org.opendaylight.yangtools.concepts.Registration;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.binding.NotificationListener;
@@ -71,6 +74,8 @@ public class StatisticsProvider implements AutoCloseable {
 
     private OpendaylightFlowTableStatisticsService flowTableStatsService;
 
+    private OpendaylightQueueStatisticsService queueStatsService;
+
     private final MultipartMessageManager multipartMessageManager = new MultipartMessageManager();
     
     private Thread statisticsRequesterThread;
@@ -129,6 +134,9 @@ public class StatisticsProvider implements AutoCloseable {
         flowTableStatsService = StatisticsManagerActivator.getProviderContext().
                 getRpcService(OpendaylightFlowTableStatisticsService.class);
         
+        queueStatsService = StatisticsManagerActivator.getProviderContext().
+                getRpcService(OpendaylightQueueStatisticsService.class);
+        
         statisticsRequesterThread = new Thread( new Runnable(){
 
             @Override
@@ -180,6 +188,8 @@ public class StatisticsProvider implements AutoCloseable {
                 sendAllPortStatisticsRequest(targetNodeRef);
                 
                 sendAllFlowTablesStatisticsRequest(targetNodeRef);
+                
+                sendAllQueueStatsFromAllNodeConnector (targetNodeRef);
 
             }catch(Exception e){
                 spLogger.error("Exception occured while sending statistics requests : {}",e);
@@ -315,9 +325,18 @@ public class StatisticsProvider implements AutoCloseable {
         @SuppressWarnings("unused")
         Future<RpcResult<GetAllMeterConfigStatisticsOutput>> response = 
                 meterStatsService.getAllMeterConfigStatistics(input.build());
-        
     }
     
+    private void sendAllQueueStatsFromAllNodeConnector(NodeRef targetNode) {
+        GetAllQueuesStatisticsFromAllPortsInputBuilder input = new GetAllQueuesStatisticsFromAllPortsInputBuilder();
+        
+        input.setNode(targetNode);
+        
+        @SuppressWarnings("unused")
+        Future<RpcResult<GetAllQueuesStatisticsFromAllPortsOutput>> response = 
+                queueStatsService.getAllQueuesStatisticsFromAllPorts(input.build());
+    }
+
     public ConcurrentMap<NodeId, NodeStatistics> getStatisticsCache() {
         return statisticsCache;
     }
index a4a7e1e..7169b39 100644 (file)
@@ -13,6 +13,7 @@ import java.util.concurrent.ConcurrentMap;
 
 import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableBuilder;
@@ -40,6 +41,10 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev13
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.OpendaylightFlowTableStatisticsListener;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.flow.table.and.statistics.map.FlowTableAndStatisticsMap;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.flow.table.statistics.FlowTableStatisticsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.queues.Queue;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.queues.QueueBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.queues.QueueKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.queue.rev130925.QueueId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GroupDescStatsUpdated;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GroupFeaturesUpdated;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GroupStatisticsUpdated;
@@ -75,6 +80,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.
 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.nodes.node.MeterConfigStatsBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.nodes.node.MeterFeaturesBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.nodes.node.MeterStatisticsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.GenericQueueStatistics;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.GenericStatistics;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.FlowCapableNodeConnectorStatisticsData;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.FlowCapableNodeConnectorStatisticsDataBuilder;
@@ -82,6 +88,12 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.O
 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.PortStatisticsUpdate;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.flow.capable.node.connector.statistics.FlowCapableNodeConnectorStatisticsBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.node.connector.statistics.and.port.number.map.NodeConnectorStatisticsAndPortNumberMap;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.FlowCapableNodeConnectorQueueStatisticsData;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.FlowCapableNodeConnectorQueueStatisticsDataBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.OpendaylightQueueStatisticsListener;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.QueueStatisticsUpdate;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.flow.capable.node.connector.queue.statistics.FlowCapableNodeConnectorQueueStatisticsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.queue.id.and.statistics.map.QueueIdAndStatisticsMap;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder;
 import org.slf4j.Logger;
@@ -91,7 +103,8 @@ public class StatisticsUpdateCommiter implements OpendaylightGroupStatisticsList
         OpendaylightMeterStatisticsListener, 
         OpendaylightFlowStatisticsListener,
         OpendaylightPortStatisticsListener,
-        OpendaylightFlowTableStatisticsListener{
+        OpendaylightFlowTableStatisticsListener,
+        OpendaylightQueueStatisticsListener{
     
     public final static Logger sucLogger = LoggerFactory.getLogger(StatisticsUpdateCommiter.class);
 
@@ -395,8 +408,8 @@ public class StatisticsUpdateCommiter implements OpendaylightGroupStatisticsList
 
             flowStatisticsData.setFlowStatistics(flowStatistics.build());
                 
-            sucLogger.info("Flow : {}",flowRule.toString());
-            sucLogger.info("Statistics to augment : {}",flowStatistics.build().toString());
+            sucLogger.debug("Flow : {}",flowRule.toString());
+            sucLogger.debug("Statistics to augment : {}",flowStatistics.build().toString());
 
             InstanceIdentifier<Table> tableRef = InstanceIdentifier.builder(Nodes.class).child(Node.class, key)
                     .augmentation(FlowCapableNode.class).child(Table.class, new TableKey(tableId)).toInstance();
@@ -573,6 +586,62 @@ public class StatisticsUpdateCommiter implements OpendaylightGroupStatisticsList
         }
     }
 
+    @Override
+    public void onQueueStatisticsUpdate(QueueStatisticsUpdate notification) {
+        NodeKey key = new NodeKey(notification.getId());
+        sucLogger.info("Received queue stats update : {}",notification.toString());
+        
+        //Add statistics to local cache
+        ConcurrentMap<NodeId, NodeStatistics> cache = this.statisticsManager.getStatisticsCache();
+        if(!cache.containsKey(notification.getId())){
+            cache.put(notification.getId(), new NodeStatistics());
+        }
+        
+        List<QueueIdAndStatisticsMap> queuesStats = notification.getQueueIdAndStatisticsMap();
+        for(QueueIdAndStatisticsMap swQueueStats : queuesStats){
+            
+            if(!cache.get(notification.getId()).getNodeConnectorAndQueuesStatsMap().containsKey(swQueueStats.getNodeConnectorId())){
+                cache.get(notification.getId()).getNodeConnectorAndQueuesStatsMap().put(swQueueStats.getNodeConnectorId(), new HashMap<QueueId,GenericQueueStatistics>());
+            }
+            
+            FlowCapableNodeConnectorQueueStatisticsDataBuilder queueStatisticsDataBuilder = new FlowCapableNodeConnectorQueueStatisticsDataBuilder();
+            
+            FlowCapableNodeConnectorQueueStatisticsBuilder queueStatisticsBuilder = new FlowCapableNodeConnectorQueueStatisticsBuilder();
+            
+            queueStatisticsBuilder.fieldsFrom(swQueueStats);
+            
+            queueStatisticsDataBuilder.setFlowCapableNodeConnectorQueueStatistics(queueStatisticsBuilder.build());
+            
+            cache.get(notification.getId()).getNodeConnectorAndQueuesStatsMap()
+                                            .get(swQueueStats.getNodeConnectorId())
+                                            .put(swQueueStats.getQueueId(), queueStatisticsBuilder.build());
+            
+            
+            DataModificationTransaction it = this.statisticsManager.startChange();
+
+            InstanceIdentifier<Queue> queueRef 
+                    = InstanceIdentifier.builder(Nodes.class)
+                                        .child(Node.class, key)
+                                        .child(NodeConnector.class, new NodeConnectorKey(swQueueStats.getNodeConnectorId()))
+                                        .augmentation(FlowCapableNodeConnector.class)
+                                        .child(Queue.class, new QueueKey(swQueueStats.getQueueId())).toInstance();
+            
+            QueueBuilder queueBuilder = new QueueBuilder();
+            queueBuilder.addAugmentation(FlowCapableNodeConnectorQueueStatisticsData.class, queueStatisticsDataBuilder.build());
+            queueBuilder.setKey(new QueueKey(swQueueStats.getQueueId()));
+
+            sucLogger.info("Augmenting queue statistics {} of queue {} to port {}"
+                                        ,queueStatisticsDataBuilder.build().toString(),
+                                        swQueueStats.getQueueId(),
+                                        swQueueStats.getNodeConnectorId());
+            
+            it.putOperationalData(queueRef, queueBuilder.build());
+            it.commit();
+            
+        }
+        
+    }
+
     @Override
     public void onFlowStatisticsUpdated(FlowStatisticsUpdated notification) {
         // TODO Auto-generated method stub
@@ -669,4 +738,5 @@ public class StatisticsUpdateCommiter implements OpendaylightGroupStatisticsList
         }
         return true;
     }
+
 }