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.md.statistics.manager.MultipartMessageManager.StatsRequestType;
15 import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
16 import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
17 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
18 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableBuilder;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableKey;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.AggregateFlowStatisticsData;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.AggregateFlowStatisticsDataBuilder;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.aggregate.flow.statistics.AggregateFlowStatisticsBuilder;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.and.statistics.map.list.FlowAndStatisticsMapList;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.flow.table.and.statistics.map.FlowTableAndStatisticsMap;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev131103.TransactionAware;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev131103.TransactionId;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.NodeGroupFeatures;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.NodeGroupFeaturesBuilder;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.group.features.GroupFeaturesBuilder;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupFeatures;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.desc.stats.reply.GroupDescStats;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.statistics.reply.GroupStats;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.NodeMeterFeatures;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.NodeMeterFeaturesBuilder;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.nodes.node.MeterFeaturesBuilder;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterFeatures;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.meter.config.stats.reply.MeterConfigStats;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.meter.statistics.reply.MeterStats;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.AggregateFlowStatistics;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.node.connector.statistics.and.port.number.map.NodeConnectorStatisticsAndPortNumberMap;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.queue.id.and.statistics.map.QueueIdAndStatisticsMap;
48 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
49 import org.slf4j.Logger;
50 import org.slf4j.LoggerFactory;
52 import com.google.common.base.Preconditions;
55 * This class handles the lifecycle of per-node statistics. It receives data
56 * from StatisticsListener, stores it in the data store and keeps track of
57 * when the data should be removed.
59 * @author avishnoi@in.ibm.com
61 public final class NodeStatisticsHandler implements AutoCloseable {
62 private static final Logger logger = LoggerFactory.getLogger(NodeStatisticsHandler.class);
63 private static final int NUMBER_OF_WAIT_CYCLES = 2;
65 private final MultipartMessageManager msgManager = new MultipartMessageManager();
66 private final InstanceIdentifier<Node> targetNodeIdentifier;
67 private final FlowStatsTracker flowStats;
68 private final FlowTableStatsTracker flowTableStats;
69 private final GroupDescStatsTracker groupDescStats;
70 private final GroupStatsTracker groupStats;
71 private final MeterConfigStatsTracker meterConfigStats;
72 private final MeterStatsTracker meterStats;
73 private final NodeConnectorStatsTracker nodeConnectorStats;
74 private final QueueStatsTracker queueStats;
75 private final DataProviderService dps;
76 private final NodeRef targetNodeRef;
77 private final NodeKey targetNodeKey;
79 public NodeStatisticsHandler(final DataProviderService dps, final NodeKey nodeKey) {
80 this.dps = Preconditions.checkNotNull(dps);
81 this.targetNodeKey = Preconditions.checkNotNull(nodeKey);
82 this.targetNodeIdentifier = InstanceIdentifier.builder(Nodes.class).child(Node.class, targetNodeKey).build();
83 this.targetNodeRef = new NodeRef(targetNodeIdentifier);
85 final long lifetimeNanos = TimeUnit.MILLISECONDS.toNanos(StatisticsProvider.STATS_COLLECTION_MILLIS * NUMBER_OF_WAIT_CYCLES);
86 flowStats = new FlowStatsTracker(targetNodeIdentifier, dps, lifetimeNanos);
87 flowTableStats = new FlowTableStatsTracker(targetNodeIdentifier, dps, lifetimeNanos);
88 groupDescStats = new GroupDescStatsTracker(targetNodeIdentifier, dps, lifetimeNanos);
89 groupStats = new GroupStatsTracker(targetNodeIdentifier, dps, lifetimeNanos);
90 meterConfigStats = new MeterConfigStatsTracker(targetNodeIdentifier, dps, lifetimeNanos);
91 meterStats = new MeterStatsTracker(targetNodeIdentifier, dps, lifetimeNanos);
92 nodeConnectorStats = new NodeConnectorStatsTracker(targetNodeIdentifier, dps, lifetimeNanos);
93 queueStats = new QueueStatsTracker(targetNodeIdentifier, dps, lifetimeNanos);
96 public NodeKey getTargetNodeKey() {
100 public Collection<TableKey> getKnownTables() {
101 return flowTableStats.getTables();
104 public InstanceIdentifier<Node> getTargetNodeIdentifier() {
105 return targetNodeIdentifier;
108 public NodeRef getTargetNodeRef() {
109 return targetNodeRef;
112 public synchronized void updateGroupDescStats(TransactionAware transaction, Boolean more, List<GroupDescStats> list) {
113 if (msgManager.isExpectedTransaction(transaction, more)) {
114 groupDescStats.updateStats(list);
118 public synchronized void updateGroupStats(TransactionAware transaction, Boolean more, List<GroupStats> list) {
119 if (msgManager.isExpectedTransaction(transaction, more)) {
120 groupStats.updateStats(list);
124 public synchronized void updateMeterConfigStats(TransactionAware transaction, Boolean more, List<MeterConfigStats> list) {
125 if (msgManager.isExpectedTransaction(transaction, more)) {
126 meterConfigStats.updateStats(list);
130 public synchronized void updateMeterStats(TransactionAware transaction, Boolean more, List<MeterStats> list) {
131 if (msgManager.isExpectedTransaction(transaction, more)) {
132 meterStats.updateStats(list);
136 public synchronized void updateQueueStats(TransactionAware transaction, Boolean more, List<QueueIdAndStatisticsMap> list) {
137 if (msgManager.isExpectedTransaction(transaction, more)) {
138 queueStats.updateStats(list);
142 public synchronized void updateFlowTableStats(TransactionAware transaction, Boolean more, List<FlowTableAndStatisticsMap> list) {
143 if (msgManager.isExpectedTransaction(transaction, more)) {
144 flowTableStats.updateStats(list);
148 public synchronized void updateNodeConnectorStats(TransactionAware transaction, Boolean more, List<NodeConnectorStatisticsAndPortNumberMap> list) {
149 if (msgManager.isExpectedTransaction(transaction, more)) {
150 nodeConnectorStats.updateStats(list);
154 public synchronized void updateAggregateFlowStats(TransactionAware transaction, Boolean more, AggregateFlowStatistics flowStats) {
155 final Short tableId = msgManager.isExpectedTableTransaction(transaction, more);
156 if (tableId != null) {
157 final DataModificationTransaction trans = dps.beginTransaction();
158 InstanceIdentifier<Table> tableRef = InstanceIdentifier.builder(Nodes.class).child(Node.class, targetNodeKey)
159 .augmentation(FlowCapableNode.class).child(Table.class, new TableKey(tableId)).toInstance();
161 AggregateFlowStatisticsDataBuilder aggregateFlowStatisticsDataBuilder = new AggregateFlowStatisticsDataBuilder();
162 AggregateFlowStatisticsBuilder aggregateFlowStatisticsBuilder = new AggregateFlowStatisticsBuilder(flowStats);
164 aggregateFlowStatisticsDataBuilder.setAggregateFlowStatistics(aggregateFlowStatisticsBuilder.build());
166 logger.debug("Augment aggregate statistics: {} for table {} on Node {}",
167 aggregateFlowStatisticsBuilder.build().toString(),tableId,targetNodeKey);
169 TableBuilder tableBuilder = new TableBuilder();
170 tableBuilder.setKey(new TableKey(tableId));
171 tableBuilder.addAugmentation(AggregateFlowStatisticsData.class, aggregateFlowStatisticsDataBuilder.build());
172 trans.putOperationalData(tableRef, tableBuilder.build());
178 public synchronized void updateFlowStats(TransactionAware transaction, Boolean more, List<FlowAndStatisticsMapList> list) {
179 if (msgManager.isExpectedTransaction(transaction, more)) {
180 flowStats.updateStats(list);
184 public synchronized void updateGroupFeatures(GroupFeatures notification) {
185 final DataModificationTransaction trans = dps.beginTransaction();
187 final NodeBuilder nodeData = new NodeBuilder();
188 nodeData.setKey(targetNodeKey);
190 NodeGroupFeaturesBuilder nodeGroupFeatures = new NodeGroupFeaturesBuilder();
191 GroupFeaturesBuilder groupFeatures = new GroupFeaturesBuilder(notification);
192 nodeGroupFeatures.setGroupFeatures(groupFeatures.build());
194 //Update augmented data
195 nodeData.addAugmentation(NodeGroupFeatures.class, nodeGroupFeatures.build());
196 trans.putOperationalData(targetNodeIdentifier, nodeData.build());
198 // FIXME: should we be tracking this data?
202 public synchronized void updateMeterFeatures(MeterFeatures features) {
203 final DataModificationTransaction trans = dps.beginTransaction();
205 final NodeBuilder nodeData = new NodeBuilder();
206 nodeData.setKey(targetNodeKey);
208 NodeMeterFeaturesBuilder nodeMeterFeatures = new NodeMeterFeaturesBuilder();
209 MeterFeaturesBuilder meterFeature = new MeterFeaturesBuilder(features);
210 nodeMeterFeatures.setMeterFeatures(meterFeature.build());
212 //Update augmented data
213 nodeData.addAugmentation(NodeMeterFeatures.class, nodeMeterFeatures.build());
214 trans.putOperationalData(targetNodeIdentifier, nodeData.build());
216 // FIXME: should we be tracking this data?
220 public synchronized void cleanStaleStatistics() {
221 final DataModificationTransaction trans = dps.beginTransaction();
222 final long now = System.nanoTime();
224 flowStats.cleanup(trans, now);
225 groupDescStats.cleanup(trans, now);
226 groupStats.cleanup(trans, now);
227 meterConfigStats.cleanup(trans, now);
228 meterStats.cleanup(trans, now);
229 nodeConnectorStats.cleanup(trans, now);
230 queueStats.cleanup(trans, now);
231 msgManager.cleanStaleTransactionIds();
237 public void close() {
238 // FIXME: cleanup any resources we hold (registrations, etc.)
239 logger.debug("Statistics handler for {} shut down", targetNodeKey.getId());
242 // FIXME: this should be private
243 public synchronized void recordExpectedTransaction(TransactionId transactionId, StatsRequestType reqType) {
244 msgManager.recordExpectedTransaction(transactionId, reqType);
247 // FIXME: this should be private
248 public synchronized void recordExpectedTableTransaction(TransactionId transactionId, Short tableId) {
249 msgManager.recordExpectedTableTransaction(transactionId, StatsRequestType.AGGR_FLOW, tableId);