sangho
Committed by Gerrit Code Review

ONOS-1440: Implements port statistics feature, which polls port statistics of al…

…l devices every 10 seconds. Also, implemented a simple portstats ONOS CLI command to show the statistics.

Change-Id: I57e046ae2c2463a58b478d3a5b523422cde71ba2
1 +package org.onosproject.cli.net;
2 +
3 +/*
4 + * Copyright 2015 Open Networking Laboratory
5 + *
6 + * Licensed under the Apache License, Version 2.0 (the "License");
7 + * you may not use this file except in compliance with the License.
8 + * You may obtain a copy of the License at
9 + *
10 + * http://www.apache.org/licenses/LICENSE-2.0
11 + *
12 + * Unless required by applicable law or agreed to in writing, software
13 + * distributed under the License is distributed on an "AS IS" BASIS,
14 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 + * See the License for the specific language governing permissions and
16 + * limitations under the License.
17 + */
18 +
19 +import org.apache.karaf.shell.commands.Command;
20 +import org.onosproject.cli.AbstractShellCommand;
21 +import org.onosproject.net.DeviceId;
22 +import org.onosproject.net.device.DeviceService;
23 +import org.onosproject.net.device.PortStatistics;
24 +
25 +/**
26 + * Lists port statistic of all ports in the system.
27 + */
28 +@Command(scope = "onos", name = "portstats",
29 + description = "Lists statistics of all ports in the system")
30 +public class DevicePortStatsCommand extends AbstractShellCommand {
31 +
32 + private static final String FORMAT =
33 + " port=%s, pktRx=%s, pktTx=%s, bytesRx=%s, bytesTx=%s, pktRxDrp=%s, pktTxDrp=%s, Dur=%s";
34 +
35 + @Override
36 + protected void execute() {
37 + DeviceService deviceService = get(DeviceService.class);
38 +
39 + deviceService.getDevices().forEach(d ->
40 + printPortStats(d.id(), deviceService.getPortStatistics(d.id()))
41 + );
42 + }
43 +
44 + private void printPortStats(DeviceId deviceId, Iterable<PortStatistics> portStats) {
45 + print("deviceId=%s", deviceId);
46 + for (PortStatistics stat : portStats) {
47 + print(FORMAT, stat.port(), stat.packetsReceived(), stat.packetsSent(), stat.bytesReceived(),
48 + stat.bytesSent(), stat.packetsRxDropped(), stat.packetsTxDropped(), stat.durationSec());
49 + }
50 + }
51 +}
...@@ -280,6 +280,10 @@ ...@@ -280,6 +280,10 @@
280 </command> 280 </command>
281 281
282 <command> 282 <command>
283 + <action class="org.onosproject.cli.net.DevicePortStatsCommand"/>
284 + </command>
285 +
286 + <command>
283 <action class="org.onosproject.cli.net.FlowsListCommand"/> 287 <action class="org.onosproject.cli.net.FlowsListCommand"/>
284 <completers> 288 <completers>
285 <ref component-id="flowRuleStatusCompleter"/> 289 <ref component-id="flowRuleStatusCompleter"/>
......
1 +/*
2 + * Copyright 2015 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 + */
16 +package org.onosproject.net.device;
17 +
18 +import org.onosproject.net.DeviceId;
19 +
20 +/**
21 + * Default implementation of immutable port statistics.
22 + */
23 +public final class DefaultPortStatistics implements PortStatistics {
24 +
25 + private final DeviceId deviceId;
26 + private final int port;
27 + private final long packetsReceived;
28 + private final long packetsSent;
29 + private final long bytesReceived;
30 + private final long bytesSent;
31 + private final long packetsRxDropped;
32 + private final long packetsTxDropped;
33 + private final long packetsRxErrors;
34 + private final long packetsTxErrors;
35 + private final long durationSec;
36 + private final long durationNano;
37 +
38 + private DefaultPortStatistics(DeviceId deviceId,
39 + int port,
40 + long packetsReceived,
41 + long packetsSent,
42 + long bytesReceived,
43 + long bytesSent,
44 + long packetsRxDropped,
45 + long packetsTxDropped,
46 + long packetsRxErrors,
47 + long packetsTxErrors,
48 + long durationSec,
49 + long durationNano) {
50 + this.deviceId = deviceId;
51 + this.port = port;
52 + this.packetsReceived = packetsReceived;
53 + this.packetsSent = packetsSent;
54 + this.bytesReceived = bytesReceived;
55 + this.bytesSent = bytesSent;
56 + this.packetsRxDropped = packetsRxDropped;
57 + this.packetsTxDropped = packetsTxDropped;
58 + this.packetsRxErrors = packetsRxErrors;
59 + this.packetsTxErrors = packetsTxErrors;
60 + this.durationSec = durationSec;
61 + this.durationNano = durationNano;
62 + }
63 +
64 + /**
65 + * Creates a builder for DefaultPortStatistics object.
66 + *
67 + * @return builder object for DefaultPortStatistics object
68 + */
69 + public static DefaultPortStatistics.Builder builder() {
70 + return new Builder();
71 + }
72 +
73 + @Override
74 + public int port() {
75 + return this.port;
76 + }
77 +
78 + @Override
79 + public long packetsReceived() {
80 + return this.packetsReceived;
81 + }
82 +
83 + @Override
84 + public long packetsSent() {
85 + return this.packetsSent;
86 + }
87 +
88 + @Override
89 + public long bytesReceived() {
90 + return this.bytesReceived;
91 + }
92 +
93 + @Override
94 + public long bytesSent() {
95 + return this.bytesSent;
96 + }
97 +
98 + @Override
99 + public long packetsRxDropped() {
100 + return this.packetsRxDropped;
101 + }
102 +
103 + @Override
104 + public long packetsTxDropped() {
105 + return this.packetsTxDropped;
106 + }
107 +
108 + @Override
109 + public long packetsRxErrors() {
110 + return this.packetsRxErrors;
111 + }
112 +
113 + @Override
114 + public long packetsTxErrors() {
115 + return this.packetsTxErrors;
116 + }
117 +
118 + @Override
119 + public long durationSec() {
120 + return this.durationSec;
121 + }
122 +
123 + @Override
124 + public long durationNano() {
125 + return this.durationNano;
126 + }
127 +
128 + @Override
129 + public String toString() {
130 + StringBuilder sb = new StringBuilder("device: " + deviceId + ", ");
131 +
132 + sb.append("port: " + this.port + ", ");
133 + sb.append("pktRx: " + this.packetsReceived + ", ");
134 + sb.append("pktTx: " + this.packetsSent + ", ");
135 + sb.append("byteRx: " + this.bytesReceived + ", ");
136 + sb.append("byteTx: " + this.bytesSent + ", ");
137 + sb.append("pktRxErr: " + this.packetsRxErrors + ", ");
138 + sb.append("pktTxErr: " + this.packetsTxErrors + ", ");
139 + sb.append("pktRxDrp: " + this.packetsRxDropped + ", ");
140 + sb.append("pktTxDrp: " + this.packetsTxDropped);
141 +
142 + return sb.toString();
143 + }
144 +
145 + public static final class Builder {
146 +
147 + DeviceId deviceId;
148 + int port;
149 + long packetsReceived;
150 + long packetsSent;
151 + long bytesReceived;
152 + long bytesSent;
153 + long packetsRxDropped;
154 + long packetsTxDropped;
155 + long packetsRxErrors;
156 + long packetsTxErrors;
157 + long durationSec;
158 + long durationNano;
159 +
160 + private Builder() {
161 +
162 + }
163 +
164 + /**
165 + * Sets port number.
166 + *
167 + * @param port port number
168 + * @return builder object
169 + */
170 + public Builder setPort(int port) {
171 + this.port = port;
172 +
173 + return this;
174 + }
175 +
176 + /**
177 + * Sets the device identifier.
178 + *
179 + * @param deviceId device identifier
180 + * @return builder object
181 + */
182 + public Builder setDeviceId(DeviceId deviceId) {
183 + this.deviceId = deviceId;
184 +
185 + return this;
186 + }
187 +
188 + /**
189 + * Sets the number of packet received.
190 + *
191 + * @param packets number of packets received
192 + * @return builder object
193 + */
194 + public Builder setPacketsReceived(long packets) {
195 + packetsReceived = packets;
196 +
197 + return this;
198 + }
199 +
200 + /**
201 + * Sets the number of packets sent.
202 + *
203 + * @param packets number of packets sent
204 + * @return builder object
205 + */
206 + public Builder setPacketsSent(long packets) {
207 + packetsSent = packets;
208 +
209 + return this;
210 + }
211 +
212 + /**
213 + * Sets the number of received bytes.
214 + *
215 + * @param bytes number of received bytes.
216 + * @return builder object
217 + */
218 + public Builder setBytesReceived(long bytes) {
219 + bytesReceived = bytes;
220 +
221 + return this;
222 + }
223 +
224 + /**
225 + * Sets the number of sent bytes.
226 + *
227 + * @param bytes number of sent bytes
228 + * @return builder object
229 + */
230 + public Builder setBytesSent(long bytes) {
231 + bytesSent = bytes;
232 +
233 + return this;
234 + }
235 +
236 + /**
237 + * Sets the number of packets dropped by RX.
238 + *
239 + * @param packets number of packets dropped by RX
240 + * @return builder object
241 + */
242 + public Builder setPacketsRxDropped(long packets) {
243 + packetsRxDropped = packets;
244 +
245 + return this;
246 + }
247 +
248 + /**
249 + * Sets the number of packets dropped by TX.
250 + *
251 + * @param packets
252 + * @return builder object
253 + */
254 + public Builder setPacketsTxDropped(long packets) {
255 + packetsTxDropped = packets;
256 +
257 + return this;
258 + }
259 +
260 + /**
261 + * Sets the number of receive errors.
262 + *
263 + * @param packets number of receive errors
264 + * @return builder object
265 + */
266 + public Builder setPacketsRxErrors(long packets) {
267 + packetsRxErrors = packets;
268 +
269 + return this;
270 + }
271 +
272 + /**
273 + * Sets the number of transmit errors.
274 + *
275 + * @param packets number of transmit errors
276 + * @return builder object
277 + */
278 + public Builder setPacketsTxErrors(long packets) {
279 + packetsTxErrors = packets;
280 +
281 + return this;
282 + }
283 +
284 + /**
285 + * Sets the time port has been alive in seconds.
286 + *
287 + * @param sec time port has been alive in seconds
288 + * @return builder object
289 + */
290 + public Builder setDurationSec(long sec) {
291 + durationSec = sec;
292 +
293 + return this;
294 + }
295 +
296 + /**
297 + * Sets the time port has been alive in nano seconds.
298 + *
299 + * @param nano time port has been alive in nano seconds
300 + * @return builder object
301 + */
302 + public Builder setDurationNano(long nano) {
303 + durationNano = nano;
304 +
305 + return this;
306 + }
307 +
308 + /**
309 + * Creates a PortStatistics object.
310 + *
311 + * @return DefaultPortStatistics object
312 + */
313 + public DefaultPortStatistics build() {
314 + return new DefaultPortStatistics(
315 + deviceId,
316 + port,
317 + packetsReceived,
318 + packetsSent,
319 + bytesReceived,
320 + bytesSent,
321 + packetsRxDropped,
322 + packetsTxDropped,
323 + packetsRxErrors,
324 + packetsTxErrors,
325 + durationSec,
326 + durationNano);
327 + }
328 +
329 + }
330 +}
...@@ -72,7 +72,12 @@ public class DeviceEvent extends AbstractEvent<DeviceEvent.Type, Device> { ...@@ -72,7 +72,12 @@ public class DeviceEvent extends AbstractEvent<DeviceEvent.Type, Device> {
72 /** 72 /**
73 * Signifies that a port has been removed. 73 * Signifies that a port has been removed.
74 */ 74 */
75 - PORT_REMOVED 75 + PORT_REMOVED,
76 +
77 + /*
78 + * Signifies that port statistics has been updated.
79 + */
80 + PORT_STATS_UPDATED
76 } 81 }
77 82
78 /** 83 /**
......
...@@ -19,6 +19,7 @@ import org.onosproject.net.DeviceId; ...@@ -19,6 +19,7 @@ import org.onosproject.net.DeviceId;
19 import org.onosproject.net.MastershipRole; 19 import org.onosproject.net.MastershipRole;
20 import org.onosproject.net.provider.ProviderService; 20 import org.onosproject.net.provider.ProviderService;
21 21
22 +import java.util.Collection;
22 import java.util.List; 23 import java.util.List;
23 24
24 /** 25 /**
...@@ -70,4 +71,12 @@ public interface DeviceProviderService extends ProviderService<DeviceProvider> { ...@@ -70,4 +71,12 @@ public interface DeviceProviderService extends ProviderService<DeviceProvider> {
70 */ 71 */
71 void receivedRoleReply(DeviceId deviceId, MastershipRole requested, MastershipRole response); 72 void receivedRoleReply(DeviceId deviceId, MastershipRole requested, MastershipRole response);
72 73
74 + /**
75 + * Sends statistics about all ports of a device.
76 + *
77 + * @param deviceId identity of the device
78 + * @param portStatistics list of device port statistics
79 + */
80 + void updatePortStatistics(DeviceId deviceId, Collection<PortStatistics> portStatistics);
81 +
73 } 82 }
......
...@@ -78,6 +78,14 @@ public interface DeviceService { ...@@ -78,6 +78,14 @@ public interface DeviceService {
78 List<Port> getPorts(DeviceId deviceId); 78 List<Port> getPorts(DeviceId deviceId);
79 79
80 /** 80 /**
81 + * Returns the list of port statistics associated with the device.
82 + *
83 + * @param deviceId device identitifer
84 + * @return list of port statistics
85 + */
86 + List<PortStatistics> getPortStatistics(DeviceId deviceId);
87 +
88 + /**
81 * Returns the port with the specified number and hosted by the given device. 89 * Returns the port with the specified number and hosted by the given device.
82 * 90 *
83 * @param deviceId device identifier 91 * @param deviceId device identifier
......
...@@ -22,6 +22,7 @@ import org.onosproject.net.PortNumber; ...@@ -22,6 +22,7 @@ import org.onosproject.net.PortNumber;
22 import org.onosproject.net.provider.ProviderId; 22 import org.onosproject.net.provider.ProviderId;
23 import org.onosproject.store.Store; 23 import org.onosproject.store.Store;
24 24
25 +import java.util.Collection;
25 import java.util.List; 26 import java.util.List;
26 27
27 /** 28 /**
...@@ -114,6 +115,26 @@ public interface DeviceStore extends Store<DeviceEvent, DeviceStoreDelegate> { ...@@ -114,6 +115,26 @@ public interface DeviceStore extends Store<DeviceEvent, DeviceStoreDelegate> {
114 List<Port> getPorts(DeviceId deviceId); 115 List<Port> getPorts(DeviceId deviceId);
115 116
116 /** 117 /**
118 + * Updates the port statistics of the specified device using the give port
119 + * statistics.
120 + *
121 + * @param providerId provider identifier
122 + * @param deviceId device identifier
123 + * @param portStats list of port statistics
124 + * @return ready to send event describing what occurred;
125 + */
126 + DeviceEvent updatePortStatistics(ProviderId providerId, DeviceId deviceId,
127 + Collection<PortStatistics> portStats);
128 +
129 + /**
130 + * Returns the list of port statistics of the specified device.
131 + *
132 + * @param deviceId device identifier
133 + * @return list of port statistics of all ports of the device
134 + */
135 + List<PortStatistics> getPortStatistics(DeviceId deviceId);
136 +
137 + /**
117 * Returns the specified device port. 138 * Returns the specified device port.
118 * 139 *
119 * @param deviceId device identifier 140 * @param deviceId device identifier
...@@ -137,4 +158,6 @@ public interface DeviceStore extends Store<DeviceEvent, DeviceStoreDelegate> { ...@@ -137,4 +158,6 @@ public interface DeviceStore extends Store<DeviceEvent, DeviceStoreDelegate> {
137 * @return null if no such device, or was forwarded to remove master 158 * @return null if no such device, or was forwarded to remove master
138 */ 159 */
139 DeviceEvent removeDevice(DeviceId deviceId); 160 DeviceEvent removeDevice(DeviceId deviceId);
161 +
162 +
140 } 163 }
......
1 +/*
2 + * Copyright 2015 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 + */
16 +package org.onosproject.net.device;
17 +
18 +/**
19 + * Statistics of a port.
20 + */
21 +public interface PortStatistics {
22 +
23 + /**
24 + * Returns the port number.
25 + *
26 + * @return port number
27 + */
28 + public int port();
29 +
30 + /**
31 + * Returns the number of packets received.
32 + *
33 + * @return the number of packets received
34 + */
35 + public long packetsReceived();
36 +
37 + /**
38 + * Returns the number of packets sent.
39 + *
40 + * @return the number of packets sent
41 + */
42 + public long packetsSent();
43 +
44 + /**
45 + * Returns the bytes received.
46 + *
47 + * @return the bytes received
48 + */
49 + public long bytesReceived();
50 +
51 + /**
52 + * Returns the bytes sent.
53 + *
54 + * @return the bytes sent
55 + */
56 + public long bytesSent();
57 +
58 + /**
59 + * Returns the number of packets dropped by RX.
60 + *
61 + * @return the number of packets dropped by RX
62 + */
63 + public long packetsRxDropped();
64 +
65 + /**
66 + * Returns the number of packets dropped by TX.
67 + *
68 + * @return the number of packets dropped by TX
69 + */
70 + public long packetsTxDropped();
71 +
72 + /**
73 + * Returns the number of transmit errors.
74 + *
75 + * @return the number of transmit errors
76 + */
77 + public long packetsRxErrors();
78 +
79 + /**
80 + * Returns the number of receive errors.
81 + *
82 + * @return the number of receive error
83 + */
84 + public long packetsTxErrors();
85 +
86 + /**
87 + * Returns the time port has been alive in seconds.
88 + *
89 + * @return the time port has been alive in seconds
90 + */
91 + public long durationSec();
92 +
93 + /**
94 + * Returns the time port has been alive in nano seconds.
95 + *
96 + * @return the time port has been alive in nano seconds
97 + */
98 + public long durationNano();
99 +
100 +}
...@@ -69,6 +69,11 @@ public class DeviceServiceAdapter implements DeviceService { ...@@ -69,6 +69,11 @@ public class DeviceServiceAdapter implements DeviceService {
69 } 69 }
70 70
71 @Override 71 @Override
72 + public List<PortStatistics> getPortStatistics(DeviceId deviceId) {
73 + return null;
74 + }
75 +
76 + @Override
72 public Port getPort(DeviceId deviceId, PortNumber portNumber) { 77 public Port getPort(DeviceId deviceId, PortNumber portNumber) {
73 return null; 78 return null;
74 } 79 }
......
...@@ -50,10 +50,12 @@ import org.onosproject.net.device.DeviceService; ...@@ -50,10 +50,12 @@ import org.onosproject.net.device.DeviceService;
50 import org.onosproject.net.device.DeviceStore; 50 import org.onosproject.net.device.DeviceStore;
51 import org.onosproject.net.device.DeviceStoreDelegate; 51 import org.onosproject.net.device.DeviceStoreDelegate;
52 import org.onosproject.net.device.PortDescription; 52 import org.onosproject.net.device.PortDescription;
53 +import org.onosproject.net.device.PortStatistics;
53 import org.onosproject.net.provider.AbstractProviderRegistry; 54 import org.onosproject.net.provider.AbstractProviderRegistry;
54 import org.onosproject.net.provider.AbstractProviderService; 55 import org.onosproject.net.provider.AbstractProviderService;
55 import org.slf4j.Logger; 56 import org.slf4j.Logger;
56 57
58 +import java.util.Collection;
57 import java.util.List; 59 import java.util.List;
58 import java.util.concurrent.ScheduledExecutorService; 60 import java.util.concurrent.ScheduledExecutorService;
59 import java.util.concurrent.TimeUnit; 61 import java.util.concurrent.TimeUnit;
...@@ -174,6 +176,12 @@ public class DeviceManager ...@@ -174,6 +176,12 @@ public class DeviceManager
174 } 176 }
175 177
176 @Override 178 @Override
179 + public List<PortStatistics> getPortStatistics(DeviceId deviceId) {
180 + checkNotNull(deviceId, DEVICE_ID_NULL);
181 + return store.getPortStatistics(deviceId);
182 + }
183 +
184 + @Override
177 public Port getPort(DeviceId deviceId, PortNumber portNumber) { 185 public Port getPort(DeviceId deviceId, PortNumber portNumber) {
178 checkNotNull(deviceId, DEVICE_ID_NULL); 186 checkNotNull(deviceId, DEVICE_ID_NULL);
179 checkNotNull(portNumber, PORT_NUMBER_NULL); 187 checkNotNull(portNumber, PORT_NUMBER_NULL);
...@@ -463,6 +471,19 @@ public class DeviceManager ...@@ -463,6 +471,19 @@ public class DeviceManager
463 } 471 }
464 472
465 } 473 }
474 +
475 + @Override
476 + public void updatePortStatistics(DeviceId deviceId, Collection<PortStatistics> portStatistics) {
477 + checkNotNull(deviceId, DEVICE_ID_NULL);
478 + checkNotNull(portStatistics,
479 + "Port statistics list cannot be null");
480 + checkValidity();
481 +
482 + DeviceEvent event = store.updatePortStatistics(this.provider().id(),
483 + deviceId, portStatistics);
484 +
485 + post(event);
486 + }
466 } 487 }
467 488
468 // Posts the specified event to the local event dispatcher. 489 // Posts the specified event to the local event dispatcher.
......
...@@ -53,6 +53,7 @@ import org.onosproject.net.device.DeviceEvent; ...@@ -53,6 +53,7 @@ import org.onosproject.net.device.DeviceEvent;
53 import org.onosproject.net.device.DeviceStore; 53 import org.onosproject.net.device.DeviceStore;
54 import org.onosproject.net.device.DeviceStoreDelegate; 54 import org.onosproject.net.device.DeviceStoreDelegate;
55 import org.onosproject.net.device.PortDescription; 55 import org.onosproject.net.device.PortDescription;
56 +import org.onosproject.net.device.PortStatistics;
56 import org.onosproject.net.provider.ProviderId; 57 import org.onosproject.net.provider.ProviderId;
57 import org.onosproject.store.AbstractStore; 58 import org.onosproject.store.AbstractStore;
58 import org.onosproject.store.Timestamp; 59 import org.onosproject.store.Timestamp;
...@@ -121,6 +122,8 @@ public class GossipDeviceStore ...@@ -121,6 +122,8 @@ public class GossipDeviceStore
121 // cache of Device and Ports generated by compositing descriptions from providers 122 // cache of Device and Ports generated by compositing descriptions from providers
122 private final ConcurrentMap<DeviceId, Device> devices = Maps.newConcurrentMap(); 123 private final ConcurrentMap<DeviceId, Device> devices = Maps.newConcurrentMap();
123 private final ConcurrentMap<DeviceId, ConcurrentMap<PortNumber, Port>> devicePorts = Maps.newConcurrentMap(); 124 private final ConcurrentMap<DeviceId, ConcurrentMap<PortNumber, Port>> devicePorts = Maps.newConcurrentMap();
125 + private final ConcurrentMap<DeviceId, ConcurrentMap<PortNumber, PortStatistics>>
126 + devicePortStats = Maps.newConcurrentMap();
124 127
125 // to be updated under Device lock 128 // to be updated under Device lock
126 private final Map<DeviceId, Timestamp> offline = Maps.newHashMap(); 129 private final Map<DeviceId, Timestamp> offline = Maps.newHashMap();
...@@ -800,6 +803,34 @@ public class GossipDeviceStore ...@@ -800,6 +803,34 @@ public class GossipDeviceStore
800 } 803 }
801 804
802 @Override 805 @Override
806 + public DeviceEvent updatePortStatistics(ProviderId providerId, DeviceId deviceId,
807 + Collection<PortStatistics> portStats) {
808 +
809 + ConcurrentMap<PortNumber, PortStatistics> statsMap = devicePortStats.get(deviceId);
810 + if (statsMap == null) {
811 + statsMap = Maps.newConcurrentMap();
812 + devicePortStats.put(deviceId, statsMap);
813 + }
814 +
815 + for (PortStatistics stat: portStats) {
816 + PortNumber portNumber = PortNumber.portNumber(stat.port());
817 + statsMap.put(portNumber, stat);
818 + }
819 +
820 + return new DeviceEvent(PORT_STATS_UPDATED, devices.get(deviceId), null);
821 + }
822 +
823 + @Override
824 + public List<PortStatistics> getPortStatistics(DeviceId deviceId) {
825 +
826 + Map<PortNumber, PortStatistics> portStats = devicePortStats.get(deviceId);
827 + if (portStats == null) {
828 + return Collections.emptyList();
829 + }
830 + return ImmutableList.copyOf(portStats.values());
831 + }
832 +
833 + @Override
803 public Port getPort(DeviceId deviceId, PortNumber portNumber) { 834 public Port getPort(DeviceId deviceId, PortNumber portNumber) {
804 Map<PortNumber, Port> ports = devicePorts.get(deviceId); 835 Map<PortNumber, Port> ports = devicePorts.get(deviceId);
805 return ports == null ? null : ports.get(portNumber); 836 return ports == null ? null : ports.get(portNumber);
......
...@@ -42,6 +42,7 @@ import org.onosproject.net.device.DeviceEvent; ...@@ -42,6 +42,7 @@ import org.onosproject.net.device.DeviceEvent;
42 import org.onosproject.net.device.DeviceStore; 42 import org.onosproject.net.device.DeviceStore;
43 import org.onosproject.net.device.DeviceStoreDelegate; 43 import org.onosproject.net.device.DeviceStoreDelegate;
44 import org.onosproject.net.device.PortDescription; 44 import org.onosproject.net.device.PortDescription;
45 +import org.onosproject.net.device.PortStatistics;
45 import org.onosproject.net.provider.ProviderId; 46 import org.onosproject.net.provider.ProviderId;
46 import org.onosproject.store.AbstractStore; 47 import org.onosproject.store.AbstractStore;
47 import org.onlab.packet.ChassisId; 48 import org.onlab.packet.ChassisId;
...@@ -49,6 +50,7 @@ import org.onlab.util.NewConcurrentHashMap; ...@@ -49,6 +50,7 @@ import org.onlab.util.NewConcurrentHashMap;
49 import org.slf4j.Logger; 50 import org.slf4j.Logger;
50 51
51 import java.util.ArrayList; 52 import java.util.ArrayList;
53 +import java.util.Collection;
52 import java.util.Collections; 54 import java.util.Collections;
53 import java.util.HashMap; 55 import java.util.HashMap;
54 import java.util.HashSet; 56 import java.util.HashSet;
...@@ -94,6 +96,8 @@ public class SimpleDeviceStore ...@@ -94,6 +96,8 @@ public class SimpleDeviceStore
94 private final ConcurrentMap<DeviceId, Device> devices = Maps.newConcurrentMap(); 96 private final ConcurrentMap<DeviceId, Device> devices = Maps.newConcurrentMap();
95 private final ConcurrentMap<DeviceId, ConcurrentMap<PortNumber, Port>> 97 private final ConcurrentMap<DeviceId, ConcurrentMap<PortNumber, Port>>
96 devicePorts = Maps.newConcurrentMap(); 98 devicePorts = Maps.newConcurrentMap();
99 + private final ConcurrentMap<DeviceId, ConcurrentMap<PortNumber, PortStatistics>>
100 + devicePortStats = Maps.newConcurrentMap();
97 101
98 // Available (=UP) devices 102 // Available (=UP) devices
99 private final Set<DeviceId> availableDevices = Sets.newConcurrentHashSet(); 103 private final Set<DeviceId> availableDevices = Sets.newConcurrentHashSet();
...@@ -416,12 +420,39 @@ public class SimpleDeviceStore ...@@ -416,12 +420,39 @@ public class SimpleDeviceStore
416 } 420 }
417 421
418 @Override 422 @Override
423 + public DeviceEvent updatePortStatistics(ProviderId providerId, DeviceId deviceId,
424 + Collection<PortStatistics> portStats) {
425 +
426 + ConcurrentMap<PortNumber, PortStatistics> statsMap = devicePortStats.get(deviceId);
427 + if (statsMap == null) {
428 + statsMap = Maps.newConcurrentMap();
429 + devicePortStats.put(deviceId, statsMap);
430 + }
431 +
432 + for (PortStatistics stat: portStats) {
433 + PortNumber portNumber = PortNumber.portNumber(stat.port());
434 + statsMap.put(portNumber, stat);
435 + }
436 +
437 + return new DeviceEvent(PORT_STATS_UPDATED, devices.get(deviceId), null);
438 + }
439 +
440 + @Override
419 public Port getPort(DeviceId deviceId, PortNumber portNumber) { 441 public Port getPort(DeviceId deviceId, PortNumber portNumber) {
420 Map<PortNumber, Port> ports = devicePorts.get(deviceId); 442 Map<PortNumber, Port> ports = devicePorts.get(deviceId);
421 return ports == null ? null : ports.get(portNumber); 443 return ports == null ? null : ports.get(portNumber);
422 } 444 }
423 445
424 @Override 446 @Override
447 + public List<PortStatistics> getPortStatistics(DeviceId deviceId) {
448 + Map<PortNumber, PortStatistics> portStats = devicePortStats.get(deviceId);
449 + if (portStats == null) {
450 + return Collections.emptyList();
451 + }
452 + return ImmutableList.copyOf(portStats.values());
453 + }
454 +
455 + @Override
425 public boolean isAvailable(DeviceId deviceId) { 456 public boolean isAvailable(DeviceId deviceId) {
426 return availableDevices.contains(deviceId); 457 return availableDevices.contains(deviceId);
427 } 458 }
......
...@@ -47,6 +47,8 @@ import org.projectfloodlight.openflow.protocol.OFGroupStatsReply; ...@@ -47,6 +47,8 @@ import org.projectfloodlight.openflow.protocol.OFGroupStatsReply;
47 import org.projectfloodlight.openflow.protocol.OFMessage; 47 import org.projectfloodlight.openflow.protocol.OFMessage;
48 import org.projectfloodlight.openflow.protocol.OFPacketIn; 48 import org.projectfloodlight.openflow.protocol.OFPacketIn;
49 import org.projectfloodlight.openflow.protocol.OFPortDesc; 49 import org.projectfloodlight.openflow.protocol.OFPortDesc;
50 +import org.projectfloodlight.openflow.protocol.OFPortStatsEntry;
51 +import org.projectfloodlight.openflow.protocol.OFPortStatsReply;
50 import org.projectfloodlight.openflow.protocol.OFPortStatus; 52 import org.projectfloodlight.openflow.protocol.OFPortStatus;
51 import org.projectfloodlight.openflow.protocol.OFStatsReply; 53 import org.projectfloodlight.openflow.protocol.OFStatsReply;
52 import org.projectfloodlight.openflow.protocol.OFStatsReplyFlags; 54 import org.projectfloodlight.openflow.protocol.OFStatsReplyFlags;
...@@ -104,6 +106,9 @@ public class OpenFlowControllerImpl implements OpenFlowController { ...@@ -104,6 +106,9 @@ public class OpenFlowControllerImpl implements OpenFlowController {
104 protected Multimap<Dpid, OFGroupDescStatsEntry> fullGroupDescStats = 106 protected Multimap<Dpid, OFGroupDescStatsEntry> fullGroupDescStats =
105 ArrayListMultimap.create(); 107 ArrayListMultimap.create();
106 108
109 + protected Multimap<Dpid, OFPortStatsEntry> fullPortStats =
110 + ArrayListMultimap.create();
111 +
107 private final Controller ctrl = new Controller(); 112 private final Controller ctrl = new Controller();
108 113
109 @Activate 114 @Activate
...@@ -216,6 +221,7 @@ public class OpenFlowControllerImpl implements OpenFlowController { ...@@ -216,6 +221,7 @@ public class OpenFlowControllerImpl implements OpenFlowController {
216 Collection<OFFlowStatsEntry> flowStats; 221 Collection<OFFlowStatsEntry> flowStats;
217 Collection<OFGroupStatsEntry> groupStats; 222 Collection<OFGroupStatsEntry> groupStats;
218 Collection<OFGroupDescStatsEntry> groupDescStats; 223 Collection<OFGroupDescStatsEntry> groupDescStats;
224 + Collection<OFPortStatsEntry> portStats;
219 225
220 switch (msg.getType()) { 226 switch (msg.getType()) {
221 case PORT_STATUS: 227 case PORT_STATUS:
...@@ -280,6 +286,9 @@ public class OpenFlowControllerImpl implements OpenFlowController { ...@@ -280,6 +286,9 @@ public class OpenFlowControllerImpl implements OpenFlowController {
280 executorMsgs.submit(new OFMessageHandler(dpid, rep.build())); 286 executorMsgs.submit(new OFMessageHandler(dpid, rep.build()));
281 } 287 }
282 break; 288 break;
289 + case PORT:
290 + executorMsgs.submit(new OFMessageHandler(dpid, reply));
291 + break;
283 default: 292 default:
284 log.warn("Unsupported stats type : {}", reply.getStatsType()); 293 log.warn("Unsupported stats type : {}", reply.getStatsType());
285 } 294 }
...@@ -343,6 +352,15 @@ public class OpenFlowControllerImpl implements OpenFlowController { ...@@ -343,6 +352,15 @@ public class OpenFlowControllerImpl implements OpenFlowController {
343 return null; 352 return null;
344 } 353 }
345 354
355 + private synchronized Collection<OFPortStatsEntry> publishPortStats(Dpid dpid,
356 + OFPortStatsReply reply) {
357 + fullPortStats.putAll(dpid, reply.getEntries());
358 + if (!reply.getFlags().contains(OFStatsReplyFlags.REPLY_MORE)) {
359 + return fullPortStats.removeAll(dpid);
360 + }
361 + return null;
362 + }
363 +
346 @Override 364 @Override
347 public void setRole(Dpid dpid, RoleState role) { 365 public void setRole(Dpid dpid, RoleState role) {
348 final OpenFlowSwitch sw = getSwitch(dpid); 366 final OpenFlowSwitch sw = getSwitch(dpid);
......
...@@ -15,6 +15,8 @@ ...@@ -15,6 +15,8 @@
15 */ 15 */
16 package org.onosproject.provider.of.device.impl; 16 package org.onosproject.provider.of.device.impl;
17 17
18 +import com.google.common.collect.Maps;
19 +import com.google.common.collect.Sets;
18 import org.apache.felix.scr.annotations.Activate; 20 import org.apache.felix.scr.annotations.Activate;
19 import org.apache.felix.scr.annotations.Component; 21 import org.apache.felix.scr.annotations.Component;
20 import org.apache.felix.scr.annotations.Deactivate; 22 import org.apache.felix.scr.annotations.Deactivate;
...@@ -29,31 +31,43 @@ import org.onosproject.net.PortNumber; ...@@ -29,31 +31,43 @@ import org.onosproject.net.PortNumber;
29 import org.onosproject.net.SparseAnnotations; 31 import org.onosproject.net.SparseAnnotations;
30 import org.onosproject.net.device.DefaultDeviceDescription; 32 import org.onosproject.net.device.DefaultDeviceDescription;
31 import org.onosproject.net.device.DefaultPortDescription; 33 import org.onosproject.net.device.DefaultPortDescription;
34 +import org.onosproject.net.device.DefaultPortStatistics;
32 import org.onosproject.net.device.DeviceDescription; 35 import org.onosproject.net.device.DeviceDescription;
33 import org.onosproject.net.device.DeviceProvider; 36 import org.onosproject.net.device.DeviceProvider;
34 import org.onosproject.net.device.DeviceProviderRegistry; 37 import org.onosproject.net.device.DeviceProviderRegistry;
35 import org.onosproject.net.device.DeviceProviderService; 38 import org.onosproject.net.device.DeviceProviderService;
36 import org.onosproject.net.device.PortDescription; 39 import org.onosproject.net.device.PortDescription;
40 +import org.onosproject.net.device.PortStatistics;
37 import org.onosproject.net.provider.AbstractProvider; 41 import org.onosproject.net.provider.AbstractProvider;
38 import org.onosproject.net.provider.ProviderId; 42 import org.onosproject.net.provider.ProviderId;
39 import org.onosproject.openflow.controller.Dpid; 43 import org.onosproject.openflow.controller.Dpid;
40 import org.onosproject.openflow.controller.OpenFlowController; 44 import org.onosproject.openflow.controller.OpenFlowController;
45 +import org.onosproject.openflow.controller.OpenFlowEventListener;
41 import org.onosproject.openflow.controller.OpenFlowSwitch; 46 import org.onosproject.openflow.controller.OpenFlowSwitch;
42 import org.onosproject.openflow.controller.OpenFlowSwitchListener; 47 import org.onosproject.openflow.controller.OpenFlowSwitchListener;
43 import org.onosproject.openflow.controller.RoleState; 48 import org.onosproject.openflow.controller.RoleState;
44 import org.onlab.packet.ChassisId; 49 import org.onlab.packet.ChassisId;
45 import org.projectfloodlight.openflow.protocol.OFFactory; 50 import org.projectfloodlight.openflow.protocol.OFFactory;
51 +import org.projectfloodlight.openflow.protocol.OFMessage;
46 import org.projectfloodlight.openflow.protocol.OFPortConfig; 52 import org.projectfloodlight.openflow.protocol.OFPortConfig;
47 import org.projectfloodlight.openflow.protocol.OFPortDesc; 53 import org.projectfloodlight.openflow.protocol.OFPortDesc;
48 import org.projectfloodlight.openflow.protocol.OFPortFeatures; 54 import org.projectfloodlight.openflow.protocol.OFPortFeatures;
49 import org.projectfloodlight.openflow.protocol.OFPortReason; 55 import org.projectfloodlight.openflow.protocol.OFPortReason;
50 import org.projectfloodlight.openflow.protocol.OFPortState; 56 import org.projectfloodlight.openflow.protocol.OFPortState;
57 +import org.projectfloodlight.openflow.protocol.OFPortStatsEntry;
58 +import org.projectfloodlight.openflow.protocol.OFPortStatsReply;
51 import org.projectfloodlight.openflow.protocol.OFPortStatus; 59 import org.projectfloodlight.openflow.protocol.OFPortStatus;
60 +import org.projectfloodlight.openflow.protocol.OFStatsReply;
61 +import org.projectfloodlight.openflow.protocol.OFStatsType;
52 import org.projectfloodlight.openflow.protocol.OFVersion; 62 import org.projectfloodlight.openflow.protocol.OFVersion;
53 import org.projectfloodlight.openflow.types.PortSpeed; 63 import org.projectfloodlight.openflow.types.PortSpeed;
54 import org.slf4j.Logger; 64 import org.slf4j.Logger;
55 65
56 import java.util.ArrayList; 66 import java.util.ArrayList;
67 +import java.util.Collection;
68 +import java.util.Collections;
69 +import java.util.HashMap;
70 +import java.util.HashSet;
57 import java.util.List; 71 import java.util.List;
58 72
59 import com.google.common.base.Strings; 73 import com.google.common.base.Strings;
...@@ -83,7 +97,12 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr ...@@ -83,7 +97,12 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr
83 97
84 private DeviceProviderService providerService; 98 private DeviceProviderService providerService;
85 99
86 - private final OpenFlowSwitchListener listener = new InternalDeviceProvider(); 100 + private final InternalDeviceProvider listener = new InternalDeviceProvider();
101 +
102 + // TODO: We need to make the poll interval configurable.
103 + static final int POLL_INTERVAL = 10;
104 +
105 + private HashMap<Dpid, PortStatsCollector> collectors = Maps.newHashMap();
87 106
88 /** 107 /**
89 * Creates an OpenFlow device provider. 108 * Creates an OpenFlow device provider.
...@@ -96,6 +115,7 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr ...@@ -96,6 +115,7 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr
96 public void activate() { 115 public void activate() {
97 providerService = providerRegistry.register(this); 116 providerService = providerRegistry.register(this);
98 controller.addListener(listener); 117 controller.addListener(listener);
118 + controller.addEventListener(listener);
99 for (OpenFlowSwitch sw : controller.getSwitches()) { 119 for (OpenFlowSwitch sw : controller.getSwitches()) {
100 try { 120 try {
101 listener.switchAdded(new Dpid(sw.getId())); 121 listener.switchAdded(new Dpid(sw.getId()));
...@@ -105,6 +125,9 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr ...@@ -105,6 +125,9 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr
105 // disconnect to trigger switch-add later 125 // disconnect to trigger switch-add later
106 sw.disconnectSwitch(); 126 sw.disconnectSwitch();
107 } 127 }
128 + PortStatsCollector psc = new PortStatsCollector(sw, POLL_INTERVAL);
129 + psc.start();
130 + collectors.put(new Dpid(sw.getId()), psc);
108 } 131 }
109 LOG.info("Started"); 132 LOG.info("Started");
110 } 133 }
...@@ -174,7 +197,45 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr ...@@ -174,7 +197,45 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr
174 LOG.info("Accepting mastership role change for device {}", deviceId); 197 LOG.info("Accepting mastership role change for device {}", deviceId);
175 } 198 }
176 199
177 - private class InternalDeviceProvider implements OpenFlowSwitchListener { 200 + private void pushPortMetrics(Dpid dpid, OFPortStatsReply msg) {
201 + DeviceId deviceId = DeviceId.deviceId(dpid.uri(dpid));
202 +
203 + Collection<PortStatistics> stats = buildPortStatistics(deviceId, msg);
204 +
205 + providerService.updatePortStatistics(deviceId, stats);
206 + }
207 +
208 + private Collection<PortStatistics> buildPortStatistics(DeviceId deviceId, OFPortStatsReply msg) {
209 +
210 + HashSet<PortStatistics> stats = Sets.newHashSet();
211 +
212 + for (OFPortStatsEntry entry: msg.getEntries()) {
213 + if (entry.getPortNo().getPortNumber() < 0) {
214 + continue;
215 + }
216 + DefaultPortStatistics.Builder builder = DefaultPortStatistics.builder();
217 + DefaultPortStatistics stat = builder.setDeviceId(deviceId)
218 + .setPort(entry.getPortNo().getPortNumber())
219 + .setPacketsReceived(entry.getRxPackets().getValue())
220 + .setPacketsSent(entry.getTxPackets().getValue())
221 + .setBytesReceived(entry.getRxBytes().getValue())
222 + .setBytesSent(entry.getTxBytes().getValue())
223 + .setPacketsRxDropped(entry.getRxDropped().getValue())
224 + .setPacketsTxDropped(entry.getTxDropped().getValue())
225 + .setPacketsRxErrors(entry.getRxErrors().getValue())
226 + .setPacketsTxErrors(entry.getTxErrors().getValue())
227 + .setDurationSec(entry.getDurationSec())
228 + .setDurationNano(entry.getDurationNsec())
229 + .build();
230 +
231 + stats.add(stat);
232 + }
233 +
234 + return Collections.unmodifiableSet(stats);
235 +
236 + }
237 +
238 + private class InternalDeviceProvider implements OpenFlowSwitchListener, OpenFlowEventListener {
178 @Override 239 @Override
179 public void switchAdded(Dpid dpid) { 240 public void switchAdded(Dpid dpid) {
180 if (providerService == null) { 241 if (providerService == null) {
...@@ -201,6 +262,11 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr ...@@ -201,6 +262,11 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr
201 cId, annotations); 262 cId, annotations);
202 providerService.deviceConnected(did, description); 263 providerService.deviceConnected(did, description);
203 providerService.updatePorts(did, buildPortDescriptions(sw.getPorts())); 264 providerService.updatePorts(did, buildPortDescriptions(sw.getPorts()));
265 +
266 + PortStatsCollector psc = new PortStatsCollector(
267 + controller.getSwitch(dpid), POLL_INTERVAL);
268 + psc.start();
269 + collectors.put(dpid, psc);
204 } 270 }
205 271
206 @Override 272 @Override
...@@ -209,8 +275,12 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr ...@@ -209,8 +275,12 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr
209 return; 275 return;
210 } 276 }
211 providerService.deviceDisconnected(deviceId(uri(dpid))); 277 providerService.deviceDisconnected(deviceId(uri(dpid)));
212 - }
213 278
279 + PortStatsCollector collector = collectors.remove(dpid);
280 + if (collector != null) {
281 + collector.stop();
282 + }
283 + }
214 284
215 @Override 285 @Override
216 public void switchChanged(Dpid dpid) { 286 public void switchChanged(Dpid dpid) {
...@@ -328,6 +398,19 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr ...@@ -328,6 +398,19 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr
328 } 398 }
329 return portSpeed.getSpeedBps() / MBPS; 399 return portSpeed.getSpeedBps() / MBPS;
330 } 400 }
401 +
402 + @Override
403 + public void handleMessage(Dpid dpid, OFMessage msg) {
404 + switch (msg.getType()) {
405 + case STATS_REPLY:
406 + if (((OFStatsReply) msg).getStatsType() == OFStatsType.PORT) {
407 + pushPortMetrics(dpid, (OFPortStatsReply) msg);
408 + }
409 + break;
410 + default:
411 + break;
412 + }
413 + }
331 } 414 }
332 415
333 } 416 }
......
1 +/*
2 + * Copyright 2015 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 + */
16 +
17 +package org.onosproject.provider.of.device.impl;
18 +
19 +import org.jboss.netty.util.HashedWheelTimer;
20 +import org.jboss.netty.util.Timeout;
21 +import org.jboss.netty.util.TimerTask;
22 +import org.onlab.util.Timer;
23 +import org.onosproject.openflow.controller.OpenFlowSwitch;
24 +import org.onosproject.openflow.controller.RoleState;
25 +import org.projectfloodlight.openflow.protocol.OFPortStatsRequest;
26 +import org.projectfloodlight.openflow.types.OFPort;
27 +import org.slf4j.Logger;
28 +
29 +import java.util.concurrent.TimeUnit;
30 +import java.util.concurrent.atomic.AtomicLong;
31 +
32 +import static org.slf4j.LoggerFactory.getLogger;
33 +
34 +/*
35 + * Sends Group Stats Request and collect the group statistics with a time interval.
36 + */
37 +public class PortStatsCollector implements TimerTask {
38 +
39 + // TODO: Refactoring is required using ScheduledExecutorService
40 +
41 + private final HashedWheelTimer timer = Timer.getTimer();
42 + private final OpenFlowSwitch sw;
43 + private final Logger log = getLogger(getClass());
44 + private final int refreshInterval;
45 + private final AtomicLong xidAtomic = new AtomicLong(1);
46 +
47 + private Timeout timeout;
48 +
49 + private boolean stopTimer = false;
50 +
51 + /**
52 + * Creates a GroupStatsCollector object.
53 + *
54 + * @param sw Open Flow switch
55 + * @param interval time interval for collecting group statistic
56 + */
57 + public PortStatsCollector(OpenFlowSwitch sw, int interval) {
58 + this.sw = sw;
59 + this.refreshInterval = interval;
60 + }
61 +
62 + @Override
63 + public void run(Timeout timeout) throws Exception {
64 + log.trace("Collecting stats for {}", sw.getStringId());
65 +
66 + sendPortStatistic();
67 +
68 + if (!this.stopTimer) {
69 + log.trace("Scheduling stats collection in {} seconds for {}",
70 + this.refreshInterval, this.sw.getStringId());
71 + timeout.getTimer().newTimeout(this, refreshInterval,
72 + TimeUnit.SECONDS);
73 + }
74 + }
75 +
76 + private void sendPortStatistic() {
77 + if (log.isTraceEnabled()) {
78 + log.trace("sendGroupStatistics {}:{}", sw.getStringId(), sw.getRole());
79 + }
80 + if (sw.getRole() != RoleState.MASTER) {
81 + return;
82 + }
83 + Long statsXid = xidAtomic.getAndIncrement();
84 + OFPortStatsRequest statsRequest = sw.factory().buildPortStatsRequest()
85 + .setPortNo(OFPort.ANY)
86 + .setXid(statsXid)
87 + .build();
88 + sw.sendMsg(statsRequest);
89 + }
90 +
91 + /**
92 + * Starts the collector.
93 + */
94 + public void start() {
95 + log.info("Starting Port Stats collection thread for {}", sw.getStringId());
96 + timeout = timer.newTimeout(this, 1, TimeUnit.SECONDS);
97 + }
98 +
99 + /**
100 + * Stops the collector.
101 + */
102 + public void stop() {
103 + log.info("Stopping Port Stats collection thread for {}", sw.getStringId());
104 + this.stopTimer = true;
105 + timeout.cancel();
106 + }
107 +}
...@@ -23,6 +23,7 @@ import static org.onosproject.net.Device.Type.*; ...@@ -23,6 +23,7 @@ import static org.onosproject.net.Device.Type.*;
23 import static org.onosproject.net.MastershipRole.*; 23 import static org.onosproject.net.MastershipRole.*;
24 24
25 import java.util.ArrayList; 25 import java.util.ArrayList;
26 +import java.util.Collection;
26 import java.util.HashMap; 27 import java.util.HashMap;
27 import java.util.HashSet; 28 import java.util.HashSet;
28 import java.util.List; 29 import java.util.List;
...@@ -41,6 +42,7 @@ import org.onosproject.net.device.DeviceProvider; ...@@ -41,6 +42,7 @@ import org.onosproject.net.device.DeviceProvider;
41 import org.onosproject.net.device.DeviceProviderRegistry; 42 import org.onosproject.net.device.DeviceProviderRegistry;
42 import org.onosproject.net.device.DeviceProviderService; 43 import org.onosproject.net.device.DeviceProviderService;
43 import org.onosproject.net.device.PortDescription; 44 import org.onosproject.net.device.PortDescription;
45 +import org.onosproject.net.device.PortStatistics;
44 import org.onosproject.net.provider.ProviderId; 46 import org.onosproject.net.provider.ProviderId;
45 import org.onosproject.openflow.controller.Dpid; 47 import org.onosproject.openflow.controller.Dpid;
46 import org.onosproject.openflow.controller.OpenFlowController; 48 import org.onosproject.openflow.controller.OpenFlowController;
...@@ -217,6 +219,11 @@ public class OpenFlowDeviceProviderTest { ...@@ -217,6 +219,11 @@ public class OpenFlowDeviceProviderTest {
217 roles.put(requested, Dpid.dpid(deviceId.uri())); 219 roles.put(requested, Dpid.dpid(deviceId.uri()));
218 } 220 }
219 221
222 + @Override
223 + public void updatePortStatistics(DeviceId deviceId, Collection<PortStatistics> portStatistics) {
224 +
225 + }
226 +
220 } 227 }
221 } 228 }
222 229
......