*/
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.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;
*
* @author avishnoi@in.ibm.com
*/
-public class NodeStatisticsHandler {
+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<FlowEntry,Long> flowStatsUpdate = new HashMap<>();
private final Map<QueueEntry,Long> queuesStatsUpdate = new HashMap<>();
private final InstanceIdentifier<Node> targetNodeIdentifier;
- private final StatisticsProvider statisticsProvider;
+ private final DataProviderService dps;
+ private final NodeRef targetNodeRef;
private final NodeKey targetNodeKey;
+ private Collection<TableKey> knownTables = Collections.emptySet();
private int unaccountedFlowsCounter = 1;
- public NodeStatisticsHandler(StatisticsProvider statisticsProvider, NodeKey nodeKey){
- this.statisticsProvider = Preconditions.checkNotNull(statisticsProvider);
+ 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);
}
- public class FlowEntry {
+ private static class FlowEntry {
private final Short tableId;
private final Flow flow;
public int hashCode() {
final int prime = 31;
int result = 1;
- result = prime * result + getOuterType().hashCode();
result = prime * result + ((flow == null) ? 0 : flow.hashCode());
result = prime * result + ((tableId == null) ? 0 : tableId.hashCode());
return result;
if (getClass() != obj.getClass())
return false;
FlowEntry other = (FlowEntry) obj;
- if (!getOuterType().equals(other.getOuterType()))
- return false;
if (flow == null) {
if (other.flow != null)
return false;
return false;
return true;
}
-
- private NodeStatisticsHandler getOuterType() {
- return NodeStatisticsHandler.this;
- }
}
- private static final class QueueEntry{
+ private static final class QueueEntry {
private final NodeConnectorId nodeConnectorId;
private final QueueId queueId;
public QueueEntry(NodeConnectorId ncId, QueueId queueId){
return targetNodeKey;
}
+ public Collection<TableKey> getKnownTables() {
+ return knownTables;
+ }
+
+ public InstanceIdentifier<Node> getTargetNodeIdentifier() {
+ return targetNodeIdentifier;
+ }
+
+ public NodeRef getTargetNodeRef() {
+ return targetNodeRef;
+ }
+
public synchronized void updateGroupDescStats(List<GroupDescStats> list){
final Long expiryTime = getExpiryTime();
- final DataModificationTransaction trans = statisticsProvider.startChange();
+ final DataModificationTransaction trans = dps.beginTransaction();
for (GroupDescStats groupDescStats : list) {
GroupBuilder groupBuilder = new GroupBuilder();
trans.commit();
}
-
public synchronized void updateGroupStats(List<GroupStats> list) {
- final DataModificationTransaction trans = statisticsProvider.startChange();
+ final DataModificationTransaction trans = dps.beginTransaction();
for(GroupStats groupStats : list) {
GroupBuilder groupBuilder = new GroupBuilder();
public synchronized void updateMeterConfigStats(List<MeterConfigStats> list) {
final Long expiryTime = getExpiryTime();
- final DataModificationTransaction trans = statisticsProvider.startChange();
+ final DataModificationTransaction trans = dps.beginTransaction();
for(MeterConfigStats meterConfigStats : list) {
MeterBuilder meterBuilder = new MeterBuilder();
public synchronized void updateMeterStats(List<MeterStats> list) {
- final DataModificationTransaction trans = statisticsProvider.startChange();
+ final DataModificationTransaction trans = dps.beginTransaction();
for(MeterStats meterStats : list) {
MeterBuilder meterBuilder = new MeterBuilder();
public synchronized void updateQueueStats(List<QueueIdAndStatisticsMap> list) {
final Long expiryTime = getExpiryTime();
- final DataModificationTransaction trans = statisticsProvider.startChange();
+ final DataModificationTransaction trans = dps.beginTransaction();
for (QueueIdAndStatisticsMap swQueueStats : list) {
}
public synchronized void updateFlowTableStats(List<FlowTableAndStatisticsMap> list) {
- final DataModificationTransaction trans = statisticsProvider.startChange();
+ final DataModificationTransaction trans = dps.beginTransaction();
+ final Set<TableKey> knownTables = new HashSet<>(list.size());
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();
+ final FlowTableStatistics stats = new FlowTableStatisticsBuilder(ftStats).build();
statisticsDataBuilder.setFlowTableStatistics(stats);
logger.debug("Augment flow table statistics: {} for table {} on Node {}",
tableBuilder.addAugmentation(FlowTableStatisticsData.class, statisticsDataBuilder.build());
trans.putOperationalData(tableRef, tableBuilder.build());
- // FIXME: should we be tracking this data?
+ knownTables.add(tableBuilder.getKey());
}
+ this.knownTables = Collections.unmodifiableCollection(knownTables);
trans.commit();
}
public synchronized void updateNodeConnectorStats(List<NodeConnectorStatisticsAndPortNumberMap> list) {
- final DataModificationTransaction trans = statisticsProvider.startChange();
+ final DataModificationTransaction trans = dps.beginTransaction();
for(NodeConnectorStatisticsAndPortNumberMap portStats : list) {
public synchronized void updateAggregateFlowStats(Short tableId, AggregateFlowStatistics flowStats) {
if (tableId != null) {
- final DataModificationTransaction trans = statisticsProvider.startChange();
+ final DataModificationTransaction trans = dps.beginTransaction();
InstanceIdentifier<Table> tableRef = InstanceIdentifier.builder(Nodes.class).child(Node.class, targetNodeKey)
}
public synchronized void updateGroupFeatures(GroupFeatures notification) {
- final DataModificationTransaction trans = statisticsProvider.startChange();
+ final DataModificationTransaction trans = dps.beginTransaction();
final NodeBuilder nodeData = new NodeBuilder();
nodeData.setKey(targetNodeKey);
}
public synchronized void updateMeterFeatures(MeterFeatures features) {
- final DataModificationTransaction trans = statisticsProvider.startChange();
+ final DataModificationTransaction trans = dps.beginTransaction();
final NodeBuilder nodeData = new NodeBuilder();
nodeData.setKey(targetNodeKey);
public synchronized void updateFlowStats(List<FlowAndStatisticsMapList> list) {
final Long expiryTime = getExpiryTime();
- final DataModificationTransaction trans = statisticsProvider.startChange();
+ final DataModificationTransaction trans = dps.beginTransaction();
for(FlowAndStatisticsMapList map : list) {
short tableId = map.getTableId();
private static Long getExpiryTime(){
final long now = System.nanoTime();
- return now + TimeUnit.MILLISECONDS.toNanos(StatisticsProvider.STATS_THREAD_EXECUTION_TIME * NUMBER_OF_WAIT_CYCLES);
+ return now + TimeUnit.MILLISECONDS.toNanos(StatisticsProvider.STATS_COLLECTION_MILLIS * NUMBER_OF_WAIT_CYCLES);
}
public synchronized void cleanStaleStatistics(){
- final DataModificationTransaction trans = this.statisticsProvider.startChange();
+ final DataModificationTransaction trans = dps.beginTransaction();
final long now = System.nanoTime();
//Clean stale statistics related to group
InstanceIdentifier<?> nodeGroupStatisticsAugmentation = groupRef.augmentation(NodeGroupStatistics.class).toInstance();
trans.removeOperationalData(nodeGroupStatisticsAugmentation);
}
+
+ @Override
+ public void close() {
+ // FIXME: cleanup any resources we hold (registrations, etc.)
+ logger.debug("Statistics handler for {} shut down", targetNodeKey.getId());
+ }
}