blob: 3bff3c5de09f164bf581c6ba2bf043901dd84730 [file] [log] [blame]
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07001/*
2 * Copyright 2014 Open Networking Laboratory
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
alshabiba43aa252014-10-21 21:36:41 -070016package org.onlab.onos.net.statistic.impl;
17
18import org.apache.felix.scr.annotations.Activate;
19import org.apache.felix.scr.annotations.Component;
20import org.apache.felix.scr.annotations.Deactivate;
21import org.apache.felix.scr.annotations.Reference;
22import org.apache.felix.scr.annotations.ReferenceCardinality;
23import org.apache.felix.scr.annotations.Service;
24import org.onlab.onos.net.ConnectPoint;
25import org.onlab.onos.net.Link;
26import org.onlab.onos.net.Path;
alshabib2374fc92014-10-22 11:03:23 -070027
alshabib3d643ec2014-10-22 18:33:00 -070028import org.onlab.onos.net.flow.FlowEntry;
alshabiba43aa252014-10-21 21:36:41 -070029import org.onlab.onos.net.flow.FlowRule;
30import org.onlab.onos.net.flow.FlowRuleEvent;
31import org.onlab.onos.net.flow.FlowRuleListener;
32import org.onlab.onos.net.flow.FlowRuleService;
alshabib3d643ec2014-10-22 18:33:00 -070033import org.onlab.onos.net.statistic.DefaultLoad;
alshabiba43aa252014-10-21 21:36:41 -070034import org.onlab.onos.net.statistic.Load;
35import org.onlab.onos.net.statistic.StatisticService;
36import org.onlab.onos.net.statistic.StatisticStore;
37import org.slf4j.Logger;
alshabib3d643ec2014-10-22 18:33:00 -070038import java.util.Set;
39
alshabiba43aa252014-10-21 21:36:41 -070040import static org.slf4j.LoggerFactory.getLogger;
41
42/**
43 * Provides an implementation of the Statistic Service.
44 */
45@Component(immediate = true)
46@Service
47public class StatisticManager implements StatisticService {
48
49 private final Logger log = getLogger(getClass());
50
51 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
52 protected FlowRuleService flowRuleService;
53
54 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
55 protected StatisticStore statisticStore;
56
alshabib2374fc92014-10-22 11:03:23 -070057
alshabiba43aa252014-10-21 21:36:41 -070058 private final InternalFlowRuleListener listener = new InternalFlowRuleListener();
59
60 @Activate
61 public void activate() {
62 flowRuleService.addListener(listener);
63 log.info("Started");
alshabib2374fc92014-10-22 11:03:23 -070064
alshabiba43aa252014-10-21 21:36:41 -070065 }
66
67 @Deactivate
68 public void deactivate() {
69 flowRuleService.removeListener(listener);
70 log.info("Stopped");
71 }
72
73 @Override
74 public Load load(Link link) {
alshabib3d643ec2014-10-22 18:33:00 -070075 return load(link.src());
alshabiba43aa252014-10-21 21:36:41 -070076 }
77
78 @Override
79 public Load load(ConnectPoint connectPoint) {
alshabib3d643ec2014-10-22 18:33:00 -070080 return loadInternal(connectPoint);
alshabiba43aa252014-10-21 21:36:41 -070081 }
82
83 @Override
84 public Link max(Path path) {
alshabib46122d82014-10-23 09:05:31 -070085 if (path.links().isEmpty()) {
86 return null;
87 }
88 Load maxLoad = new DefaultLoad();
89 Link maxLink = null;
90 for (Link link : path.links()) {
91 Load load = loadInternal(link.src());
92 if (load.rate() > maxLoad.rate()) {
93 maxLoad = load;
94 maxLink = link;
95 }
96 }
97 return maxLink;
alshabiba43aa252014-10-21 21:36:41 -070098 }
99
100 @Override
101 public Link min(Path path) {
alshabib46122d82014-10-23 09:05:31 -0700102 if (path.links().isEmpty()) {
103 return null;
104 }
105 Load minLoad = new DefaultLoad();
106 Link minLink = null;
107 for (Link link : path.links()) {
108 Load load = loadInternal(link.src());
109 if (load.rate() < minLoad.rate()) {
110 minLoad = load;
111 minLink = link;
112 }
113 }
114 return minLink;
alshabiba43aa252014-10-21 21:36:41 -0700115 }
116
117 @Override
118 public FlowRule highestHitter(ConnectPoint connectPoint) {
alshabib46122d82014-10-23 09:05:31 -0700119 Set<FlowEntry> hitters = statisticStore.getCurrentStatistic(connectPoint);
120 if (hitters.isEmpty()) {
121 return null;
122 }
123
124 FlowEntry max = hitters.iterator().next();
125 for (FlowEntry entry : hitters) {
126 if (entry.bytes() > max.bytes()) {
127 max = entry;
128 }
129 }
130 return max;
alshabiba43aa252014-10-21 21:36:41 -0700131 }
132
alshabib3d643ec2014-10-22 18:33:00 -0700133 private Load loadInternal(ConnectPoint connectPoint) {
134 Set<FlowEntry> current;
135 Set<FlowEntry> previous;
136 synchronized (statisticStore) {
137 current = statisticStore.getCurrentStatistic(connectPoint);
138 previous = statisticStore.getPreviousStatistic(connectPoint);
139 }
140 if (current == null || previous == null) {
141 return new DefaultLoad();
142 }
143 long currentAggregate = aggregate(current);
144 long previousAggregate = aggregate(previous);
145
146 return new DefaultLoad(currentAggregate, previousAggregate);
147 }
148
149 /**
150 * Aggregates a set of values.
151 * @param values the values to aggregate
152 * @return a long value
153 */
154 private long aggregate(Set<FlowEntry> values) {
155 long sum = 0;
156 for (FlowEntry f : values) {
157 sum += f.bytes();
158 }
159 return sum;
160 }
161
alshabiba43aa252014-10-21 21:36:41 -0700162 /**
163 * Internal flow rule event listener.
164 */
165 private class InternalFlowRuleListener implements FlowRuleListener {
166
167 @Override
168 public void event(FlowRuleEvent event) {
alshabib3d643ec2014-10-22 18:33:00 -0700169 FlowRule rule = event.subject();
170 switch (event.type()) {
171 case RULE_ADDED:
172 case RULE_UPDATED:
173 if (rule instanceof FlowEntry) {
174 statisticStore.addOrUpdateStatistic((FlowEntry) rule);
alshabib3d643ec2014-10-22 18:33:00 -0700175 }
176 break;
177 case RULE_ADD_REQUESTED:
alshabib3d643ec2014-10-22 18:33:00 -0700178 statisticStore.prepareForStatistics(rule);
179 break;
180 case RULE_REMOVE_REQUESTED:
alshabib3d643ec2014-10-22 18:33:00 -0700181 statisticStore.removeFromStatistics(rule);
182 break;
183 case RULE_REMOVED:
184 break;
185 default:
186 log.warn("Unknown flow rule event {}", event);
187 }
alshabiba43aa252014-10-21 21:36:41 -0700188 }
189 }
190
191
192}