blob: edd7db95bf984632c7609ec7860904e465fe9251 [file] [log] [blame]
alshabiba43aa252014-10-21 21:36:41 -07001package org.onlab.onos.net.statistic.impl;
2
3import org.apache.felix.scr.annotations.Activate;
4import org.apache.felix.scr.annotations.Component;
5import org.apache.felix.scr.annotations.Deactivate;
6import org.apache.felix.scr.annotations.Reference;
7import org.apache.felix.scr.annotations.ReferenceCardinality;
8import org.apache.felix.scr.annotations.Service;
9import org.onlab.onos.net.ConnectPoint;
10import org.onlab.onos.net.Link;
11import org.onlab.onos.net.Path;
alshabib2374fc92014-10-22 11:03:23 -070012
alshabib3d643ec2014-10-22 18:33:00 -070013import org.onlab.onos.net.flow.FlowEntry;
alshabiba43aa252014-10-21 21:36:41 -070014import org.onlab.onos.net.flow.FlowRule;
15import org.onlab.onos.net.flow.FlowRuleEvent;
16import org.onlab.onos.net.flow.FlowRuleListener;
17import org.onlab.onos.net.flow.FlowRuleService;
alshabib3d643ec2014-10-22 18:33:00 -070018import org.onlab.onos.net.statistic.DefaultLoad;
alshabiba43aa252014-10-21 21:36:41 -070019import org.onlab.onos.net.statistic.Load;
20import org.onlab.onos.net.statistic.StatisticService;
21import org.onlab.onos.net.statistic.StatisticStore;
22import org.slf4j.Logger;
alshabib3d643ec2014-10-22 18:33:00 -070023import java.util.Set;
24
alshabiba43aa252014-10-21 21:36:41 -070025import static org.slf4j.LoggerFactory.getLogger;
26
27/**
28 * Provides an implementation of the Statistic Service.
29 */
30@Component(immediate = true)
31@Service
32public class StatisticManager implements StatisticService {
33
34 private final Logger log = getLogger(getClass());
35
36 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
37 protected FlowRuleService flowRuleService;
38
39 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
40 protected StatisticStore statisticStore;
41
alshabib2374fc92014-10-22 11:03:23 -070042
alshabiba43aa252014-10-21 21:36:41 -070043 private final InternalFlowRuleListener listener = new InternalFlowRuleListener();
44
45 @Activate
46 public void activate() {
47 flowRuleService.addListener(listener);
48 log.info("Started");
alshabib2374fc92014-10-22 11:03:23 -070049
alshabiba43aa252014-10-21 21:36:41 -070050 }
51
52 @Deactivate
53 public void deactivate() {
54 flowRuleService.removeListener(listener);
55 log.info("Stopped");
56 }
57
58 @Override
59 public Load load(Link link) {
alshabib3d643ec2014-10-22 18:33:00 -070060 return load(link.src());
alshabiba43aa252014-10-21 21:36:41 -070061 }
62
63 @Override
64 public Load load(ConnectPoint connectPoint) {
alshabib3d643ec2014-10-22 18:33:00 -070065 return loadInternal(connectPoint);
alshabiba43aa252014-10-21 21:36:41 -070066 }
67
68 @Override
69 public Link max(Path path) {
alshabib46122d82014-10-23 09:05:31 -070070 if (path.links().isEmpty()) {
71 return null;
72 }
73 Load maxLoad = new DefaultLoad();
74 Link maxLink = null;
75 for (Link link : path.links()) {
76 Load load = loadInternal(link.src());
77 if (load.rate() > maxLoad.rate()) {
78 maxLoad = load;
79 maxLink = link;
80 }
81 }
82 return maxLink;
alshabiba43aa252014-10-21 21:36:41 -070083 }
84
85 @Override
86 public Link min(Path path) {
alshabib46122d82014-10-23 09:05:31 -070087 if (path.links().isEmpty()) {
88 return null;
89 }
90 Load minLoad = new DefaultLoad();
91 Link minLink = null;
92 for (Link link : path.links()) {
93 Load load = loadInternal(link.src());
94 if (load.rate() < minLoad.rate()) {
95 minLoad = load;
96 minLink = link;
97 }
98 }
99 return minLink;
alshabiba43aa252014-10-21 21:36:41 -0700100 }
101
102 @Override
103 public FlowRule highestHitter(ConnectPoint connectPoint) {
alshabib46122d82014-10-23 09:05:31 -0700104 Set<FlowEntry> hitters = statisticStore.getCurrentStatistic(connectPoint);
105 if (hitters.isEmpty()) {
106 return null;
107 }
108
109 FlowEntry max = hitters.iterator().next();
110 for (FlowEntry entry : hitters) {
111 if (entry.bytes() > max.bytes()) {
112 max = entry;
113 }
114 }
115 return max;
alshabiba43aa252014-10-21 21:36:41 -0700116 }
117
alshabib3d643ec2014-10-22 18:33:00 -0700118 private Load loadInternal(ConnectPoint connectPoint) {
119 Set<FlowEntry> current;
120 Set<FlowEntry> previous;
121 synchronized (statisticStore) {
122 current = statisticStore.getCurrentStatistic(connectPoint);
123 previous = statisticStore.getPreviousStatistic(connectPoint);
124 }
125 if (current == null || previous == null) {
126 return new DefaultLoad();
127 }
128 long currentAggregate = aggregate(current);
129 long previousAggregate = aggregate(previous);
130
131 return new DefaultLoad(currentAggregate, previousAggregate);
132 }
133
134 /**
135 * Aggregates a set of values.
136 * @param values the values to aggregate
137 * @return a long value
138 */
139 private long aggregate(Set<FlowEntry> values) {
140 long sum = 0;
141 for (FlowEntry f : values) {
142 sum += f.bytes();
143 }
144 return sum;
145 }
146
alshabiba43aa252014-10-21 21:36:41 -0700147 /**
148 * Internal flow rule event listener.
149 */
150 private class InternalFlowRuleListener implements FlowRuleListener {
151
152 @Override
153 public void event(FlowRuleEvent event) {
alshabib3d643ec2014-10-22 18:33:00 -0700154 FlowRule rule = event.subject();
155 switch (event.type()) {
156 case RULE_ADDED:
157 case RULE_UPDATED:
158 if (rule instanceof FlowEntry) {
159 statisticStore.addOrUpdateStatistic((FlowEntry) rule);
alshabib3d643ec2014-10-22 18:33:00 -0700160 }
161 break;
162 case RULE_ADD_REQUESTED:
alshabib3d643ec2014-10-22 18:33:00 -0700163 statisticStore.prepareForStatistics(rule);
164 break;
165 case RULE_REMOVE_REQUESTED:
alshabib3d643ec2014-10-22 18:33:00 -0700166 statisticStore.removeFromStatistics(rule);
167 break;
168 case RULE_REMOVED:
169 break;
170 default:
171 log.warn("Unknown flow rule event {}", event);
172 }
alshabiba43aa252014-10-21 21:36:41 -0700173 }
174 }
175
176
177}