From 7c1ced6aeaeca12da6786950c20a2133d9eb72e1 Mon Sep 17 00:00:00 2001 From: Robert Varga Date: Thu, 13 Feb 2014 19:45:13 +0100 Subject: [PATCH] Split out statistics tracking into separate classes - FlowStats - FlowTableStats - GroupDescStats - GroupStats - MeterConfigStats - MeterStats - NodeConnectorStats - QueueStats are all now tracked by dedicated classes. Also create a dedicated QueueStatsEntry and FlowStatsEntry class. Furthermore the flow walking code is modified to stop searching as soon as it finds a matching flow. Change-Id: Ia2bacb12f9c0af6520c115c161388b72a846b062 Signed-off-by: Robert Varga --- .../manager/AbstractStatsTracker.java | 64 ++ .../md/statistics/manager/FlowStatsEntry.java | 59 ++ .../statistics/manager/FlowStatsTracker.java | 186 +++++ .../manager/FlowTableStatsTracker.java | 61 ++ .../manager/GroupDescStatsTracker.java | 53 ++ .../statistics/manager/GroupStatsTracker.java | 55 ++ .../manager/MeterConfigStatsTracker.java | 56 ++ .../statistics/manager/MeterStatsTracker.java | 55 ++ .../manager/NodeConnectorStatsTracker.java | 73 ++ .../manager/NodeStatisticsHandler.java | 641 +----------------- .../statistics/manager/QueueStatsEntry.java | 62 ++ .../statistics/manager/QueueStatsTracker.java | 75 ++ .../manager/StatisticsProvider.java | 10 +- 13 files changed, 837 insertions(+), 613 deletions(-) create mode 100644 opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/AbstractStatsTracker.java create mode 100644 opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/FlowStatsEntry.java create mode 100644 opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/FlowStatsTracker.java create mode 100644 opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/FlowTableStatsTracker.java create mode 100644 opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/GroupDescStatsTracker.java create mode 100644 opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/GroupStatsTracker.java create mode 100644 opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/MeterConfigStatsTracker.java create mode 100644 opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/MeterStatsTracker.java create mode 100644 opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/NodeConnectorStatsTracker.java create mode 100644 opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/QueueStatsEntry.java create mode 100644 opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/QueueStatsTracker.java diff --git a/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/AbstractStatsTracker.java b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/AbstractStatsTracker.java new file mode 100644 index 0000000000..aa7720cf10 --- /dev/null +++ b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/AbstractStatsTracker.java @@ -0,0 +1,64 @@ +/* + * Copyright IBM Corporation, 2013. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.controller.md.statistics.manager; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction; +import org.opendaylight.controller.sal.binding.api.data.DataProviderService; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder; + +import com.google.common.base.Preconditions; + +abstract class AbstractStatsTracker { + private final Map trackedItems = new HashMap<>(); + private final InstanceIdentifier nodeIdentifier; + private final DataProviderService dps; + private final long lifetimeNanos; + + protected AbstractStatsTracker(final InstanceIdentifier nodeIdentifier, final DataProviderService dps, long lifetimeNanos) { + this.nodeIdentifier = Preconditions.checkNotNull(nodeIdentifier); + this.dps = Preconditions.checkNotNull(dps); + this.lifetimeNanos = lifetimeNanos; + } + + protected final InstanceIdentifierBuilder getNodeIdentifierBuilder() { + return InstanceIdentifier.builder(nodeIdentifier); + } + + final synchronized void updateStats(List list) { + final Long expiryTime = System.nanoTime() + lifetimeNanos; + final DataModificationTransaction trans = dps.beginTransaction(); + + for (final I item : list) { + trackedItems.put(updateSingleStat(trans, item), expiryTime); + } + + trans.commit(); + } + + + final synchronized void cleanup(final DataModificationTransaction trans, long now) { + for (Iterator> it = trackedItems.entrySet().iterator();it.hasNext();){ + Entry e = it.next(); + if (now > e.getValue()) { + cleanupSingleStat(trans, e.getKey()); + it.remove(); + } + } + } + + protected abstract void cleanupSingleStat(DataModificationTransaction trans, K item); + protected abstract K updateSingleStat(DataModificationTransaction trans, I item); +} diff --git a/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/FlowStatsEntry.java b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/FlowStatsEntry.java new file mode 100644 index 0000000000..b5b39d94d2 --- /dev/null +++ b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/FlowStatsEntry.java @@ -0,0 +1,59 @@ +/* + * Copyright IBM Corporation, 2013. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.controller.md.statistics.manager; + +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow; + +final class FlowStatsEntry { + private final Short tableId; + private final Flow flow; + + public FlowStatsEntry(Short tableId, Flow flow){ + this.tableId = tableId; + this.flow = flow; + } + + public Short getTableId() { + return tableId; + } + + public Flow getFlow() { + return flow; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((flow == null) ? 0 : flow.hashCode()); + result = prime * result + ((tableId == null) ? 0 : tableId.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + FlowStatsEntry other = (FlowStatsEntry) obj; + if (flow == null) { + if (other.flow != null) + return false; + } else if (!flow.equals(other.flow)) + return false; + if (tableId == null) { + if (other.tableId != null) + return false; + } else if (!tableId.equals(other.tableId)) + return false; + return true; + } +} diff --git a/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/FlowStatsTracker.java b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/FlowStatsTracker.java new file mode 100644 index 0000000000..e1854375a5 --- /dev/null +++ b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/FlowStatsTracker.java @@ -0,0 +1,186 @@ +/* + * Copyright IBM Corporation, 2013. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.controller.md.statistics.manager; + +import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction; +import org.opendaylight.controller.sal.binding.api.data.DataProviderService; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode; +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.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.FlowStatisticsData; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowStatisticsDataBuilder; +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.inventory.rev130819.nodes.Node; +import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.GenericStatistics; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +final class FlowStatsTracker extends AbstractStatsTracker { + private static final Logger logger = LoggerFactory.getLogger(FlowStatsTracker.class); + private int unaccountedFlowsCounter = 1; + + FlowStatsTracker(InstanceIdentifier nodeIdentifier, DataProviderService dps, long lifetimeNanos) { + super(nodeIdentifier, dps, lifetimeNanos); + } + + @Override + protected void cleanupSingleStat(DataModificationTransaction trans, FlowStatsEntry item) { + InstanceIdentifier flowRef = getNodeIdentifierBuilder() + .augmentation(FlowCapableNode.class) + .child(Table.class, new TableKey(item.getTableId())) + .child(Flow.class,item.getFlow().getKey()) + .augmentation(FlowStatisticsData.class).toInstance(); + trans.removeOperationalData(flowRef); + } + + @Override + protected FlowStatsEntry updateSingleStat(DataModificationTransaction trans, FlowAndStatisticsMapList map) { + short tableId = map.getTableId(); + + FlowBuilder flowBuilder = new FlowBuilder(); + + FlowStatisticsDataBuilder flowStatisticsData = new FlowStatisticsDataBuilder(); + + FlowBuilder flow = new FlowBuilder(); + flow.setContainerName(map.getContainerName()); + flow.setBufferId(map.getBufferId()); + flow.setCookie(map.getCookie()); + flow.setCookieMask(map.getCookieMask()); + flow.setFlags(map.getFlags()); + flow.setFlowName(map.getFlowName()); + flow.setHardTimeout(map.getHardTimeout()); + if(map.getFlowId() != null) + flow.setId(new FlowId(map.getFlowId().getValue())); + flow.setIdleTimeout(map.getIdleTimeout()); + flow.setInstallHw(map.isInstallHw()); + flow.setInstructions(map.getInstructions()); + if(map.getFlowId()!= null) + flow.setKey(new FlowKey(new FlowId(map.getKey().getFlowId().getValue()))); + flow.setMatch(map.getMatch()); + flow.setOutGroup(map.getOutGroup()); + flow.setOutPort(map.getOutPort()); + flow.setPriority(map.getPriority()); + flow.setStrict(map.isStrict()); + flow.setTableId(tableId); + + Flow flowRule = flow.build(); + + FlowAndStatisticsMapListBuilder stats = new FlowAndStatisticsMapListBuilder(); + stats.setByteCount(map.getByteCount()); + stats.setPacketCount(map.getPacketCount()); + stats.setDuration(map.getDuration()); + + GenericStatistics flowStats = stats.build(); + + //Augment the data to the flow node + + FlowStatisticsBuilder flowStatistics = new FlowStatisticsBuilder(); + flowStatistics.setByteCount(flowStats.getByteCount()); + flowStatistics.setPacketCount(flowStats.getPacketCount()); + flowStatistics.setDuration(flowStats.getDuration()); + flowStatistics.setContainerName(map.getContainerName()); + flowStatistics.setBufferId(map.getBufferId()); + flowStatistics.setCookie(map.getCookie()); + flowStatistics.setCookieMask(map.getCookieMask()); + flowStatistics.setFlags(map.getFlags()); + flowStatistics.setFlowName(map.getFlowName()); + flowStatistics.setHardTimeout(map.getHardTimeout()); + flowStatistics.setIdleTimeout(map.getIdleTimeout()); + flowStatistics.setInstallHw(map.isInstallHw()); + flowStatistics.setInstructions(map.getInstructions()); + flowStatistics.setMatch(map.getMatch()); + flowStatistics.setOutGroup(map.getOutGroup()); + flowStatistics.setOutPort(map.getOutPort()); + flowStatistics.setPriority(map.getPriority()); + flowStatistics.setStrict(map.isStrict()); + flowStatistics.setTableId(tableId); + + flowStatisticsData.setFlowStatistics(flowStatistics.build()); + + logger.debug("Flow : {}",flowRule.toString()); + logger.debug("Statistics to augment : {}",flowStatistics.build().toString()); + + InstanceIdentifier tableRef = getNodeIdentifierBuilder() + .augmentation(FlowCapableNode.class).child(Table.class, new TableKey(tableId)).toInstance(); + + //TODO: Not a good way to do it, need to figure out better way. + //TODO: major issue in any alternate approach is that flow key is incrementally assigned + //to the flows stored in data store. + // Augment same statistics to all the matching masked flow + Table table= (Table)trans.readConfigurationData(tableRef); + if(table != null){ + for(Flow existingFlow : table.getFlow()){ + logger.debug("Existing flow in data store : {}",existingFlow.toString()); + if(FlowComparator.flowEquals(flowRule,existingFlow)){ + InstanceIdentifier flowRef = getNodeIdentifierBuilder() + .augmentation(FlowCapableNode.class) + .child(Table.class, new TableKey(tableId)) + .child(Flow.class,existingFlow.getKey()).toInstance(); + flowBuilder.setKey(existingFlow.getKey()); + flowBuilder.addAugmentation(FlowStatisticsData.class, flowStatisticsData.build()); + logger.debug("Found matching flow in the datastore, augmenting statistics"); + // Update entry with timestamp of latest response + flow.setKey(existingFlow.getKey()); + FlowStatsEntry flowStatsEntry = new FlowStatsEntry(tableId,flow.build()); + trans.putOperationalData(flowRef, flowBuilder.build()); + return flowStatsEntry; + } + } + } + + table = (Table)trans.readOperationalData(tableRef); + if(table != null){ + for(Flow existingFlow : table.getFlow()){ + FlowStatisticsData augmentedflowStatisticsData = existingFlow.getAugmentation(FlowStatisticsData.class); + if(augmentedflowStatisticsData != null){ + FlowBuilder existingOperationalFlow = new FlowBuilder(); + existingOperationalFlow.fieldsFrom(augmentedflowStatisticsData.getFlowStatistics()); + logger.debug("Existing unaccounted flow in operational data store : {}",existingFlow.toString()); + if(FlowComparator.flowEquals(flowRule,existingOperationalFlow.build())){ + InstanceIdentifier flowRef = getNodeIdentifierBuilder() + .augmentation(FlowCapableNode.class) + .child(Table.class, new TableKey(tableId)) + .child(Flow.class,existingFlow.getKey()).toInstance(); + flowBuilder.setKey(existingFlow.getKey()); + flowBuilder.addAugmentation(FlowStatisticsData.class, flowStatisticsData.build()); + logger.debug("Found matching unaccounted flow in the operational datastore, augmenting statistics"); + // Update entry with timestamp of latest response + flow.setKey(existingFlow.getKey()); + FlowStatsEntry flowStatsEntry = new FlowStatsEntry(tableId,flow.build()); + trans.putOperationalData(flowRef, flowBuilder.build()); + return flowStatsEntry; + } + } + } + } + + String flowKey = "#UF$TABLE*"+Short.toString(tableId)+"*"+Integer.toString(this.unaccountedFlowsCounter); + this.unaccountedFlowsCounter++; + FlowKey newFlowKey = new FlowKey(new FlowId(flowKey)); + InstanceIdentifier flowRef = getNodeIdentifierBuilder().augmentation(FlowCapableNode.class) + .child(Table.class, new TableKey(tableId)) + .child(Flow.class,newFlowKey).toInstance(); + flowBuilder.setKey(newFlowKey); + flowBuilder.addAugmentation(FlowStatisticsData.class, flowStatisticsData.build()); + logger.debug("Flow {} is not present in config data store, augmenting statistics as an unaccounted flow", + flowBuilder.build()); + + // Update entry with timestamp of latest response + flow.setKey(newFlowKey); + FlowStatsEntry flowStatsEntry = new FlowStatsEntry(tableId,flow.build()); + trans.putOperationalData(flowRef, flowBuilder.build()); + return flowStatsEntry; + } +} diff --git a/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/FlowTableStatsTracker.java b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/FlowTableStatsTracker.java new file mode 100644 index 0000000000..2544d55805 --- /dev/null +++ b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/FlowTableStatsTracker.java @@ -0,0 +1,61 @@ +/* + * Copyright IBM Corporation, 2013. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.controller.md.statistics.manager; + +import java.util.Collections; +import java.util.Set; +import java.util.concurrent.ConcurrentSkipListSet; + +import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction; +import org.opendaylight.controller.sal.binding.api.data.DataProviderService; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode; +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.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.inventory.rev130819.nodes.Node; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +final class FlowTableStatsTracker extends AbstractStatsTracker { + private final Set privateTables = new ConcurrentSkipListSet<>(); + private final Set tables = Collections.unmodifiableSet(privateTables); + + FlowTableStatsTracker(InstanceIdentifier nodeIdentifier, DataProviderService dps, long lifetimeNanos) { + super(nodeIdentifier, dps, lifetimeNanos); + } + + Set getTables() { + return tables; + } + + @Override + protected void cleanupSingleStat(DataModificationTransaction trans, FlowTableAndStatisticsMap item) { + // TODO: do we want to do this? + } + + @Override + protected FlowTableAndStatisticsMap updateSingleStat(DataModificationTransaction trans, FlowTableAndStatisticsMap item) { + + InstanceIdentifier
tableRef = getNodeIdentifierBuilder() + .augmentation(FlowCapableNode.class).child(Table.class, new TableKey(item.getTableId().getValue())).build(); + + FlowTableStatisticsDataBuilder statisticsDataBuilder = new FlowTableStatisticsDataBuilder(); + final FlowTableStatistics stats = new FlowTableStatisticsBuilder(item).build(); + statisticsDataBuilder.setFlowTableStatistics(stats); + + TableBuilder tableBuilder = new TableBuilder(); + tableBuilder.setKey(new TableKey(item.getTableId().getValue())); + tableBuilder.addAugmentation(FlowTableStatisticsData.class, statisticsDataBuilder.build()); + trans.putOperationalData(tableRef, tableBuilder.build()); + return item; + } +} diff --git a/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/GroupDescStatsTracker.java b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/GroupDescStatsTracker.java new file mode 100644 index 0000000000..928bf4ea55 --- /dev/null +++ b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/GroupDescStatsTracker.java @@ -0,0 +1,53 @@ +/* + * Copyright IBM Corporation, 2013. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.controller.md.statistics.manager; + +import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction; +import org.opendaylight.controller.sal.binding.api.data.DataProviderService; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode; +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.group.desc.GroupDescBuilder; +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.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.nodes.Node; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +final class GroupDescStatsTracker extends AbstractStatsTracker { + public GroupDescStatsTracker(final InstanceIdentifier targetNodeIdentifier, final DataProviderService dps, final long lifetimeNanos) { + super(targetNodeIdentifier, dps, lifetimeNanos); + } + + @Override + protected GroupDescStats updateSingleStat(DataModificationTransaction trans, GroupDescStats item) { + GroupBuilder groupBuilder = new GroupBuilder(); + GroupKey groupKey = new GroupKey(item.getGroupId()); + groupBuilder.setKey(groupKey); + + InstanceIdentifier groupRef = getNodeIdentifierBuilder() + .augmentation(FlowCapableNode.class).child(Group.class,groupKey).build(); + + NodeGroupDescStatsBuilder groupDesc= new NodeGroupDescStatsBuilder(); + groupDesc.setGroupDesc(new GroupDescBuilder(item).build()); + + //Update augmented data + groupBuilder.addAugmentation(NodeGroupDescStats.class, groupDesc.build()); + + trans.putOperationalData(groupRef, groupBuilder.build()); + return item; + } + + @Override + protected void cleanupSingleStat(DataModificationTransaction trans, GroupDescStats item) { + InstanceIdentifier groupRef = getNodeIdentifierBuilder().augmentation(FlowCapableNode.class) + .child(Group.class, new GroupKey(item.getGroupId())).augmentation(NodeGroupDescStats.class).build(); + trans.removeOperationalData(groupRef); + } +} diff --git a/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/GroupStatsTracker.java b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/GroupStatsTracker.java new file mode 100644 index 0000000000..a5498f5a30 --- /dev/null +++ b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/GroupStatsTracker.java @@ -0,0 +1,55 @@ +/* + * Copyright IBM Corporation, 2013. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.controller.md.statistics.manager; + +import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction; +import org.opendaylight.controller.sal.binding.api.data.DataProviderService; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode; +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.statistics.GroupStatisticsBuilder; +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.nodes.Node; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +final class GroupStatsTracker extends AbstractStatsTracker { + + GroupStatsTracker(InstanceIdentifier nodeIdentifier, DataProviderService dps, long lifetimeNanos) { + super(nodeIdentifier, dps, lifetimeNanos); + } + + @Override + protected void cleanupSingleStat(DataModificationTransaction trans, GroupStats item) { + InstanceIdentifier groupRef = getNodeIdentifierBuilder().augmentation(FlowCapableNode.class) + .child(Group.class, new GroupKey(item.getGroupId())).augmentation(NodeGroupStatistics.class).build(); + trans.removeOperationalData(groupRef); + } + + @Override + protected GroupStats updateSingleStat(DataModificationTransaction trans, + GroupStats item) { + GroupBuilder groupBuilder = new GroupBuilder(); + GroupKey groupKey = new GroupKey(item.getGroupId()); + groupBuilder.setKey(groupKey); + + InstanceIdentifier groupRef = getNodeIdentifierBuilder().augmentation(FlowCapableNode.class) + .child(Group.class,groupKey).build(); + + NodeGroupStatisticsBuilder groupStatisticsBuilder= new NodeGroupStatisticsBuilder(); + groupStatisticsBuilder.setGroupStatistics(new GroupStatisticsBuilder(item).build()); + + //Update augmented data + groupBuilder.addAugmentation(NodeGroupStatistics.class, groupStatisticsBuilder.build()); + trans.putOperationalData(groupRef, groupBuilder.build()); + return item; + } + +} diff --git a/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/MeterConfigStatsTracker.java b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/MeterConfigStatsTracker.java new file mode 100644 index 0000000000..dcb0b403dc --- /dev/null +++ b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/MeterConfigStatsTracker.java @@ -0,0 +1,56 @@ +/* + * Copyright IBM Corporation, 2013. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.controller.md.statistics.manager; + +import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction; +import org.opendaylight.controller.sal.binding.api.data.DataProviderService; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode; +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.inventory.rev130819.nodes.Node; +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.nodes.node.meter.MeterConfigStatsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.meter.config.stats.reply.MeterConfigStats; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +final class MeterConfigStatsTracker extends AbstractStatsTracker { + protected MeterConfigStatsTracker(InstanceIdentifier nodeIdentifier, DataProviderService dps, long lifetimeNanos) { + super(nodeIdentifier, dps, lifetimeNanos); + } + + @Override + protected void cleanupSingleStat(DataModificationTransaction trans, MeterConfigStats item) { + InstanceIdentifier meterRef = getNodeIdentifierBuilder() + .augmentation(FlowCapableNode.class) + .child(Meter.class, new MeterKey(item.getMeterId())) + .augmentation(NodeMeterConfigStats.class).build(); + trans.removeOperationalData(meterRef); + } + + @Override + protected MeterConfigStats updateSingleStat(DataModificationTransaction trans, MeterConfigStats item) { + MeterBuilder meterBuilder = new MeterBuilder(); + MeterKey meterKey = new MeterKey(item.getMeterId()); + meterBuilder.setKey(meterKey); + + InstanceIdentifier meterRef = getNodeIdentifierBuilder().augmentation(FlowCapableNode.class) + .child(Meter.class,meterKey).toInstance(); + + NodeMeterConfigStatsBuilder meterConfig = new NodeMeterConfigStatsBuilder(); + meterConfig.setMeterConfigStats(new MeterConfigStatsBuilder(item).build()); + + //Update augmented data + meterBuilder.addAugmentation(NodeMeterConfigStats.class, meterConfig.build()); + + trans.putOperationalData(meterRef, meterBuilder.build()); + return item; + } + +} diff --git a/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/MeterStatsTracker.java b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/MeterStatsTracker.java new file mode 100644 index 0000000000..381db8a39f --- /dev/null +++ b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/MeterStatsTracker.java @@ -0,0 +1,55 @@ +/* + * Copyright IBM Corporation, 2013. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.controller.md.statistics.manager; + +import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction; +import org.opendaylight.controller.sal.binding.api.data.DataProviderService; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode; +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.inventory.rev130819.nodes.Node; +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.meter.MeterStatisticsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.meter.statistics.reply.MeterStats; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +final class MeterStatsTracker extends AbstractStatsTracker { + + MeterStatsTracker(InstanceIdentifier nodeIdentifier, DataProviderService dps, long lifetimeNanos) { + super(nodeIdentifier, dps, lifetimeNanos); + } + + @Override + protected void cleanupSingleStat(DataModificationTransaction trans, MeterStats item) { + InstanceIdentifier meterRef = getNodeIdentifierBuilder() + .augmentation(FlowCapableNode.class) + .child(Meter.class,new MeterKey(item.getMeterId())) + .augmentation(NodeMeterStatistics.class).build(); + trans.removeOperationalData(meterRef); + } + + @Override + protected MeterStats updateSingleStat(DataModificationTransaction trans, MeterStats item) { + MeterBuilder meterBuilder = new MeterBuilder(); + MeterKey meterKey = new MeterKey(item.getMeterId()); + meterBuilder.setKey(meterKey); + + InstanceIdentifier meterRef = getNodeIdentifierBuilder() + .augmentation(FlowCapableNode.class).child(Meter.class,meterKey).build(); + + NodeMeterStatisticsBuilder meterStatsBuilder= new NodeMeterStatisticsBuilder(); + meterStatsBuilder.setMeterStatistics(new MeterStatisticsBuilder(item).build()); + + //Update augmented data + meterBuilder.addAugmentation(NodeMeterStatistics.class, meterStatsBuilder.build()); + trans.putOperationalData(meterRef, meterBuilder.build()); + return item; + } +} diff --git a/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/NodeConnectorStatsTracker.java b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/NodeConnectorStatsTracker.java new file mode 100644 index 0000000000..2a8b180a51 --- /dev/null +++ b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/NodeConnectorStatsTracker.java @@ -0,0 +1,73 @@ +/* + * Copyright IBM Corporation, 2013. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.controller.md.statistics.manager; + +import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction; +import org.opendaylight.controller.sal.binding.api.data.DataProviderService; +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.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.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +final class NodeConnectorStatsTracker extends AbstractStatsTracker { + private static final Logger logger = LoggerFactory.getLogger(NodeConnectorStatsTracker.class); + + NodeConnectorStatsTracker(InstanceIdentifier nodeIdentifier, DataProviderService dps, long lifetimeNanos) { + super(nodeIdentifier, dps, lifetimeNanos); + } + + @Override + protected void cleanupSingleStat(DataModificationTransaction trans, NodeConnectorStatisticsAndPortNumberMap item) { + // TODO Auto-generated method stub + } + + @Override + protected NodeConnectorStatisticsAndPortNumberMap updateSingleStat(DataModificationTransaction trans, NodeConnectorStatisticsAndPortNumberMap item) { + FlowCapableNodeConnectorStatisticsBuilder statisticsBuilder + = new FlowCapableNodeConnectorStatisticsBuilder(); + statisticsBuilder.setBytes(item.getBytes()); + statisticsBuilder.setCollisionCount(item.getCollisionCount()); + statisticsBuilder.setDuration(item.getDuration()); + statisticsBuilder.setPackets(item.getPackets()); + statisticsBuilder.setReceiveCrcError(item.getReceiveCrcError()); + statisticsBuilder.setReceiveDrops(item.getReceiveDrops()); + statisticsBuilder.setReceiveErrors(item.getReceiveErrors()); + statisticsBuilder.setReceiveFrameError(item.getReceiveFrameError()); + statisticsBuilder.setReceiveOverRunError(item.getReceiveOverRunError()); + statisticsBuilder.setTransmitDrops(item.getTransmitDrops()); + statisticsBuilder.setTransmitErrors(item.getTransmitErrors()); + + //Augment data to the node-connector + FlowCapableNodeConnectorStatisticsDataBuilder statisticsDataBuilder = + new FlowCapableNodeConnectorStatisticsDataBuilder(); + + statisticsDataBuilder.setFlowCapableNodeConnectorStatistics(statisticsBuilder.build()); + + InstanceIdentifier nodeConnectorRef = getNodeIdentifierBuilder() + .child(NodeConnector.class, new NodeConnectorKey(item.getNodeConnectorId())).build(); + + // 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()); + } + + return item; + } +} diff --git a/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/NodeStatisticsHandler.java b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/NodeStatisticsHandler.java index 326da07c73..17f1ce2a7b 100644 --- a/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/NodeStatisticsHandler.java +++ b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/NodeStatisticsHandler.java @@ -8,95 +8,41 @@ package org.opendaylight.controller.md.statistics.manager; import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; import java.util.concurrent.TimeUnit; import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction; import org.opendaylight.controller.sal.binding.api.data.DataProviderService; 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.FlowStatisticsData; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowStatisticsDataBuilder; 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.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.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.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.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.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; @@ -113,122 +59,34 @@ public final class NodeStatisticsHandler implements AutoCloseable { private static final Logger logger = LoggerFactory.getLogger(NodeStatisticsHandler.class); private static final int NUMBER_OF_WAIT_CYCLES = 2; - private final Map groupDescStatsUpdate = new HashMap<>(); - private final Map meterConfigStatsUpdate = new HashMap<>(); - private final Map flowStatsUpdate = new HashMap<>(); - private final Map queuesStatsUpdate = new HashMap<>(); private final InstanceIdentifier targetNodeIdentifier; + private final FlowStatsTracker flowStats; + private final FlowTableStatsTracker flowTableStats; + private final GroupDescStatsTracker groupDescStats; + private final GroupStatsTracker groupStats; + private final MeterConfigStatsTracker meterConfigStats; + private final MeterStatsTracker meterStats; + private final NodeConnectorStatsTracker nodeConnectorStats; + private final QueueStatsTracker queueStats; private final DataProviderService dps; private final NodeRef targetNodeRef; private final NodeKey targetNodeKey; - private Collection knownTables = Collections.emptySet(); - private int unaccountedFlowsCounter = 1; public NodeStatisticsHandler(final DataProviderService dps, final NodeKey nodeKey) { this.dps = Preconditions.checkNotNull(dps); this.targetNodeKey = Preconditions.checkNotNull(nodeKey); this.targetNodeIdentifier = InstanceIdentifier.builder(Nodes.class).child(Node.class, targetNodeKey).build(); this.targetNodeRef = new NodeRef(targetNodeIdentifier); - } - - private static class FlowEntry { - private final Short tableId; - private final Flow flow; - - public FlowEntry(Short tableId, Flow flow){ - this.tableId = tableId; - this.flow = flow; - } - - public Short getTableId() { - return tableId; - } - - public Flow getFlow() { - return flow; - } - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((flow == null) ? 0 : flow.hashCode()); - result = prime * result + ((tableId == null) ? 0 : tableId.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - FlowEntry other = (FlowEntry) obj; - if (flow == null) { - if (other.flow != null) - return false; - } else if (!flow.equals(other.flow)) - return false; - if (tableId == null) { - if (other.tableId != null) - return false; - } else if (!tableId.equals(other.tableId)) - return false; - return true; - } - } - - private static final class QueueEntry { - private final NodeConnectorId nodeConnectorId; - private final QueueId queueId; - public QueueEntry(NodeConnectorId ncId, QueueId queueId){ - this.nodeConnectorId = ncId; - this.queueId = queueId; - } - public NodeConnectorId getNodeConnectorId() { - return nodeConnectorId; - } - public QueueId getQueueId() { - return queueId; - } - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((nodeConnectorId == null) ? 0 : nodeConnectorId.hashCode()); - result = prime * result + ((queueId == null) ? 0 : queueId.hashCode()); - return result; - } - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (!(obj instanceof QueueEntry)) { - return false; - } - QueueEntry other = (QueueEntry) obj; - if (nodeConnectorId == null) { - if (other.nodeConnectorId != null) { - return false; - } - } else if (!nodeConnectorId.equals(other.nodeConnectorId)) { - return false; - } - if (queueId == null) { - if (other.queueId != null) { - return false; - } - } else if (!queueId.equals(other.queueId)) { - return false; - } - return true; - } + final long lifetimeNanos = TimeUnit.MILLISECONDS.toNanos(StatisticsProvider.STATS_COLLECTION_MILLIS * NUMBER_OF_WAIT_CYCLES); + flowStats = new FlowStatsTracker(targetNodeIdentifier, dps, lifetimeNanos); + flowTableStats = new FlowTableStatsTracker(targetNodeIdentifier, dps, lifetimeNanos); + groupDescStats = new GroupDescStatsTracker(targetNodeIdentifier, dps, lifetimeNanos); + groupStats = new GroupStatsTracker(targetNodeIdentifier, dps, lifetimeNanos); + meterConfigStats = new MeterConfigStatsTracker(targetNodeIdentifier, dps, lifetimeNanos); + meterStats = new MeterStatsTracker(targetNodeIdentifier, dps, lifetimeNanos); + nodeConnectorStats = new NodeConnectorStatsTracker(targetNodeIdentifier, dps, lifetimeNanos); + queueStats = new QueueStatsTracker(targetNodeIdentifier, dps, lifetimeNanos); } public NodeKey getTargetNodeKey() { @@ -236,7 +94,7 @@ public final class NodeStatisticsHandler implements AutoCloseable { } public Collection getKnownTables() { - return knownTables; + return flowTableStats.getTables(); } public InstanceIdentifier getTargetNodeIdentifier() { @@ -247,235 +105,38 @@ public final class NodeStatisticsHandler implements AutoCloseable { return targetNodeRef; } - public synchronized void updateGroupDescStats(List list){ - final Long expiryTime = getExpiryTime(); - final DataModificationTransaction trans = dps.beginTransaction(); - - for (GroupDescStats groupDescStats : list) { - GroupBuilder groupBuilder = new GroupBuilder(); - GroupKey groupKey = new GroupKey(groupDescStats.getGroupId()); - groupBuilder.setKey(groupKey); - - InstanceIdentifier 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 updateGroupDescStats(List list) { + groupDescStats.updateStats(list); } public synchronized void updateGroupStats(List list) { - final DataModificationTransaction trans = dps.beginTransaction(); - - for(GroupStats groupStats : list) { - GroupBuilder groupBuilder = new GroupBuilder(); - GroupKey groupKey = new GroupKey(groupStats.getGroupId()); - groupBuilder.setKey(groupKey); - - InstanceIdentifier 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(); + groupStats.updateStats(list); } public synchronized void updateMeterConfigStats(List list) { - final Long expiryTime = getExpiryTime(); - final DataModificationTransaction trans = dps.beginTransaction(); - - for(MeterConfigStats meterConfigStats : list) { - MeterBuilder meterBuilder = new MeterBuilder(); - MeterKey meterKey = new MeterKey(meterConfigStats.getMeterId()); - meterBuilder.setKey(meterKey); - - InstanceIdentifier 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(); + meterConfigStats.updateStats(list); } - public synchronized void updateMeterStats(List list) { - final DataModificationTransaction trans = dps.beginTransaction(); - - for(MeterStats meterStats : list) { - MeterBuilder meterBuilder = new MeterBuilder(); - MeterKey meterKey = new MeterKey(meterStats.getMeterId()); - meterBuilder.setKey(meterKey); - - InstanceIdentifier 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(); + meterStats.updateStats(list); } public synchronized void updateQueueStats(List list) { - final Long expiryTime = getExpiryTime(); - final DataModificationTransaction trans = dps.beginTransaction(); - - 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 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(); + queueStats.updateStats(list); } public synchronized void updateFlowTableStats(List list) { - final DataModificationTransaction trans = dps.beginTransaction(); - - final Set knownTables = new HashSet<>(list.size()); - for (FlowTableAndStatisticsMap ftStats : list) { - - InstanceIdentifier
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(); - final FlowTableStatistics stats = new FlowTableStatisticsBuilder(ftStats).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()); - - knownTables.add(tableBuilder.getKey()); - } - - this.knownTables = Collections.unmodifiableCollection(knownTables); - trans.commit(); + flowTableStats.updateStats(list); } public synchronized void updateNodeConnectorStats(List list) { - final DataModificationTransaction trans = dps.beginTransaction(); - - 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 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(); + nodeConnectorStats.updateStats(list); } public synchronized void updateAggregateFlowStats(Short tableId, AggregateFlowStatistics flowStats) { if (tableId != null) { final DataModificationTransaction trans = dps.beginTransaction(); - InstanceIdentifier
tableRef = InstanceIdentifier.builder(Nodes.class).child(Node.class, targetNodeKey) .augmentation(FlowCapableNode.class).child(Table.class, new TableKey(tableId)).toInstance(); @@ -534,256 +195,24 @@ public final class NodeStatisticsHandler implements AutoCloseable { } public synchronized void updateFlowStats(List list) { - final Long expiryTime = getExpiryTime(); - final DataModificationTransaction trans = dps.beginTransaction(); - - for(FlowAndStatisticsMapList map : list) { - short tableId = map.getTableId(); - boolean foundOriginalFlow = false; - - FlowBuilder flowBuilder = new FlowBuilder(); - - FlowStatisticsDataBuilder flowStatisticsData = new FlowStatisticsDataBuilder(); - - FlowBuilder flow = new FlowBuilder(); - flow.setContainerName(map.getContainerName()); - flow.setBufferId(map.getBufferId()); - flow.setCookie(map.getCookie()); - flow.setCookieMask(map.getCookieMask()); - flow.setFlags(map.getFlags()); - flow.setFlowName(map.getFlowName()); - flow.setHardTimeout(map.getHardTimeout()); - if(map.getFlowId() != null) - flow.setId(new FlowId(map.getFlowId().getValue())); - flow.setIdleTimeout(map.getIdleTimeout()); - flow.setInstallHw(map.isInstallHw()); - flow.setInstructions(map.getInstructions()); - if(map.getFlowId()!= null) - flow.setKey(new FlowKey(new FlowId(map.getKey().getFlowId().getValue()))); - flow.setMatch(map.getMatch()); - flow.setOutGroup(map.getOutGroup()); - flow.setOutPort(map.getOutPort()); - flow.setPriority(map.getPriority()); - flow.setStrict(map.isStrict()); - flow.setTableId(tableId); - - Flow flowRule = flow.build(); - - FlowAndStatisticsMapListBuilder stats = new FlowAndStatisticsMapListBuilder(); - stats.setByteCount(map.getByteCount()); - stats.setPacketCount(map.getPacketCount()); - stats.setDuration(map.getDuration()); - - GenericStatistics flowStats = stats.build(); - - //Augment the data to the flow node - - FlowStatisticsBuilder flowStatistics = new FlowStatisticsBuilder(); - flowStatistics.setByteCount(flowStats.getByteCount()); - flowStatistics.setPacketCount(flowStats.getPacketCount()); - flowStatistics.setDuration(flowStats.getDuration()); - flowStatistics.setContainerName(map.getContainerName()); - flowStatistics.setBufferId(map.getBufferId()); - flowStatistics.setCookie(map.getCookie()); - flowStatistics.setCookieMask(map.getCookieMask()); - flowStatistics.setFlags(map.getFlags()); - flowStatistics.setFlowName(map.getFlowName()); - flowStatistics.setHardTimeout(map.getHardTimeout()); - flowStatistics.setIdleTimeout(map.getIdleTimeout()); - flowStatistics.setInstallHw(map.isInstallHw()); - flowStatistics.setInstructions(map.getInstructions()); - flowStatistics.setMatch(map.getMatch()); - flowStatistics.setOutGroup(map.getOutGroup()); - flowStatistics.setOutPort(map.getOutPort()); - flowStatistics.setPriority(map.getPriority()); - flowStatistics.setStrict(map.isStrict()); - flowStatistics.setTableId(tableId); - - flowStatisticsData.setFlowStatistics(flowStatistics.build()); - - logger.debug("Flow : {}",flowRule.toString()); - logger.debug("Statistics to augment : {}",flowStatistics.build().toString()); - - InstanceIdentifier
tableRef = InstanceIdentifier.builder(Nodes.class).child(Node.class, targetNodeKey) - .augmentation(FlowCapableNode.class).child(Table.class, new TableKey(tableId)).toInstance(); - - Table table= (Table)trans.readConfigurationData(tableRef); - - //TODO: Not a good way to do it, need to figure out better way. - //TODO: major issue in any alternate approach is that flow key is incrementally assigned - //to the flows stored in data store. - // Augment same statistics to all the matching masked flow - if(table != null){ - - for(Flow existingFlow : table.getFlow()){ - logger.debug("Existing flow in data store : {}",existingFlow.toString()); - if(FlowComparator.flowEquals(flowRule,existingFlow)){ - InstanceIdentifier flowRef = InstanceIdentifier.builder(Nodes.class).child(Node.class, targetNodeKey) - .augmentation(FlowCapableNode.class) - .child(Table.class, new TableKey(tableId)) - .child(Flow.class,existingFlow.getKey()).toInstance(); - flowBuilder.setKey(existingFlow.getKey()); - flowBuilder.addAugmentation(FlowStatisticsData.class, flowStatisticsData.build()); - logger.debug("Found matching flow in the datastore, augmenting statistics"); - foundOriginalFlow = true; - // Update entry with timestamp of latest response - flow.setKey(existingFlow.getKey()); - FlowEntry flowStatsEntry = new FlowEntry(tableId,flow.build()); - flowStatsUpdate.put(flowStatsEntry, expiryTime); - - trans.putOperationalData(flowRef, flowBuilder.build()); - } - } - } - - table = (Table)trans.readOperationalData(tableRef); - if(!foundOriginalFlow && table != null){ - - for(Flow existingFlow : table.getFlow()){ - FlowStatisticsData augmentedflowStatisticsData = existingFlow.getAugmentation(FlowStatisticsData.class); - if(augmentedflowStatisticsData != null){ - FlowBuilder existingOperationalFlow = new FlowBuilder(); - existingOperationalFlow.fieldsFrom(augmentedflowStatisticsData.getFlowStatistics()); - logger.debug("Existing unaccounted flow in operational data store : {}",existingFlow.toString()); - if(FlowComparator.flowEquals(flowRule,existingOperationalFlow.build())){ - InstanceIdentifier flowRef = InstanceIdentifier.builder(Nodes.class).child(Node.class, targetNodeKey) - .augmentation(FlowCapableNode.class) - .child(Table.class, new TableKey(tableId)) - .child(Flow.class,existingFlow.getKey()).toInstance(); - flowBuilder.setKey(existingFlow.getKey()); - flowBuilder.addAugmentation(FlowStatisticsData.class, flowStatisticsData.build()); - logger.debug("Found matching unaccounted flow in the operational datastore, augmenting statistics"); - foundOriginalFlow = true; - - // Update entry with timestamp of latest response - flow.setKey(existingFlow.getKey()); - FlowEntry flowStatsEntry = new FlowEntry(tableId,flow.build()); - flowStatsUpdate.put(flowStatsEntry, expiryTime); - trans.putOperationalData(flowRef, flowBuilder.build()); - break; - } - } - } - } - if(!foundOriginalFlow){ - String flowKey = "#UF$TABLE*"+Short.toString(tableId)+"*"+Integer.toString(this.unaccountedFlowsCounter); - this.unaccountedFlowsCounter++; - FlowKey newFlowKey = new FlowKey(new FlowId(flowKey)); - InstanceIdentifier flowRef = InstanceIdentifier.builder(Nodes.class).child(Node.class, targetNodeKey) - .augmentation(FlowCapableNode.class) - .child(Table.class, new TableKey(tableId)) - .child(Flow.class,newFlowKey).toInstance(); - flowBuilder.setKey(newFlowKey); - flowBuilder.addAugmentation(FlowStatisticsData.class, flowStatisticsData.build()); - logger.debug("Flow {} is not present in config data store, augmenting statistics as an unaccounted flow", - flowBuilder.build()); - - // Update entry with timestamp of latest response - flow.setKey(newFlowKey); - FlowEntry flowStatsEntry = new FlowEntry(tableId,flow.build()); - flowStatsUpdate.put(flowStatsEntry, expiryTime); - trans.putOperationalData(flowRef, flowBuilder.build()); - } - } - - trans.commit(); + flowStats.updateStats(list); } - private static Long getExpiryTime(){ - final long now = System.nanoTime(); - return now + TimeUnit.MILLISECONDS.toNanos(StatisticsProvider.STATS_COLLECTION_MILLIS * NUMBER_OF_WAIT_CYCLES); - } - - public synchronized void cleanStaleStatistics(){ + public synchronized void cleanStaleStatistics() { final DataModificationTransaction trans = dps.beginTransaction(); final long now = System.nanoTime(); - //Clean stale statistics related to group - for (Iterator> it = this.groupDescStatsUpdate.entrySet().iterator();it.hasNext();){ - Entry e = it.next(); - if (now > e.getValue()) { - cleanGroupStatsFromDataStore(trans, e.getKey()); - it.remove(); - } - } - - //Clean stale statistics related to meter - for (Iterator> it = this.meterConfigStatsUpdate.entrySet().iterator();it.hasNext();){ - Entry e = it.next(); - if (now > e.getValue()) { - cleanMeterStatsFromDataStore(trans, e.getKey()); - it.remove(); - } - } - - //Clean stale statistics related to flow - for (Iterator> it = this.flowStatsUpdate.entrySet().iterator();it.hasNext();){ - Entry e = it.next(); - if (now > e.getValue()) { - cleanFlowStatsFromDataStore(trans, e.getKey()); - it.remove(); - } - } - - //Clean stale statistics related to queue - for (Iterator> it = this.queuesStatsUpdate.entrySet().iterator();it.hasNext();){ - Entry e = it.next(); - if (now > e.getValue()) { - cleanQueueStatsFromDataStore(trans, e.getKey()); - it.remove(); - } - } + flowStats.cleanup(trans, now); + groupDescStats.cleanup(trans, now); + groupStats.cleanup(trans, now); + meterConfigStats.cleanup(trans, now); + meterStats.cleanup(trans, now); + nodeConnectorStats.cleanup(trans, now); + queueStats.cleanup(trans, now); trans.commit(); } - private void cleanQueueStatsFromDataStore(DataModificationTransaction trans, QueueEntry queueEntry) { - InstanceIdentifier queueRef - = InstanceIdentifier.builder(Nodes.class) - .child(Node.class, this.targetNodeKey) - .child(NodeConnector.class, new NodeConnectorKey(queueEntry.getNodeConnectorId())) - .augmentation(FlowCapableNodeConnector.class) - .child(Queue.class, new QueueKey(queueEntry.getQueueId())) - .augmentation(FlowCapableNodeConnectorQueueStatisticsData.class).toInstance(); - trans.removeOperationalData(queueRef); - } - - private void cleanFlowStatsFromDataStore(DataModificationTransaction trans, FlowEntry flowEntry) { - InstanceIdentifier flowRef - = InstanceIdentifier.builder(Nodes.class).child(Node.class, this.targetNodeKey) - .augmentation(FlowCapableNode.class) - .child(Table.class, new TableKey(flowEntry.getTableId())) - .child(Flow.class,flowEntry.getFlow().getKey()) - .augmentation(FlowStatisticsData.class).toInstance(); - trans.removeOperationalData(flowRef); - } - - private void cleanMeterStatsFromDataStore(DataModificationTransaction trans, MeterConfigStats meterConfigStats) { - InstanceIdentifierBuilder meterRef - = InstanceIdentifier.builder(Nodes.class).child(Node.class,this.targetNodeKey) - .augmentation(FlowCapableNode.class) - .child(Meter.class,new MeterKey(meterConfigStats.getMeterId())); - - InstanceIdentifier nodeMeterConfigStatsAugmentation = meterRef.augmentation(NodeMeterConfigStats.class).toInstance(); - trans.removeOperationalData(nodeMeterConfigStatsAugmentation); - - InstanceIdentifier nodeMeterStatisticsAugmentation = meterRef.augmentation(NodeMeterStatistics.class).toInstance(); - trans.removeOperationalData(nodeMeterStatisticsAugmentation); - } - - private void cleanGroupStatsFromDataStore(DataModificationTransaction trans, GroupDescStats groupDescStats) { - InstanceIdentifierBuilder groupRef - = InstanceIdentifier.builder(Nodes.class).child(Node.class,this.targetNodeKey) - .augmentation(FlowCapableNode.class) - .child(Group.class,new GroupKey(groupDescStats.getGroupId())); - - InstanceIdentifier nodeGroupDescStatsAugmentation = groupRef.augmentation(NodeGroupDescStats.class).toInstance(); - trans.removeOperationalData(nodeGroupDescStatsAugmentation); - - InstanceIdentifier nodeGroupStatisticsAugmentation = groupRef.augmentation(NodeGroupStatistics.class).toInstance(); - trans.removeOperationalData(nodeGroupStatisticsAugmentation); - } - @Override public void close() { // FIXME: cleanup any resources we hold (registrations, etc.) diff --git a/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/QueueStatsEntry.java b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/QueueStatsEntry.java new file mode 100644 index 0000000000..d1f2529de8 --- /dev/null +++ b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/QueueStatsEntry.java @@ -0,0 +1,62 @@ +/* + * Copyright IBM Corporation, 2013. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.controller.md.statistics.manager; + +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.queue.rev130925.QueueId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId; + +final class QueueStatsEntry { + private final NodeConnectorId nodeConnectorId; + private final QueueId queueId; + public QueueStatsEntry(NodeConnectorId ncId, QueueId queueId){ + this.nodeConnectorId = ncId; + this.queueId = queueId; + } + public NodeConnectorId getNodeConnectorId() { + return nodeConnectorId; + } + public QueueId getQueueId() { + return queueId; + } + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((nodeConnectorId == null) ? 0 : nodeConnectorId.hashCode()); + result = prime * result + ((queueId == null) ? 0 : queueId.hashCode()); + return result; + } + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (!(obj instanceof QueueStatsEntry)) { + return false; + } + QueueStatsEntry other = (QueueStatsEntry) obj; + if (nodeConnectorId == null) { + if (other.nodeConnectorId != null) { + return false; + } + } else if (!nodeConnectorId.equals(other.nodeConnectorId)) { + return false; + } + if (queueId == null) { + if (other.queueId != null) { + return false; + } + } else if (!queueId.equals(other.queueId)) { + return false; + } + return true; + } +} diff --git a/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/QueueStatsTracker.java b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/QueueStatsTracker.java new file mode 100644 index 0000000000..c2bde6ae60 --- /dev/null +++ b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/QueueStatsTracker.java @@ -0,0 +1,75 @@ +/* + * Copyright IBM Corporation, 2013. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.controller.md.statistics.manager; + +import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction; +import org.opendaylight.controller.sal.binding.api.data.DataProviderService; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector; +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.inventory.rev130819.node.NodeConnector; +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.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.slf4j.Logger; +import org.slf4j.LoggerFactory; + +final class QueueStatsTracker extends AbstractStatsTracker { + private static final Logger logger = LoggerFactory.getLogger(QueueStatsTracker.class); + + QueueStatsTracker(InstanceIdentifier nodeIdentifier, + DataProviderService dps, long lifetimeNanos) { + super(nodeIdentifier, dps, lifetimeNanos); + } + + @Override + protected void cleanupSingleStat(DataModificationTransaction trans, QueueStatsEntry item) { + InstanceIdentifier queueRef + = getNodeIdentifierBuilder().child(NodeConnector.class, new NodeConnectorKey(item.getNodeConnectorId())) + .augmentation(FlowCapableNodeConnector.class) + .child(Queue.class, new QueueKey(item.getQueueId())) + .augmentation(FlowCapableNodeConnectorQueueStatisticsData.class).build(); + trans.removeOperationalData(queueRef); + } + + @Override + protected QueueStatsEntry updateSingleStat(DataModificationTransaction trans, QueueIdAndStatisticsMap item) { + + QueueStatsEntry queueEntry = new QueueStatsEntry(item.getNodeConnectorId(), item.getQueueId()); + + FlowCapableNodeConnectorQueueStatisticsDataBuilder queueStatisticsDataBuilder = new FlowCapableNodeConnectorQueueStatisticsDataBuilder(); + + FlowCapableNodeConnectorQueueStatisticsBuilder queueStatisticsBuilder = new FlowCapableNodeConnectorQueueStatisticsBuilder(); + + queueStatisticsBuilder.fieldsFrom(item); + + queueStatisticsDataBuilder.setFlowCapableNodeConnectorQueueStatistics(queueStatisticsBuilder.build()); + + InstanceIdentifier queueRef = getNodeIdentifierBuilder().child(NodeConnector.class, new NodeConnectorKey(item.getNodeConnectorId())) + .augmentation(FlowCapableNodeConnector.class) + .child(Queue.class, new QueueKey(item.getQueueId())).toInstance(); + + QueueBuilder queueBuilder = new QueueBuilder(); + FlowCapableNodeConnectorQueueStatisticsData qsd = queueStatisticsDataBuilder.build(); + queueBuilder.addAugmentation(FlowCapableNodeConnectorQueueStatisticsData.class, qsd); + queueBuilder.setKey(new QueueKey(item.getQueueId())); + + logger.debug("Augmenting queue statistics {} of queue {} to port {}", + qsd, + item.getQueueId(), + item.getNodeConnectorId()); + + trans.putOperationalData(queueRef, queueBuilder.build()); + return queueEntry; + } +} 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 d8ee80a10f..e9d2356cf9 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 @@ -156,7 +156,9 @@ public class StatisticsProvider implements AutoCloseable { public void run() { try { // Send stats requests - statsRequestSender(); + for (NodeStatisticsHandler h : handlers.values()) { + sendStatisticsRequestsToNode(h); + } // Perform cleanup for(NodeStatisticsHandler nodeStatisticsAger : handlers.values()){ @@ -209,12 +211,6 @@ public class StatisticsProvider implements AutoCloseable { return dps.beginTransaction(); } - private void statsRequestSender() { - for (NodeStatisticsHandler h : handlers.values()) { - sendStatisticsRequestsToNode(h); - } - } - private void sendStatisticsRequestsToNode(final NodeStatisticsHandler h) { NodeKey targetNode = h.getTargetNodeKey(); spLogger.debug("Send requests for statistics collection to node : {}", targetNode.getId()); -- 2.36.6