From 986f7091e577ac69cbc180a9f981760b78dd18e6 Mon Sep 17 00:00:00 2001 From: Anil Vishnoi Date: Mon, 16 Dec 2013 16:21:51 +0530 Subject: [PATCH] MD-SAL Statistics Manager: Added support for queue statistics collection Change-Id: I173d7722a8d1684e069c34733fdca0613c1d6530 Signed-off-by: Anil Vishnoi --- .../src/main/yang/port-types.yang | 10 ++ .../src/main/yang/queue-types.yang | 9 +- .../src/main/yang/queue-statistics.yang | 101 ++++++++++++++++++ .../src/main/yang/statistics-types.yang | 51 +++++---- .../md/statistics/manager/NodeStatistics.java | 9 ++ .../manager/StatisticsProvider.java | 21 +++- .../manager/StatisticsUpdateCommiter.java | 76 ++++++++++++- 7 files changed, 250 insertions(+), 27 deletions(-) create mode 100644 opendaylight/md-sal/model/model-flow-statistics/src/main/yang/queue-statistics.yang diff --git a/opendaylight/md-sal/model/model-flow-base/src/main/yang/port-types.yang b/opendaylight/md-sal/model/model-flow-base/src/main/yang/port-types.yang index f0b7e97a15..bc05894da8 100644 --- a/opendaylight/md-sal/model/model-flow-base/src/main/yang/port-types.yang +++ b/opendaylight/md-sal/model/model-flow-base/src/main/yang/port-types.yang @@ -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 { diff --git a/opendaylight/md-sal/model/model-flow-base/src/main/yang/queue-types.yang b/opendaylight/md-sal/model/model-flow-base/src/main/yang/queue-types.yang index 57a92378c0..06f832e114 100644 --- a/opendaylight/md-sal/model/model-flow-base/src/main/yang/queue-types.yang +++ b/opendaylight/md-sal/model/model-flow-base/src/main/yang/queue-types.yang @@ -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 index 0000000000..7665ef75c7 --- /dev/null +++ b/opendaylight/md-sal/model/model-flow-statistics/src/main/yang/queue-statistics.yang @@ -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; + } +} diff --git a/opendaylight/md-sal/model/model-flow-statistics/src/main/yang/statistics-types.yang b/opendaylight/md-sal/model/model-flow-statistics/src/main/yang/statistics-types.yang index 6d5bec1280..7bde486e91 100644 --- a/opendaylight/md-sal/model/model-flow-statistics/src/main/yang/statistics-types.yang +++ b/opendaylight/md-sal/model/model-flow-statistics/src/main/yang/statistics-types.yang @@ -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 diff --git a/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/NodeStatistics.java b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/NodeStatistics.java index a659a40886..e84b437b53 100644 --- a/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/NodeStatistics.java +++ b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/NodeStatistics.java @@ -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 flowTableAndStatisticsMap = new HashMap(); + private final Map> NodeConnectorAndQueuesStatsMap = + new HashMap>(); + public NodeStatistics(){ } @@ -128,4 +133,8 @@ public class NodeStatistics { public Map getNodeConnectorStats() { return nodeConnectorStats; } + + public Map> getNodeConnectorAndQueuesStatsMap() { + return NodeConnectorAndQueuesStatsMap; + } } diff --git a/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/StatisticsProvider.java b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/StatisticsProvider.java index b7b4082118..6dafa58c7e 100644 --- a/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/StatisticsProvider.java +++ b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/StatisticsProvider.java @@ -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> response = meterStatsService.getAllMeterConfigStatistics(input.build()); - } + private void sendAllQueueStatsFromAllNodeConnector(NodeRef targetNode) { + GetAllQueuesStatisticsFromAllPortsInputBuilder input = new GetAllQueuesStatisticsFromAllPortsInputBuilder(); + + input.setNode(targetNode); + + @SuppressWarnings("unused") + Future> response = + queueStatsService.getAllQueuesStatisticsFromAllPorts(input.build()); + } + public ConcurrentMap getStatisticsCache() { return statisticsCache; } diff --git a/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/StatisticsUpdateCommiter.java b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/StatisticsUpdateCommiter.java index a4a7e1e661..7169b39b77 100644 --- a/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/StatisticsUpdateCommiter.java +++ b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/StatisticsUpdateCommiter.java @@ -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 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 cache = this.statisticsManager.getStatisticsCache(); + if(!cache.containsKey(notification.getId())){ + cache.put(notification.getId(), new NodeStatistics()); + } + + List 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()); + } + + 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 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; } + } -- 2.36.6