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;
12 import java.util.concurrent.ExecutionException;
14 import org.opendaylight.controller.md.sal.common.api.data.DataChangeEvent;
15 import org.opendaylight.controller.sal.binding.api.data.DataChangeListener;
16 import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
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.meters.Meter;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowStatisticsData;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.queues.Queue;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.NodeGroupDescStats;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.NodeGroupStatistics;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.NodeMeterConfigStats;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.NodeMeterStatistics;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.FlowCapableNodeConnectorQueueStatisticsData;
32 import org.opendaylight.yangtools.yang.binding.DataObject;
33 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
34 import org.slf4j.Logger;
35 import org.slf4j.LoggerFactory;
38 * Following are two main responsibilities of the class
39 * 1) Listen for the create changes in config data store for tree nodes (Flow,Group,Meter,Queue)
40 * and send statistics request to the switch to fetch the statistics
42 * 2)Listen for the remove changes in config data store for tree nodes (Flow,Group,Meter,Queue)
43 * and remove the relative statistics data from operational data store.
45 * @author avishnoi@in.ibm.com
48 public class StatisticsUpdateHandler implements DataChangeListener {
50 public final static Logger suhLogger = LoggerFactory.getLogger(StatisticsUpdateHandler.class);
52 private final StatisticsProvider statisticsManager;
54 public StatisticsUpdateHandler(final StatisticsProvider manager){
56 this.statisticsManager = manager;
59 public StatisticsProvider getStatisticsManager(){
60 return statisticsManager;
63 @SuppressWarnings("unchecked")
65 public void onDataChanged(DataChangeEvent<InstanceIdentifier<?>, DataObject> change) {
67 Map<InstanceIdentifier<?>, DataObject> nodeAdditions = change.getCreatedOperationalData();
68 for (InstanceIdentifier<? extends DataObject> dataObjectInstance : nodeAdditions.keySet()) {
69 DataObject dataObject = nodeAdditions.get(dataObjectInstance);
70 if(dataObject instanceof Node){
72 Node node = (Node) dataObject;
73 if(node.getAugmentation(FlowCapableNode.class) != null){
74 this.statisticsManager.sendStatisticsRequestsToNode(node);
79 Map<InstanceIdentifier<?>, DataObject> additions = change.getCreatedConfigurationData();
80 for (InstanceIdentifier<? extends DataObject> dataObjectInstance : additions.keySet()) {
81 DataObject dataObject = additions.get(dataObjectInstance);
82 InstanceIdentifier<Node> nodeII = dataObjectInstance.firstIdentifierOf(Node.class);
83 NodeRef nodeRef = new NodeRef(nodeII);
84 if(dataObject instanceof Flow){
85 Flow flow = (Flow) dataObject;
87 this.statisticsManager.sendFlowStatsFromTableRequest(nodeRef, flow);
88 } catch (InterruptedException | ExecutionException e) {
89 suhLogger.warn("Following exception occured while sending flow statistics request newly added flow: {}", e);
92 if(dataObject instanceof Meter){
94 this.statisticsManager.sendMeterConfigStatisticsRequest(nodeRef);
95 } catch (InterruptedException | ExecutionException e) {
96 suhLogger.warn("Following exception occured while sending meter statistics request for newly added meter: {}", e);
99 if(dataObject instanceof Group){
101 this.statisticsManager.sendGroupDescriptionRequest(nodeRef);
102 } catch (InterruptedException | ExecutionException e) {
103 suhLogger.warn("Following exception occured while sending group description request for newly added group: {}", e);
106 if(dataObject instanceof Queue){
107 Queue queue = (Queue) dataObject;
108 InstanceIdentifier<NodeConnector> nodeConnectorII = dataObjectInstance.firstIdentifierOf(NodeConnector.class);
109 NodeConnectorKey nodeConnectorKey = InstanceIdentifier.keyOf(nodeConnectorII);
111 this.statisticsManager.sendQueueStatsFromGivenNodeConnector(nodeRef, nodeConnectorKey.getId(), queue.getQueueId());
112 } catch (InterruptedException | ExecutionException e) {
113 suhLogger.warn("Following exception occured while sending queue statistics request for newly added group: {}", e);
118 Set<InstanceIdentifier<? extends DataObject>> removals = change.getRemovedConfigurationData();
119 for (InstanceIdentifier<? extends DataObject> dataObjectInstance : removals) {
120 DataObject dataObject = change.getOriginalConfigurationData().get(dataObjectInstance);
122 if(dataObject instanceof Flow){
123 InstanceIdentifier<Flow> flowII = (InstanceIdentifier<Flow>)dataObjectInstance;
124 InstanceIdentifier<?> flowAugmentation =
125 InstanceIdentifier.builder(flowII).augmentation(FlowStatisticsData.class).toInstance();
126 removeAugmentedOperationalData(flowAugmentation);
128 if(dataObject instanceof Meter){
129 InstanceIdentifier<Meter> meterII = (InstanceIdentifier<Meter>)dataObjectInstance;
131 InstanceIdentifier<?> nodeMeterConfigStatsAugmentation =
132 InstanceIdentifier.builder(meterII).augmentation(NodeMeterConfigStats.class).toInstance();
133 removeAugmentedOperationalData(nodeMeterConfigStatsAugmentation);
135 InstanceIdentifier<?> nodeMeterStatisticsAugmentation =
136 InstanceIdentifier.builder(meterII).augmentation(NodeMeterStatistics.class).toInstance();
137 removeAugmentedOperationalData(nodeMeterStatisticsAugmentation);
140 if(dataObject instanceof Group){
141 InstanceIdentifier<Group> groupII = (InstanceIdentifier<Group>)dataObjectInstance;
143 InstanceIdentifier<?> nodeGroupDescStatsAugmentation =
144 InstanceIdentifier.builder(groupII).augmentation(NodeGroupDescStats.class).toInstance();
145 removeAugmentedOperationalData(nodeGroupDescStatsAugmentation);
147 InstanceIdentifier<?> nodeGroupStatisticsAugmentation =
148 InstanceIdentifier.builder(groupII).augmentation(NodeGroupStatistics.class).toInstance();
149 removeAugmentedOperationalData(nodeGroupStatisticsAugmentation);
152 if(dataObject instanceof Queue){
153 InstanceIdentifier<Queue> queueII = (InstanceIdentifier<Queue>)dataObjectInstance;
155 InstanceIdentifier<?> nodeConnectorQueueStatisticsDataAugmentation =
156 InstanceIdentifier.builder(queueII).augmentation(FlowCapableNodeConnectorQueueStatisticsData.class).toInstance();
157 removeAugmentedOperationalData(nodeConnectorQueueStatisticsDataAugmentation);
162 private void removeAugmentedOperationalData(InstanceIdentifier<? extends DataObject> dataObjectInstance ){
163 if(dataObjectInstance != null){
164 DataModificationTransaction it = this.statisticsManager.startChange();
165 it.removeOperationalData(dataObjectInstance);