Prepare for transitioning NodeStatisticsAger 73/5273/3
authorRobert Varga <rovarga@cisco.com>
Wed, 12 Feb 2014 00:35:30 +0000 (01:35 +0100)
committerRobert Varga <rovarga@cisco.com>
Wed, 12 Feb 2014 01:58:32 +0000 (02:58 +0100)
NodeStatisticsAger is currently the object which tracks per-node state,
synchronizing our view of what comes from the network vs. what is timed
out. Previous patches have already added partial ordering, this patch
moves the actual modifications in NodeStatisticsAger. This gives us
predictable behavior while keeping us per-switch scalable.

Change-Id: I7a11cf5eb885b46972ecf7a362a8d80a97923a0a
Signed-off-by: Robert Varga <rovarga@cisco.com>
opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/NodeStatisticsAger.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 2460e1ea9a9f56e6f48a4b3773b0c6577ad890aa..8e68515c325bc1acba4b9ca64a10984f4e2619ce 100644 (file)
@@ -18,31 +18,73 @@ import org.opendaylight.controller.sal.binding.api.data.DataModificationTransact
 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.meters.Meter;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.MeterBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.MeterKey;
 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.inventory.rev130819.tables.TableKey;
 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.AggregateFlowStatisticsData;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.AggregateFlowStatisticsDataBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowStatisticsData;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.aggregate.flow.statistics.AggregateFlowStatisticsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.FlowTableStatisticsData;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.FlowTableStatisticsDataBuilder;
+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.FlowTableStatistics;
+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.NodeGroupDescStats;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.NodeGroupDescStatsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.NodeGroupFeatures;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.NodeGroupFeaturesBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.NodeGroupStatistics;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.NodeGroupStatisticsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.group.desc.GroupDescBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.group.features.GroupFeaturesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.group.statistics.GroupStatisticsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.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.group.types.rev131018.groups.Group;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.GroupBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.GroupKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.NodeMeterConfigStats;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.NodeMeterConfigStatsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.NodeMeterFeatures;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.NodeMeterFeaturesBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.NodeMeterStatistics;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.NodeMeterStatisticsBuilder;
+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.meter.MeterConfigStatsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.nodes.node.meter.MeterStatisticsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.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.AggregateFlowStatistics;
+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.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.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;
+import org.slf4j.LoggerFactory;
 
 import com.google.common.base.Preconditions;
 
@@ -53,18 +95,21 @@ import com.google.common.base.Preconditions;
  *
  */
 public class NodeStatisticsAger {
+    private static final Logger logger = LoggerFactory.getLogger(NodeStatisticsAger.class);
     private static final int NUMBER_OF_WAIT_CYCLES = 2;
 
     private final Map<GroupDescStats,Long> groupDescStatsUpdate = new HashMap<>();
     private final Map<MeterConfigStats,Long> meterConfigStatsUpdate = new HashMap<>();
     private final Map<FlowEntry,Long> flowStatsUpdate = new HashMap<>();
     private final Map<QueueEntry,Long> queuesStatsUpdate = new HashMap<>();
+    private final InstanceIdentifier<Node> targetNodeIdentifier;
     private final StatisticsProvider statisticsProvider;
     private final NodeKey targetNodeKey;
 
     public NodeStatisticsAger(StatisticsProvider statisticsProvider, NodeKey nodeKey){
         this.statisticsProvider = Preconditions.checkNotNull(statisticsProvider);
         this.targetNodeKey = Preconditions.checkNotNull(nodeKey);
+        this.targetNodeIdentifier = InstanceIdentifier.builder(Nodes.class).child(Node.class, targetNodeKey).build();
     }
 
     public class FlowEntry {
@@ -123,7 +168,7 @@ public class NodeStatisticsAger {
         }
     }
 
-    public class QueueEntry{
+    private static final class QueueEntry{
         private final NodeConnectorId nodeConnectorId;
         private final QueueId queueId;
         public QueueEntry(NodeConnectorId ncId, QueueId queueId){
@@ -140,7 +185,6 @@ public class NodeStatisticsAger {
         public int hashCode() {
             final int prime = 31;
             int result = 1;
-            result = prime * result + getOuterType().hashCode();
             result = prime * result + ((nodeConnectorId == null) ? 0 : nodeConnectorId.hashCode());
             result = prime * result + ((queueId == null) ? 0 : queueId.hashCode());
             return result;
@@ -157,9 +201,6 @@ public class NodeStatisticsAger {
                 return false;
             }
             QueueEntry other = (QueueEntry) obj;
-            if (!getOuterType().equals(other.getOuterType())) {
-                return false;
-            }
             if (nodeConnectorId == null) {
                 if (other.nodeConnectorId != null) {
                     return false;
@@ -176,9 +217,6 @@ public class NodeStatisticsAger {
             }
             return true;
         }
-        private NodeStatisticsAger getOuterType() {
-            return NodeStatisticsAger.this;
-        }
     }
 
     public NodeKey getTargetNodeKey() {
@@ -186,23 +224,299 @@ public class NodeStatisticsAger {
     }
 
     public synchronized void updateGroupDescStats(List<GroupDescStats> list){
-        Long expiryTime = getExpiryTime();
-        for(GroupDescStats groupDescStats : list)
+        final Long expiryTime = getExpiryTime();
+        final DataModificationTransaction trans = statisticsProvider.startChange();
+
+        for (GroupDescStats groupDescStats : list) {
+            GroupBuilder groupBuilder = new GroupBuilder();
+            GroupKey groupKey = new GroupKey(groupDescStats.getGroupId());
+            groupBuilder.setKey(groupKey);
+
+            InstanceIdentifier<Group> groupRef = InstanceIdentifier.builder(Nodes.class).child(Node.class, targetNodeKey)
+                                                                                        .augmentation(FlowCapableNode.class)
+                                                                                        .child(Group.class,groupKey).toInstance();
+
+            NodeGroupDescStatsBuilder groupDesc= new NodeGroupDescStatsBuilder();
+            GroupDescBuilder stats = new GroupDescBuilder();
+            stats.fieldsFrom(groupDescStats);
+            groupDesc.setGroupDesc(stats.build());
+
+            //Update augmented data
+            groupBuilder.addAugmentation(NodeGroupDescStats.class, groupDesc.build());
+
+            trans.putOperationalData(groupRef, groupBuilder.build());
             this.groupDescStatsUpdate.put(groupDescStats, expiryTime);
+        }
+
+        trans.commit();
     }
 
-    public synchronized void updateMeterConfigStats(List<MeterConfigStats> list){
-        Long expiryTime = getExpiryTime();
-        for(MeterConfigStats meterConfigStats: list)
+
+    public synchronized void updateGroupStats(List<GroupStats> list) {
+        final DataModificationTransaction trans = statisticsProvider.startChange();
+
+        for(GroupStats groupStats : list) {
+            GroupBuilder groupBuilder = new GroupBuilder();
+            GroupKey groupKey = new GroupKey(groupStats.getGroupId());
+            groupBuilder.setKey(groupKey);
+
+            InstanceIdentifier<Group> groupRef = InstanceIdentifier.builder(Nodes.class).child(Node.class, targetNodeKey)
+                                                                                        .augmentation(FlowCapableNode.class)
+                                                                                        .child(Group.class,groupKey).toInstance();
+
+            NodeGroupStatisticsBuilder groupStatisticsBuilder= new NodeGroupStatisticsBuilder();
+            GroupStatisticsBuilder stats = new GroupStatisticsBuilder();
+            stats.fieldsFrom(groupStats);
+            groupStatisticsBuilder.setGroupStatistics(stats.build());
+
+            //Update augmented data
+            groupBuilder.addAugmentation(NodeGroupStatistics.class, groupStatisticsBuilder.build());
+            trans.putOperationalData(groupRef, groupBuilder.build());
+
+            // FIXME: should we be tracking this data?
+        }
+
+        trans.commit();
+    }
+
+    public synchronized void updateMeterConfigStats(List<MeterConfigStats> list) {
+        final Long expiryTime = getExpiryTime();
+        final DataModificationTransaction trans = statisticsProvider.startChange();
+
+        for(MeterConfigStats meterConfigStats : list) {
+            MeterBuilder meterBuilder = new MeterBuilder();
+            MeterKey meterKey = new MeterKey(meterConfigStats.getMeterId());
+            meterBuilder.setKey(meterKey);
+
+            InstanceIdentifier<Meter> meterRef = InstanceIdentifier.builder(Nodes.class).child(Node.class, targetNodeKey)
+                                                                                        .augmentation(FlowCapableNode.class)
+                                                                                        .child(Meter.class,meterKey).toInstance();
+
+            NodeMeterConfigStatsBuilder meterConfig= new NodeMeterConfigStatsBuilder();
+            MeterConfigStatsBuilder stats = new MeterConfigStatsBuilder();
+            stats.fieldsFrom(meterConfigStats);
+            meterConfig.setMeterConfigStats(stats.build());
+
+            //Update augmented data
+            meterBuilder.addAugmentation(NodeMeterConfigStats.class, meterConfig.build());
+
+            trans.putOperationalData(meterRef, meterBuilder.build());
             this.meterConfigStatsUpdate.put(meterConfigStats, expiryTime);
+        }
+
+        trans.commit();
+    }
+
+
+    public synchronized void updateMeterStats(List<MeterStats> list) {
+        final DataModificationTransaction trans = statisticsProvider.startChange();
+
+        for(MeterStats meterStats : list) {
+            MeterBuilder meterBuilder = new MeterBuilder();
+            MeterKey meterKey = new MeterKey(meterStats.getMeterId());
+            meterBuilder.setKey(meterKey);
+
+            InstanceIdentifier<Meter> meterRef = InstanceIdentifier.builder(Nodes.class).child(Node.class, targetNodeKey)
+                                                                                        .augmentation(FlowCapableNode.class)
+                                                                                        .child(Meter.class,meterKey).toInstance();
+
+            NodeMeterStatisticsBuilder meterStatsBuilder= new NodeMeterStatisticsBuilder();
+            MeterStatisticsBuilder stats = new MeterStatisticsBuilder();
+            stats.fieldsFrom(meterStats);
+            meterStatsBuilder.setMeterStatistics(stats.build());
+
+            //Update augmented data
+            meterBuilder.addAugmentation(NodeMeterStatistics.class, meterStatsBuilder.build());
+            trans.putOperationalData(meterRef, meterBuilder.build());
+
+            // FIXME: should we be tracking this data?
+        }
+
+        trans.commit();
+    }
+
+    public synchronized void updateQueueStats(List<QueueIdAndStatisticsMap> list) {
+        final Long expiryTime = getExpiryTime();
+        final DataModificationTransaction trans = statisticsProvider.startChange();
+
+        for (QueueIdAndStatisticsMap swQueueStats : list) {
+
+            QueueEntry queueEntry = new QueueEntry(swQueueStats.getNodeConnectorId(),swQueueStats.getQueueId());
+
+            FlowCapableNodeConnectorQueueStatisticsDataBuilder queueStatisticsDataBuilder = new FlowCapableNodeConnectorQueueStatisticsDataBuilder();
+
+            FlowCapableNodeConnectorQueueStatisticsBuilder queueStatisticsBuilder = new FlowCapableNodeConnectorQueueStatisticsBuilder();
+
+            queueStatisticsBuilder.fieldsFrom(swQueueStats);
+
+            queueStatisticsDataBuilder.setFlowCapableNodeConnectorQueueStatistics(queueStatisticsBuilder.build());
+
+            InstanceIdentifier<Queue> queueRef
+                    = InstanceIdentifier.builder(Nodes.class)
+                                        .child(Node.class, targetNodeKey)
+                                        .child(NodeConnector.class, new NodeConnectorKey(swQueueStats.getNodeConnectorId()))
+                                        .augmentation(FlowCapableNodeConnector.class)
+                                        .child(Queue.class, new QueueKey(swQueueStats.getQueueId())).toInstance();
+
+            QueueBuilder queueBuilder = new QueueBuilder();
+            FlowCapableNodeConnectorQueueStatisticsData qsd = queueStatisticsDataBuilder.build();
+            queueBuilder.addAugmentation(FlowCapableNodeConnectorQueueStatisticsData.class, qsd);
+            queueBuilder.setKey(new QueueKey(swQueueStats.getQueueId()));
+
+            logger.debug("Augmenting queue statistics {} of queue {} to port {}",
+                                        qsd,
+                                        swQueueStats.getQueueId(),
+                                        swQueueStats.getNodeConnectorId());
+
+            trans.putOperationalData(queueRef, queueBuilder.build());
+            this.queuesStatsUpdate.put(queueEntry, expiryTime);
+        }
+
+        trans.commit();
+    }
+
+    public synchronized void updateFlowTableStats(List<FlowTableAndStatisticsMap> list) {
+        final DataModificationTransaction trans = statisticsProvider.startChange();
+
+        for (FlowTableAndStatisticsMap ftStats : list) {
+
+            InstanceIdentifier<Table> tableRef = InstanceIdentifier.builder(Nodes.class).child(Node.class, targetNodeKey)
+                    .augmentation(FlowCapableNode.class).child(Table.class, new TableKey(ftStats.getTableId().getValue())).toInstance();
+
+            FlowTableStatisticsDataBuilder statisticsDataBuilder = new FlowTableStatisticsDataBuilder();
+
+            FlowTableStatisticsBuilder statisticsBuilder = new FlowTableStatisticsBuilder();
+            statisticsBuilder.setActiveFlows(ftStats.getActiveFlows());
+            statisticsBuilder.setPacketsLookedUp(ftStats.getPacketsLookedUp());
+            statisticsBuilder.setPacketsMatched(ftStats.getPacketsMatched());
+
+            final FlowTableStatistics stats = statisticsBuilder.build();
+            statisticsDataBuilder.setFlowTableStatistics(stats);
+
+            logger.debug("Augment flow table statistics: {} for table {} on Node {}",
+                    stats,ftStats.getTableId(), targetNodeKey);
+
+            TableBuilder tableBuilder = new TableBuilder();
+            tableBuilder.setKey(new TableKey(ftStats.getTableId().getValue()));
+            tableBuilder.addAugmentation(FlowTableStatisticsData.class, statisticsDataBuilder.build());
+            trans.putOperationalData(tableRef, tableBuilder.build());
+
+            // FIXME: should we be tracking this data?
+        }
+
+        trans.commit();
+    }
+
+    public synchronized void updateNodeConnectorStats(List<NodeConnectorStatisticsAndPortNumberMap> list) {
+        final DataModificationTransaction trans = statisticsProvider.startChange();
+
+        for(NodeConnectorStatisticsAndPortNumberMap portStats : list) {
+
+            FlowCapableNodeConnectorStatisticsBuilder statisticsBuilder
+                                            = new FlowCapableNodeConnectorStatisticsBuilder();
+            statisticsBuilder.setBytes(portStats.getBytes());
+            statisticsBuilder.setCollisionCount(portStats.getCollisionCount());
+            statisticsBuilder.setDuration(portStats.getDuration());
+            statisticsBuilder.setPackets(portStats.getPackets());
+            statisticsBuilder.setReceiveCrcError(portStats.getReceiveCrcError());
+            statisticsBuilder.setReceiveDrops(portStats.getReceiveDrops());
+            statisticsBuilder.setReceiveErrors(portStats.getReceiveErrors());
+            statisticsBuilder.setReceiveFrameError(portStats.getReceiveFrameError());
+            statisticsBuilder.setReceiveOverRunError(portStats.getReceiveOverRunError());
+            statisticsBuilder.setTransmitDrops(portStats.getTransmitDrops());
+            statisticsBuilder.setTransmitErrors(portStats.getTransmitErrors());
+
+            //Augment data to the node-connector
+            FlowCapableNodeConnectorStatisticsDataBuilder statisticsDataBuilder =
+                    new FlowCapableNodeConnectorStatisticsDataBuilder();
+
+            statisticsDataBuilder.setFlowCapableNodeConnectorStatistics(statisticsBuilder.build());
+
+            InstanceIdentifier<NodeConnector> nodeConnectorRef = InstanceIdentifier.builder(Nodes.class)
+                    .child(Node.class, targetNodeKey)
+                    .child(NodeConnector.class, new NodeConnectorKey(portStats.getNodeConnectorId())).toInstance();
+
+            // FIXME: can we bypass this read?
+            NodeConnector nodeConnector = (NodeConnector)trans.readOperationalData(nodeConnectorRef);
+            if(nodeConnector != null){
+                final FlowCapableNodeConnectorStatisticsData stats = statisticsDataBuilder.build();
+                logger.debug("Augmenting port statistics {} to port {}",stats,nodeConnectorRef.toString());
+                NodeConnectorBuilder nodeConnectorBuilder = new NodeConnectorBuilder();
+                nodeConnectorBuilder.addAugmentation(FlowCapableNodeConnectorStatisticsData.class, stats);
+                trans.putOperationalData(nodeConnectorRef, nodeConnectorBuilder.build());
+            }
+
+            // FIXME: should we be tracking this data?
+        }
+
+        trans.commit();
+    }
+
+    public synchronized void updateAggregateFlowStats(Short tableId, AggregateFlowStatistics flowStats) {
+        if (tableId != null) {
+            final DataModificationTransaction trans = statisticsProvider.startChange();
+
+
+            InstanceIdentifier<Table> tableRef = InstanceIdentifier.builder(Nodes.class).child(Node.class, targetNodeKey)
+                    .augmentation(FlowCapableNode.class).child(Table.class, new TableKey(tableId)).toInstance();
+
+            AggregateFlowStatisticsDataBuilder aggregateFlowStatisticsDataBuilder = new AggregateFlowStatisticsDataBuilder();
+            AggregateFlowStatisticsBuilder aggregateFlowStatisticsBuilder = new AggregateFlowStatisticsBuilder(flowStats);
+
+            aggregateFlowStatisticsDataBuilder.setAggregateFlowStatistics(aggregateFlowStatisticsBuilder.build());
+
+            logger.debug("Augment aggregate statistics: {} for table {} on Node {}",
+                    aggregateFlowStatisticsBuilder.build().toString(),tableId,targetNodeKey);
+
+            TableBuilder tableBuilder = new TableBuilder();
+            tableBuilder.setKey(new TableKey(tableId));
+            tableBuilder.addAugmentation(AggregateFlowStatisticsData.class, aggregateFlowStatisticsDataBuilder.build());
+            trans.putOperationalData(tableRef, tableBuilder.build());
+
+            // FIXME: should we be tracking this data?
+            trans.commit();
+        }
+    }
+
+    public synchronized void updateGroupFeatures(GroupFeatures notification) {
+        final DataModificationTransaction trans = statisticsProvider.startChange();
+
+        final NodeBuilder nodeData = new NodeBuilder();
+        nodeData.setKey(targetNodeKey);
+
+        NodeGroupFeaturesBuilder nodeGroupFeatures = new NodeGroupFeaturesBuilder();
+        GroupFeaturesBuilder groupFeatures = new GroupFeaturesBuilder(notification);
+        nodeGroupFeatures.setGroupFeatures(groupFeatures.build());
+
+        //Update augmented data
+        nodeData.addAugmentation(NodeGroupFeatures.class, nodeGroupFeatures.build());
+        trans.putOperationalData(targetNodeIdentifier, nodeData.build());
+
+        // FIXME: should we be tracking this data?
+        trans.commit();
+    }
+
+    public synchronized void updateMeterFeatures(MeterFeatures features) {
+        final DataModificationTransaction trans = statisticsProvider.startChange();
+
+        final NodeBuilder nodeData = new NodeBuilder();
+        nodeData.setKey(targetNodeKey);
+
+        NodeMeterFeaturesBuilder nodeMeterFeatures = new NodeMeterFeaturesBuilder();
+        MeterFeaturesBuilder meterFeature = new MeterFeaturesBuilder(features);
+        nodeMeterFeatures.setMeterFeatures(meterFeature.build());
+
+        //Update augmented data
+        nodeData.addAugmentation(NodeMeterFeatures.class, nodeMeterFeatures.build());
+        trans.putOperationalData(targetNodeIdentifier, nodeData.build());
+
+        // FIXME: should we be tracking this data?
+        trans.commit();
     }
 
     public synchronized void updateFlowStats(FlowEntry flowEntry){
         this.flowStatsUpdate.put(flowEntry, getExpiryTime());
     }
-    public synchronized void updateQueueStats(QueueEntry queueEntry){
-        this.queuesStatsUpdate.put(queueEntry, getExpiryTime());
-    }
 
     private static Long getExpiryTime(){
         final long now = System.nanoTime();
@@ -298,4 +612,5 @@ public class NodeStatisticsAger {
         InstanceIdentifier<?> nodeGroupStatisticsAugmentation = groupRef.augmentation(NodeGroupStatistics.class).toInstance();
         trans.removeOperationalData(nodeGroupStatisticsAugmentation);
     }
+
 }
index 353c3336cfdb490070c1e02e222dac8fef3f5790..1269c1c6d8287fda41ec1fce515895e32fa50abd 100644 (file)
@@ -448,7 +448,15 @@ public class StatisticsProvider implements AutoCloseable {
 
     }
 
-    public final NodeStatisticsAger getStatisticsAger(final NodeId nodeId) {
+    /**
+     * Get the handler for a particular node.
+     *
+     * @param nodeId source node
+     * @return Node statistics handler for that node. Null if the statistics should
+     *         not handled.
+     */
+    public final NodeStatisticsAger getStatisticsHandler(final NodeId nodeId) {
+        Preconditions.checkNotNull(nodeId);
         NodeStatisticsAger ager = statisticsCache.get(nodeId);
         if (ager == null) {
             ager = new NodeStatisticsAger(this, new NodeKey(nodeId));
index 2fa380db3c5a651a47ba0d69386c0499eb68db29..6ba46e3827dbe2f7ff919a3c8eed2d4fd61affe9 100644 (file)
@@ -10,103 +10,47 @@ package org.opendaylight.controller.md.statistics.manager;
 import java.net.Inet4Address;
 import java.net.InetAddress;
 import java.net.UnknownHostException;
-import java.util.List;
 
 import org.opendaylight.controller.md.statistics.manager.NodeStatisticsAger.FlowEntry;
-import org.opendaylight.controller.md.statistics.manager.NodeStatisticsAger.QueueEntry;
 import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;
 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.meters.Meter;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.MeterBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.MeterKey;
 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.inventory.rev130819.tables.TableKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.AggregateFlowStatisticsData;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.AggregateFlowStatisticsDataBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.AggregateFlowStatisticsUpdate;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowStatisticsData;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowStatisticsDataBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowsStatisticsUpdate;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.OpendaylightFlowStatisticsListener;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.aggregate.flow.statistics.AggregateFlowStatisticsBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.and.statistics.map.list.FlowAndStatisticsMapList;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.and.statistics.map.list.FlowAndStatisticsMapListBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.statistics.FlowStatisticsBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.FlowTableStatisticsData;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.FlowTableStatisticsDataBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.FlowTableStatisticsUpdate;
 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.rev131026.flow.Match;
 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.group.statistics.rev131111.NodeGroupDescStats;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.NodeGroupDescStatsBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.NodeGroupFeatures;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.NodeGroupFeaturesBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.NodeGroupStatistics;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.NodeGroupStatisticsBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.OpendaylightGroupStatisticsListener;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.group.desc.GroupDescBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.group.features.GroupFeaturesBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.group.statistics.GroupStatisticsBuilder;
-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.group.types.rev131018.groups.Group;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.GroupBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.GroupKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.MeterConfigStatsUpdated;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.MeterFeaturesUpdated;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.MeterStatisticsUpdated;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.NodeMeterConfigStats;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.NodeMeterConfigStatsBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.NodeMeterFeatures;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.NodeMeterFeaturesBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.NodeMeterStatistics;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.NodeMeterStatisticsBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.OpendaylightMeterStatisticsListener;
-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.meter.MeterConfigStatsBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.nodes.node.meter.MeterStatisticsBuilder;
-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.match.types.rev131026.match.Layer3Match;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4Match;
 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.NodeConnectorStatisticsUpdate;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.OpendaylightPortStatisticsListener;
-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;
 import org.slf4j.LoggerFactory;
 
@@ -137,214 +81,74 @@ public class StatisticsUpdateCommiter implements OpendaylightGroupStatisticsList
      * @param manager
      */
     public StatisticsUpdateCommiter(final StatisticsProvider manager){
-
         this.statisticsManager = manager;
         this.messageManager = this.statisticsManager.getMultipartMessageManager();
     }
 
-    public StatisticsProvider getStatisticsManager(){
-        return statisticsManager;
-    }
-
     @Override
     public void onMeterConfigStatsUpdated(final MeterConfigStatsUpdated notification) {
         //Check if response is for the request statistics-manager sent.
         if(!messageManager.isRequestTxIdExist(notification.getId(),notification.getTransactionId(),notification.isMoreReplies()))
             return;
 
-        final NodeKey key = new NodeKey(notification.getId());
-
         //Add statistics to local cache
-        this.statisticsManager.getStatisticsAger(notification.getId()).updateMeterConfigStats(notification.getMeterConfigStats());
-
-        //Publish data to configuration data store
-        List<MeterConfigStats> meterConfigStatsList = notification.getMeterConfigStats();
-        DataModificationTransaction it = this.statisticsManager.startChange();
-
-        for(MeterConfigStats meterConfigStats : meterConfigStatsList){
-            MeterBuilder meterBuilder = new MeterBuilder();
-            MeterKey meterKey = new MeterKey(meterConfigStats.getMeterId());
-            meterBuilder.setKey(meterKey);
-
-            InstanceIdentifier<Meter> meterRef = InstanceIdentifier.builder(Nodes.class).child(Node.class,key)
-                                                                                        .augmentation(FlowCapableNode.class)
-                                                                                        .child(Meter.class,meterKey).toInstance();
-
-            NodeMeterConfigStatsBuilder meterConfig= new NodeMeterConfigStatsBuilder();
-            MeterConfigStatsBuilder stats = new MeterConfigStatsBuilder();
-            stats.fieldsFrom(meterConfigStats);
-            meterConfig.setMeterConfigStats(stats.build());
-
-            //Update augmented data
-            meterBuilder.addAugmentation(NodeMeterConfigStats.class, meterConfig.build());
-            it.putOperationalData(meterRef, meterBuilder.build());
+        final NodeStatisticsAger sna = this.statisticsManager.getStatisticsHandler(notification.getId());
+        if (sna != null) {
+            sna.updateMeterConfigStats(notification.getMeterConfigStats());
         }
-        it.commit();
     }
 
     @Override
     public void onMeterStatisticsUpdated(MeterStatisticsUpdated notification) {
-
         //Check if response is for the request statistics-manager sent.
         if(!messageManager.isRequestTxIdExist(notification.getId(),notification.getTransactionId(),notification.isMoreReplies()))
             return;
 
-        final NodeKey key = new NodeKey(notification.getId());
-
-        //Publish data to configuration data store
-        List<MeterStats> meterStatsList = notification.getMeterStats();
-        DataModificationTransaction it = this.statisticsManager.startChange();
-
-        for(MeterStats meterStats : meterStatsList){
-
-            MeterBuilder meterBuilder = new MeterBuilder();
-            MeterKey meterKey = new MeterKey(meterStats.getMeterId());
-            meterBuilder.setKey(meterKey);
-
-            InstanceIdentifier<Meter> meterRef = InstanceIdentifier.builder(Nodes.class).child(Node.class,key)
-                                                                                        .augmentation(FlowCapableNode.class)
-                                                                                        .child(Meter.class,meterKey).toInstance();
-
-            NodeMeterStatisticsBuilder meterStatsBuilder= new NodeMeterStatisticsBuilder();
-            MeterStatisticsBuilder stats = new MeterStatisticsBuilder();
-            stats.fieldsFrom(meterStats);
-            meterStatsBuilder.setMeterStatistics(stats.build());
-
-            //Update augmented data
-            meterBuilder.addAugmentation(NodeMeterStatistics.class, meterStatsBuilder.build());
-            it.putOperationalData(meterRef, meterBuilder.build());
+        //Add statistics to local cache
+        final NodeStatisticsAger nsa = this.statisticsManager.getStatisticsHandler(notification.getId());
+        if (nsa != null) {
+            nsa.updateMeterStats(notification.getMeterStats());
         }
-        it.commit();
     }
 
     @Override
     public void onGroupDescStatsUpdated(GroupDescStatsUpdated notification) {
-
         //Check if response is for the request statistics-manager sent.
         if(!messageManager.isRequestTxIdExist(notification.getId(),notification.getTransactionId(),notification.isMoreReplies()))
             return;
 
-        final NodeKey key = new NodeKey(notification.getId());
-
-        //Add statistics to local cache
-        this.statisticsManager.getStatisticsAger(key.getId()).updateGroupDescStats(notification.getGroupDescStats());
-
-        //Publish data to configuration data store
-        List<GroupDescStats> groupDescStatsList = notification.getGroupDescStats();
-        DataModificationTransaction it = this.statisticsManager.startChange();
-
-        for(GroupDescStats groupDescStats : groupDescStatsList){
-
-            GroupBuilder groupBuilder = new GroupBuilder();
-            GroupKey groupKey = new GroupKey(groupDescStats.getGroupId());
-            groupBuilder.setKey(groupKey);
-
-            InstanceIdentifier<Group> groupRef = InstanceIdentifier.builder(Nodes.class).child(Node.class,key)
-                                                                                        .augmentation(FlowCapableNode.class)
-                                                                                        .child(Group.class,groupKey).toInstance();
-
-            NodeGroupDescStatsBuilder groupDesc= new NodeGroupDescStatsBuilder();
-            GroupDescBuilder stats = new GroupDescBuilder();
-            stats.fieldsFrom(groupDescStats);
-            groupDesc.setGroupDesc(stats.build());
-
-            //Update augmented data
-            groupBuilder.addAugmentation(NodeGroupDescStats.class, groupDesc.build());
-
-            it.putOperationalData(groupRef, groupBuilder.build());
+        final NodeStatisticsAger nsa = statisticsManager.getStatisticsHandler(notification.getId());
+        if (nsa != null) {
+            nsa.updateGroupDescStats(notification.getGroupDescStats());
         }
-        it.commit();
     }
 
     @Override
     public void onGroupStatisticsUpdated(GroupStatisticsUpdated notification) {
-
         //Check if response is for the request statistics-manager sent.
         if(!messageManager.isRequestTxIdExist(notification.getId(),notification.getTransactionId(),notification.isMoreReplies()))
             return;
 
-        //Publish data to configuration data store
-        NodeKey key = new NodeKey(notification.getId());
-        List<GroupStats> groupStatsList = notification.getGroupStats();
-        DataModificationTransaction it = this.statisticsManager.startChange();
-
-        for(GroupStats groupStats : groupStatsList){
-
-            GroupBuilder groupBuilder = new GroupBuilder();
-            GroupKey groupKey = new GroupKey(groupStats.getGroupId());
-            groupBuilder.setKey(groupKey);
-
-            InstanceIdentifier<Group> groupRef = InstanceIdentifier.builder(Nodes.class).child(Node.class,key)
-                                                                                        .augmentation(FlowCapableNode.class)
-                                                                                        .child(Group.class,groupKey).toInstance();
-
-            NodeGroupStatisticsBuilder groupStatisticsBuilder= new NodeGroupStatisticsBuilder();
-            GroupStatisticsBuilder stats = new GroupStatisticsBuilder();
-            stats.fieldsFrom(groupStats);
-            groupStatisticsBuilder.setGroupStatistics(stats.build());
-
-            //Update augmented data
-            groupBuilder.addAugmentation(NodeGroupStatistics.class, groupStatisticsBuilder.build());
-            it.putOperationalData(groupRef, groupBuilder.build());
+        final NodeStatisticsAger nsa = statisticsManager.getStatisticsHandler(notification.getId());
+        if (nsa != null) {
+            nsa.updateGroupStats(notification.getGroupStats());
         }
-        it.commit();
     }
 
     @Override
     public void onMeterFeaturesUpdated(MeterFeaturesUpdated notification) {
-
-        MeterFeaturesBuilder meterFeature = new MeterFeaturesBuilder();
-        meterFeature.setMeterBandSupported(notification.getMeterBandSupported());
-        meterFeature.setMeterCapabilitiesSupported(notification.getMeterCapabilitiesSupported());
-        meterFeature.setMaxBands(notification.getMaxBands());
-        meterFeature.setMaxColor(notification.getMaxColor());
-        meterFeature.setMaxMeter(notification.getMaxMeter());
-
-        //Publish data to configuration data store
-        DataModificationTransaction it = this.statisticsManager.startChange();
-        NodeKey key = new NodeKey(notification.getId());
-        NodeRef ref = getNodeRef(key);
-
-        final NodeBuilder nodeData = new NodeBuilder();
-        nodeData.setKey(key);
-
-        NodeMeterFeaturesBuilder nodeMeterFeatures= new NodeMeterFeaturesBuilder();
-        nodeMeterFeatures.setMeterFeatures(meterFeature.build());
-
-        //Update augmented data
-        nodeData.addAugmentation(NodeMeterFeatures.class, nodeMeterFeatures.build());
-
-        InstanceIdentifier<? extends Object> refValue = ref.getValue();
-        it.putOperationalData(refValue, nodeData.build());
-        it.commit();
+        final NodeStatisticsAger sna = this.statisticsManager.getStatisticsHandler(notification.getId());
+        if (sna != null) {
+            sna.updateMeterFeatures(notification);
+        }
     }
 
     @Override
     public void onGroupFeaturesUpdated(GroupFeaturesUpdated notification) {
-
-        GroupFeaturesBuilder groupFeatures = new GroupFeaturesBuilder();
-        groupFeatures.setActions(notification.getActions());
-        groupFeatures.setGroupCapabilitiesSupported(notification.getGroupCapabilitiesSupported());
-        groupFeatures.setGroupTypesSupported(notification.getGroupTypesSupported());
-        groupFeatures.setMaxGroups(notification.getMaxGroups());
-
-        //Publish data to configuration data store
-        DataModificationTransaction it = this.statisticsManager.startChange();
-        NodeKey key = new NodeKey(notification.getId());
-        NodeRef ref = getNodeRef(key);
-
-        final NodeBuilder nodeData = new NodeBuilder();
-        nodeData.setKey(key);
-
-        NodeGroupFeaturesBuilder nodeGroupFeatures= new NodeGroupFeaturesBuilder();
-        nodeGroupFeatures.setGroupFeatures(groupFeatures.build());
-
-        //Update augmented data
-        nodeData.addAugmentation(NodeGroupFeatures.class, nodeGroupFeatures.build());
-
-        InstanceIdentifier<? extends Object> refValue = ref.getValue();
-        it.putOperationalData(refValue, nodeData.build());
-        it.commit();
+        final NodeStatisticsAger sna = this.statisticsManager.getStatisticsHandler(notification.getId());
+        if (sna != null) {
+            sna.updateGroupFeatures(notification);
+        }
     }
 
     @Override
@@ -357,7 +161,7 @@ public class StatisticsUpdateCommiter implements OpendaylightGroupStatisticsList
         sucLogger.debug("Received flow stats update : {}",notification.toString());
 
         final NodeKey key = new NodeKey(notification.getId());
-        final NodeStatisticsAger nsa =  this.statisticsManager.getStatisticsAger(key.getId());
+        final NodeStatisticsAger nsa =  this.statisticsManager.getStatisticsHandler(key.getId());
         DataModificationTransaction it = this.statisticsManager.startChange();
 
         for(FlowAndStatisticsMapList map: notification.getFlowAndStatisticsMapList()){
@@ -520,31 +324,10 @@ public class StatisticsUpdateCommiter implements OpendaylightGroupStatisticsList
         if(!messageManager.isRequestTxIdExist(notification.getId(),notification.getTransactionId(),notification.isMoreReplies()))
             return;
 
-        NodeKey key = new NodeKey(notification.getId());
-
-        Short tableId = messageManager.getTableIdForTxId(notification.getId(),notification.getTransactionId());
-        if(tableId != null){
-
-            DataModificationTransaction it = this.statisticsManager.startChange();
-
-            InstanceIdentifier<Table> tableRef = InstanceIdentifier.builder(Nodes.class).child(Node.class, key)
-                    .augmentation(FlowCapableNode.class).child(Table.class, new TableKey(tableId)).toInstance();
-
-            AggregateFlowStatisticsDataBuilder aggregateFlowStatisticsDataBuilder = new AggregateFlowStatisticsDataBuilder();
-            AggregateFlowStatisticsBuilder aggregateFlowStatisticsBuilder = new AggregateFlowStatisticsBuilder();
-            aggregateFlowStatisticsBuilder.setByteCount(notification.getByteCount());
-            aggregateFlowStatisticsBuilder.setFlowCount(notification.getFlowCount());
-            aggregateFlowStatisticsBuilder.setPacketCount(notification.getPacketCount());
-            aggregateFlowStatisticsDataBuilder.setAggregateFlowStatistics(aggregateFlowStatisticsBuilder.build());
-
-            sucLogger.debug("Augment aggregate statistics: {} for table {} on Node {}",aggregateFlowStatisticsBuilder.build().toString(),tableId,key);
-
-            TableBuilder tableBuilder = new TableBuilder();
-            tableBuilder.setKey(new TableKey(tableId));
-            tableBuilder.addAugmentation(AggregateFlowStatisticsData.class, aggregateFlowStatisticsDataBuilder.build());
-            it.putOperationalData(tableRef, tableBuilder.build());
-            it.commit();
-
+        final NodeStatisticsAger nsa = this.statisticsManager.getStatisticsHandler(notification.getId());
+        if (nsa != null) {
+            final Short tableId = messageManager.getTableIdForTxId(notification.getId(),notification.getTransactionId());
+            nsa.updateAggregateFlowStats(tableId, notification);
         }
     }
 
@@ -554,45 +337,10 @@ public class StatisticsUpdateCommiter implements OpendaylightGroupStatisticsList
         if(!messageManager.isRequestTxIdExist(notification.getId(),notification.getTransactionId(),notification.isMoreReplies()))
             return;
 
-        NodeKey key = new NodeKey(notification.getId());
-
-        List<NodeConnectorStatisticsAndPortNumberMap> portsStats = notification.getNodeConnectorStatisticsAndPortNumberMap();
-        DataModificationTransaction it = this.statisticsManager.startChange();
-
-        for(NodeConnectorStatisticsAndPortNumberMap portStats : portsStats){
-
-            FlowCapableNodeConnectorStatisticsBuilder statisticsBuilder
-                                            = new FlowCapableNodeConnectorStatisticsBuilder();
-            statisticsBuilder.setBytes(portStats.getBytes());
-            statisticsBuilder.setCollisionCount(portStats.getCollisionCount());
-            statisticsBuilder.setDuration(portStats.getDuration());
-            statisticsBuilder.setPackets(portStats.getPackets());
-            statisticsBuilder.setReceiveCrcError(portStats.getReceiveCrcError());
-            statisticsBuilder.setReceiveDrops(portStats.getReceiveDrops());
-            statisticsBuilder.setReceiveErrors(portStats.getReceiveErrors());
-            statisticsBuilder.setReceiveFrameError(portStats.getReceiveFrameError());
-            statisticsBuilder.setReceiveOverRunError(portStats.getReceiveOverRunError());
-            statisticsBuilder.setTransmitDrops(portStats.getTransmitDrops());
-            statisticsBuilder.setTransmitErrors(portStats.getTransmitErrors());
-
-            //Augment data to the node-connector
-            FlowCapableNodeConnectorStatisticsDataBuilder statisticsDataBuilder =
-                    new FlowCapableNodeConnectorStatisticsDataBuilder();
-
-            statisticsDataBuilder.setFlowCapableNodeConnectorStatistics(statisticsBuilder.build());
-
-            InstanceIdentifier<NodeConnector> nodeConnectorRef = InstanceIdentifier.builder(Nodes.class).child(Node.class, key).child(NodeConnector.class, new NodeConnectorKey(portStats.getNodeConnectorId())).toInstance();
-
-            NodeConnector nodeConnector = (NodeConnector)it.readOperationalData(nodeConnectorRef);
-
-            if(nodeConnector != null){
-                sucLogger.debug("Augmenting port statistics {} to port {}",statisticsDataBuilder.build().toString(),nodeConnectorRef.toString());
-                NodeConnectorBuilder nodeConnectorBuilder = new NodeConnectorBuilder();
-                nodeConnectorBuilder.addAugmentation(FlowCapableNodeConnectorStatisticsData.class, statisticsDataBuilder.build());
-                it.putOperationalData(nodeConnectorRef, nodeConnectorBuilder.build());
-            }
+        final NodeStatisticsAger nsa = this.statisticsManager.getStatisticsHandler(notification.getId());
+        if (nsa != null) {
+            nsa.updateNodeConnectorStats(notification.getNodeConnectorStatisticsAndPortNumberMap());
         }
-        it.commit();
     }
 
     @Override
@@ -601,33 +349,10 @@ public class StatisticsUpdateCommiter implements OpendaylightGroupStatisticsList
         if(!messageManager.isRequestTxIdExist(notification.getId(),notification.getTransactionId(),notification.isMoreReplies()))
             return;
 
-        NodeKey key = new NodeKey(notification.getId());
-
-        List<FlowTableAndStatisticsMap> flowTablesStatsList = notification.getFlowTableAndStatisticsMap();
-        DataModificationTransaction it = this.statisticsManager.startChange();
-
-        for (FlowTableAndStatisticsMap ftStats : flowTablesStatsList){
-
-            InstanceIdentifier<Table> tableRef = InstanceIdentifier.builder(Nodes.class).child(Node.class, key)
-                    .augmentation(FlowCapableNode.class).child(Table.class, new TableKey(ftStats.getTableId().getValue())).toInstance();
-
-            FlowTableStatisticsDataBuilder statisticsDataBuilder = new FlowTableStatisticsDataBuilder();
-
-            FlowTableStatisticsBuilder statisticsBuilder = new FlowTableStatisticsBuilder();
-            statisticsBuilder.setActiveFlows(ftStats.getActiveFlows());
-            statisticsBuilder.setPacketsLookedUp(ftStats.getPacketsLookedUp());
-            statisticsBuilder.setPacketsMatched(ftStats.getPacketsMatched());
-
-            statisticsDataBuilder.setFlowTableStatistics(statisticsBuilder.build());
-
-            sucLogger.debug("Augment flow table statistics: {} for table {} on Node {}",statisticsBuilder.build().toString(),ftStats.getTableId(),key);
-
-            TableBuilder tableBuilder = new TableBuilder();
-            tableBuilder.setKey(new TableKey(ftStats.getTableId().getValue()));
-            tableBuilder.addAugmentation(FlowTableStatisticsData.class, statisticsDataBuilder.build());
-            it.putOperationalData(tableRef, tableBuilder.build());
+        final NodeStatisticsAger nsa = this.statisticsManager.getStatisticsHandler(notification.getId());
+        if (nsa != null) {
+            nsa.updateFlowTableStats(notification.getFlowTableAndStatisticsMap());
         }
-        it.commit();
     }
 
     @Override
@@ -637,51 +362,11 @@ public class StatisticsUpdateCommiter implements OpendaylightGroupStatisticsList
         if(!messageManager.isRequestTxIdExist(notification.getId(),notification.getTransactionId(),notification.isMoreReplies()))
             return;
 
-        NodeKey key = new NodeKey(notification.getId());
-
         //Add statistics to local cache
-        NodeStatisticsAger nsa = this.statisticsManager.getStatisticsAger(key.getId());
-
-        List<QueueIdAndStatisticsMap> queuesStats = notification.getQueueIdAndStatisticsMap();
-        DataModificationTransaction it = this.statisticsManager.startChange();
-
-        for(QueueIdAndStatisticsMap swQueueStats : queuesStats){
-
-            QueueEntry queueEntry = nsa.new QueueEntry(swQueueStats.getNodeConnectorId(),swQueueStats.getQueueId());
-            nsa.updateQueueStats(queueEntry);
-
-            FlowCapableNodeConnectorQueueStatisticsDataBuilder queueStatisticsDataBuilder = new FlowCapableNodeConnectorQueueStatisticsDataBuilder();
-
-            FlowCapableNodeConnectorQueueStatisticsBuilder queueStatisticsBuilder = new FlowCapableNodeConnectorQueueStatisticsBuilder();
-
-            queueStatisticsBuilder.fieldsFrom(swQueueStats);
-
-            queueStatisticsDataBuilder.setFlowCapableNodeConnectorQueueStatistics(queueStatisticsBuilder.build());
-
-            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.debug("Augmenting queue statistics {} of queue {} to port {}"
-                                        ,queueStatisticsDataBuilder.build().toString(),
-                                        swQueueStats.getQueueId(),
-                                        swQueueStats.getNodeConnectorId());
-
-            it.putOperationalData(queueRef, queueBuilder.build());
+        final NodeStatisticsAger nsa = this.statisticsManager.getStatisticsHandler(notification.getId());
+        if (nsa != null) {
+            nsa.updateQueueStats(notification.getQueueIdAndStatisticsMap());
         }
-        it.commit();
-    }
-
-    private static NodeRef getNodeRef(NodeKey nodeKey){
-        InstanceIdentifierBuilder<?> builder = InstanceIdentifier.builder(Nodes.class).child(Node.class, nodeKey);
-        return new NodeRef(builder.toInstance());
     }
 
     public static boolean flowEquals(Flow statsFlow, Flow storedFlow) {