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";
uses flow-capable-port;
}
+ grouping queues {
+ list queue {
+ key "queue-id";
+ uses queue-types:queue-packet;
+ }
+ }
+
grouping flow-capable-port {
uses common-port;
units "kbps";
description "Max port bit rate in kbps";
}
+
+ uses queues;
}
grouping port-mod {
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;
}
}
-
-
grouping queue-prop-max-rate {
leaf queue-id {
- type uint32;
+ type queue-id;
description "id for the specific queue.";
}
--- /dev/null
+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;
+ }
+}
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 {
leaf collision-count {
type uint64;
}
-
- container duration {
- leaf second {
- type yang:counter32;
- }
- leaf nanosecond {
- type yang:counter32;
- }
- }
+ uses duration;
}
grouping generic-statistics {
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";
}
}
+ 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
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;
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;
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(){
}
public Map<NodeConnectorId, NodeConnectorStatistics> getNodeConnectorStats() {
return nodeConnectorStats;
}
+
+ public Map<NodeConnectorId, Map<QueueId, GenericQueueStatistics>> getNodeConnectorAndQueuesStatsMap() {
+ return NodeConnectorAndQueuesStatsMap;
+ }
}
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;
private OpendaylightFlowTableStatisticsService flowTableStatsService;
+ private OpendaylightQueueStatisticsService queueStatsService;
+
private final MultipartMessageManager multipartMessageManager = new MultipartMessageManager();
private Thread statisticsRequesterThread;
flowTableStatsService = StatisticsManagerActivator.getProviderContext().
getRpcService(OpendaylightFlowTableStatisticsService.class);
+ queueStatsService = StatisticsManagerActivator.getProviderContext().
+ getRpcService(OpendaylightQueueStatisticsService.class);
+
statisticsRequesterThread = new Thread( new Runnable(){
@Override
sendAllPortStatisticsRequest(targetNodeRef);
sendAllFlowTablesStatisticsRequest(targetNodeRef);
+
+ sendAllQueueStatsFromAllNodeConnector (targetNodeRef);
}catch(Exception e){
spLogger.error("Exception occured while sending statistics requests : {}",e);
@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;
}
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;
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;
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;
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;
OpendaylightMeterStatisticsListener,
OpendaylightFlowStatisticsListener,
OpendaylightPortStatisticsListener,
- OpendaylightFlowTableStatisticsListener{
+ OpendaylightFlowTableStatisticsListener,
+ OpendaylightQueueStatisticsListener{
public final static Logger sucLogger = LoggerFactory.getLogger(StatisticsUpdateCommiter.class);
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();
}
}
+ @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
}
return true;
}
+
}