2 * Copyright IBM Corporation, 2013. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.controller.md.statistics.manager;
10 import java.util.Collection;
11 import java.util.List;
12 import java.util.concurrent.TimeUnit;
14 import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
15 import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
16 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
17 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table;
18 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableBuilder;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableKey;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.AggregateFlowStatisticsData;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.AggregateFlowStatisticsDataBuilder;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.aggregate.flow.statistics.AggregateFlowStatisticsBuilder;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.and.statistics.map.list.FlowAndStatisticsMapList;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.flow.table.and.statistics.map.FlowTableAndStatisticsMap;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.NodeGroupFeatures;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.NodeGroupFeaturesBuilder;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.group.features.GroupFeaturesBuilder;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupFeatures;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.desc.stats.reply.GroupDescStats;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.statistics.reply.GroupStats;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.NodeMeterFeatures;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.NodeMeterFeaturesBuilder;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.nodes.node.MeterFeaturesBuilder;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterFeatures;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.meter.config.stats.reply.MeterConfigStats;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.meter.statistics.reply.MeterStats;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.AggregateFlowStatistics;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.node.connector.statistics.and.port.number.map.NodeConnectorStatisticsAndPortNumberMap;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.queue.id.and.statistics.map.QueueIdAndStatisticsMap;
45 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
46 import org.slf4j.Logger;
47 import org.slf4j.LoggerFactory;
49 import com.google.common.base.Preconditions;
52 * This class handles the lifecycle of per-node statistics. It receives data
53 * from StatisticsListener, stores it in the data store and keeps track of
54 * when the data should be removed.
56 * @author avishnoi@in.ibm.com
58 public final class NodeStatisticsHandler implements AutoCloseable {
59 private static final Logger logger = LoggerFactory.getLogger(NodeStatisticsHandler.class);
60 private static final int NUMBER_OF_WAIT_CYCLES = 2;
62 private final InstanceIdentifier<Node> targetNodeIdentifier;
63 private final FlowStatsTracker flowStats;
64 private final FlowTableStatsTracker flowTableStats;
65 private final GroupDescStatsTracker groupDescStats;
66 private final GroupStatsTracker groupStats;
67 private final MeterConfigStatsTracker meterConfigStats;
68 private final MeterStatsTracker meterStats;
69 private final NodeConnectorStatsTracker nodeConnectorStats;
70 private final QueueStatsTracker queueStats;
71 private final DataProviderService dps;
72 private final NodeRef targetNodeRef;
73 private final NodeKey targetNodeKey;
75 public NodeStatisticsHandler(final DataProviderService dps, final NodeKey nodeKey) {
76 this.dps = Preconditions.checkNotNull(dps);
77 this.targetNodeKey = Preconditions.checkNotNull(nodeKey);
78 this.targetNodeIdentifier = InstanceIdentifier.builder(Nodes.class).child(Node.class, targetNodeKey).build();
79 this.targetNodeRef = new NodeRef(targetNodeIdentifier);
81 final long lifetimeNanos = TimeUnit.MILLISECONDS.toNanos(StatisticsProvider.STATS_COLLECTION_MILLIS * NUMBER_OF_WAIT_CYCLES);
82 flowStats = new FlowStatsTracker(targetNodeIdentifier, dps, lifetimeNanos);
83 flowTableStats = new FlowTableStatsTracker(targetNodeIdentifier, dps, lifetimeNanos);
84 groupDescStats = new GroupDescStatsTracker(targetNodeIdentifier, dps, lifetimeNanos);
85 groupStats = new GroupStatsTracker(targetNodeIdentifier, dps, lifetimeNanos);
86 meterConfigStats = new MeterConfigStatsTracker(targetNodeIdentifier, dps, lifetimeNanos);
87 meterStats = new MeterStatsTracker(targetNodeIdentifier, dps, lifetimeNanos);
88 nodeConnectorStats = new NodeConnectorStatsTracker(targetNodeIdentifier, dps, lifetimeNanos);
89 queueStats = new QueueStatsTracker(targetNodeIdentifier, dps, lifetimeNanos);
92 public NodeKey getTargetNodeKey() {
96 public Collection<TableKey> getKnownTables() {
97 return flowTableStats.getTables();
100 public InstanceIdentifier<Node> getTargetNodeIdentifier() {
101 return targetNodeIdentifier;
104 public NodeRef getTargetNodeRef() {
105 return targetNodeRef;
108 public synchronized void updateGroupDescStats(List<GroupDescStats> list) {
109 groupDescStats.updateStats(list);
112 public synchronized void updateGroupStats(List<GroupStats> list) {
113 groupStats.updateStats(list);
116 public synchronized void updateMeterConfigStats(List<MeterConfigStats> list) {
117 meterConfigStats.updateStats(list);
120 public synchronized void updateMeterStats(List<MeterStats> list) {
121 meterStats.updateStats(list);
124 public synchronized void updateQueueStats(List<QueueIdAndStatisticsMap> list) {
125 queueStats.updateStats(list);
128 public synchronized void updateFlowTableStats(List<FlowTableAndStatisticsMap> list) {
129 flowTableStats.updateStats(list);
132 public synchronized void updateNodeConnectorStats(List<NodeConnectorStatisticsAndPortNumberMap> list) {
133 nodeConnectorStats.updateStats(list);
136 public synchronized void updateAggregateFlowStats(Short tableId, AggregateFlowStatistics flowStats) {
137 if (tableId != null) {
138 final DataModificationTransaction trans = dps.beginTransaction();
140 InstanceIdentifier<Table> tableRef = InstanceIdentifier.builder(Nodes.class).child(Node.class, targetNodeKey)
141 .augmentation(FlowCapableNode.class).child(Table.class, new TableKey(tableId)).toInstance();
143 AggregateFlowStatisticsDataBuilder aggregateFlowStatisticsDataBuilder = new AggregateFlowStatisticsDataBuilder();
144 AggregateFlowStatisticsBuilder aggregateFlowStatisticsBuilder = new AggregateFlowStatisticsBuilder(flowStats);
146 aggregateFlowStatisticsDataBuilder.setAggregateFlowStatistics(aggregateFlowStatisticsBuilder.build());
148 logger.debug("Augment aggregate statistics: {} for table {} on Node {}",
149 aggregateFlowStatisticsBuilder.build().toString(),tableId,targetNodeKey);
151 TableBuilder tableBuilder = new TableBuilder();
152 tableBuilder.setKey(new TableKey(tableId));
153 tableBuilder.addAugmentation(AggregateFlowStatisticsData.class, aggregateFlowStatisticsDataBuilder.build());
154 trans.putOperationalData(tableRef, tableBuilder.build());
156 // FIXME: should we be tracking this data?
161 public synchronized void updateGroupFeatures(GroupFeatures notification) {
162 final DataModificationTransaction trans = dps.beginTransaction();
164 final NodeBuilder nodeData = new NodeBuilder();
165 nodeData.setKey(targetNodeKey);
167 NodeGroupFeaturesBuilder nodeGroupFeatures = new NodeGroupFeaturesBuilder();
168 GroupFeaturesBuilder groupFeatures = new GroupFeaturesBuilder(notification);
169 nodeGroupFeatures.setGroupFeatures(groupFeatures.build());
171 //Update augmented data
172 nodeData.addAugmentation(NodeGroupFeatures.class, nodeGroupFeatures.build());
173 trans.putOperationalData(targetNodeIdentifier, nodeData.build());
175 // FIXME: should we be tracking this data?
179 public synchronized void updateMeterFeatures(MeterFeatures features) {
180 final DataModificationTransaction trans = dps.beginTransaction();
182 final NodeBuilder nodeData = new NodeBuilder();
183 nodeData.setKey(targetNodeKey);
185 NodeMeterFeaturesBuilder nodeMeterFeatures = new NodeMeterFeaturesBuilder();
186 MeterFeaturesBuilder meterFeature = new MeterFeaturesBuilder(features);
187 nodeMeterFeatures.setMeterFeatures(meterFeature.build());
189 //Update augmented data
190 nodeData.addAugmentation(NodeMeterFeatures.class, nodeMeterFeatures.build());
191 trans.putOperationalData(targetNodeIdentifier, nodeData.build());
193 // FIXME: should we be tracking this data?
197 public synchronized void updateFlowStats(List<FlowAndStatisticsMapList> list) {
198 flowStats.updateStats(list);
201 public synchronized void cleanStaleStatistics() {
202 final DataModificationTransaction trans = dps.beginTransaction();
203 final long now = System.nanoTime();
205 flowStats.cleanup(trans, now);
206 groupDescStats.cleanup(trans, now);
207 groupStats.cleanup(trans, now);
208 meterConfigStats.cleanup(trans, now);
209 meterStats.cleanup(trans, now);
210 nodeConnectorStats.cleanup(trans, now);
211 queueStats.cleanup(trans, now);
217 public void close() {
218 // FIXME: cleanup any resources we hold (registrations, etc.)
219 logger.debug("Statistics handler for {} shut down", targetNodeKey.getId());