sangyun-han
Committed by Gerrit Code Review

[ONOS-4668] Refactoring port statistic collector using SharedExecutor

- Add OpenFlowSwitchAdapter

Change-Id: I7bd9c61d8961bee18eca2c1ac0e5fca610e166e5
1 +/*
2 + * Copyright 2015-present 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.openflow.controller;
17 +
18 +import org.onosproject.net.Device;
19 +import org.projectfloodlight.openflow.protocol.OFFactory;
20 +import org.projectfloodlight.openflow.protocol.OFMessage;
21 +import org.projectfloodlight.openflow.protocol.OFPortDesc;
22 +
23 +import java.util.List;
24 +
25 +/**
26 + * Test adapter for the OpenFlow switch interface.
27 + */
28 +public class OpenFlowSwitchAdapter implements OpenFlowSwitch {
29 + @Override
30 + public void sendMsg(OFMessage msg) {
31 +
32 + }
33 +
34 + @Override
35 + public void sendMsg(List<OFMessage> msgs) {
36 +
37 + }
38 +
39 + @Override
40 + public void handleMessage(OFMessage fromSwitch) {
41 +
42 + }
43 +
44 + @Override
45 + public void setRole(RoleState role) {
46 +
47 + }
48 +
49 + @Override
50 + public RoleState getRole() {
51 + return null;
52 + }
53 +
54 + @Override
55 + public List<OFPortDesc> getPorts() {
56 + return null;
57 + }
58 +
59 + @Override
60 + public OFFactory factory() {
61 + return null;
62 + }
63 +
64 + @Override
65 + public String getStringId() {
66 + return null;
67 + }
68 +
69 + @Override
70 + public long getId() {
71 + return 0;
72 + }
73 +
74 + @Override
75 + public String manufacturerDescription() {
76 + return null;
77 + }
78 +
79 + @Override
80 + public String datapathDescription() {
81 + return null;
82 + }
83 +
84 + @Override
85 + public String hardwareDescription() {
86 + return null;
87 + }
88 +
89 + @Override
90 + public String softwareDescription() {
91 + return null;
92 + }
93 +
94 + @Override
95 + public String serialNumber() {
96 + return null;
97 + }
98 +
99 + @Override
100 + public boolean isConnected() {
101 + return false;
102 + }
103 +
104 + @Override
105 + public void disconnectSwitch() {
106 +
107 + }
108 +
109 + @Override
110 + public void returnRoleReply(RoleState requested, RoleState response) {
111 +
112 + }
113 +
114 + @Override
115 + public Device.Type deviceType() {
116 + return null;
117 + }
118 +
119 + @Override
120 + public String channelId() {
121 + return null;
122 + }
123 +}
...\ No newline at end of file ...\ No newline at end of file
1 /* 1 /*
2 - * Copyright 2014-present Open Networking Laboratory 2 + * Copyright 2015-present Open Networking Laboratory
3 * 3 *
4 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License. 5 * you may not use this file except in compliance with the License.
...@@ -38,6 +38,7 @@ import java.util.HashMap; ...@@ -38,6 +38,7 @@ import java.util.HashMap;
38 import java.util.HashSet; 38 import java.util.HashSet;
39 import java.util.List; 39 import java.util.List;
40 import java.util.Set; 40 import java.util.Set;
41 +import java.util.Timer;
41 42
42 import org.apache.felix.scr.annotations.Activate; 43 import org.apache.felix.scr.annotations.Activate;
43 import org.apache.felix.scr.annotations.Component; 44 import org.apache.felix.scr.annotations.Component;
...@@ -159,6 +160,8 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr ...@@ -159,6 +160,8 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr
159 label = "Frequency (in seconds) for polling switch Port statistics") 160 label = "Frequency (in seconds) for polling switch Port statistics")
160 private int portStatsPollFrequency = POLL_INTERVAL; 161 private int portStatsPollFrequency = POLL_INTERVAL;
161 162
163 + private final Timer timer = new Timer("onos-openflow-collector");
164 +
162 private HashMap<Dpid, PortStatsCollector> collectors = Maps.newHashMap(); 165 private HashMap<Dpid, PortStatsCollector> collectors = Maps.newHashMap();
163 166
164 /** 167 /**
...@@ -221,7 +224,7 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr ...@@ -221,7 +224,7 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr
221 // disconnect to trigger switch-add later 224 // disconnect to trigger switch-add later
222 sw.disconnectSwitch(); 225 sw.disconnectSwitch();
223 } 226 }
224 - PortStatsCollector psc = new PortStatsCollector(sw, portStatsPollFrequency); 227 + PortStatsCollector psc = new PortStatsCollector(timer, sw, portStatsPollFrequency);
225 psc.start(); 228 psc.start();
226 collectors.put(new Dpid(sw.getId()), psc); 229 collectors.put(new Dpid(sw.getId()), psc);
227 } 230 }
...@@ -382,7 +385,7 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr ...@@ -382,7 +385,7 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr
382 providerService.deviceConnected(did, description); 385 providerService.deviceConnected(did, description);
383 providerService.updatePorts(did, buildPortDescriptions(sw)); 386 providerService.updatePorts(did, buildPortDescriptions(sw));
384 387
385 - PortStatsCollector psc = new PortStatsCollector(sw, portStatsPollFrequency); 388 + PortStatsCollector psc = new PortStatsCollector(timer, sw, portStatsPollFrequency);
386 stopCollectorIfNeeded(collectors.put(dpid, psc)); 389 stopCollectorIfNeeded(collectors.put(dpid, psc));
387 psc.start(); 390 psc.start();
388 391
......
...@@ -16,69 +16,87 @@ ...@@ -16,69 +16,87 @@
16 16
17 package org.onosproject.provider.of.device.impl; 17 package org.onosproject.provider.of.device.impl;
18 18
19 -import org.jboss.netty.util.HashedWheelTimer; 19 +import org.onlab.util.SharedExecutors;
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; 20 import org.onosproject.openflow.controller.OpenFlowSwitch;
24 import org.onosproject.openflow.controller.RoleState; 21 import org.onosproject.openflow.controller.RoleState;
25 import org.projectfloodlight.openflow.protocol.OFPortStatsRequest; 22 import org.projectfloodlight.openflow.protocol.OFPortStatsRequest;
26 import org.projectfloodlight.openflow.types.OFPort; 23 import org.projectfloodlight.openflow.types.OFPort;
27 import org.slf4j.Logger; 24 import org.slf4j.Logger;
28 25
29 -import java.util.concurrent.TimeUnit; 26 +import java.util.Timer;
27 +import java.util.TimerTask;
30 import java.util.concurrent.atomic.AtomicLong; 28 import java.util.concurrent.atomic.AtomicLong;
31 29
30 +import static com.google.common.base.Preconditions.checkNotNull;
32 import static org.slf4j.LoggerFactory.getLogger; 31 import static org.slf4j.LoggerFactory.getLogger;
33 32
34 /** 33 /**
35 * Sends Port Stats Request and collect the port statistics with a time interval. 34 * Sends Port Stats Request and collect the port statistics with a time interval.
36 */ 35 */
37 -public class PortStatsCollector implements TimerTask { 36 +public class PortStatsCollector {
38 37
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()); 38 private final Logger log = getLogger(getClass());
39 +
40 + private static final int SECONDS = 1000;
41 +
42 + private OpenFlowSwitch sw;
43 + private Timer timer;
44 + private TimerTask task;
45 +
44 private int refreshInterval; 46 private int refreshInterval;
45 private final AtomicLong xidAtomic = new AtomicLong(1); 47 private final AtomicLong xidAtomic = new AtomicLong(1);
46 48
47 - private Timeout timeout;
48 - private volatile boolean stopped;
49 -
50 /** 49 /**
51 - * Creates a PortStatsCollector object. 50 + * Creates a port states collector object.
52 * 51 *
53 - * @param sw Open Flow switch 52 + * @param timer timer to use for scheduling
54 - * @param interval time interval for collecting port statistic 53 + * @param sw switch to pull
54 + * @param interval interval for collecting port statistic
55 */ 55 */
56 - public PortStatsCollector(OpenFlowSwitch sw, int interval) { 56 + PortStatsCollector(Timer timer, OpenFlowSwitch sw, int interval) {
57 - this.sw = sw; 57 + this.timer = timer;
58 + this.sw = checkNotNull(sw, "Null switch");
58 this.refreshInterval = interval; 59 this.refreshInterval = interval;
59 } 60 }
60 61
61 - @Override 62 + private class InternalTimerTask extends TimerTask {
62 - public void run(Timeout to) throws Exception {
63 - if (stopped || timeout.isCancelled()) {
64 - return;
65 - }
66 - log.trace("Collecting stats for {}", sw.getStringId());
67 63
64 + @Override
65 + public void run() {
68 sendPortStatistic(); 66 sendPortStatistic();
67 + }
68 + }
69 69
70 - if (!stopped && !timeout.isCancelled()) { 70 + /**
71 - log.trace("Scheduling stats collection in {} seconds for {}", 71 + * Starts the port statistic collector.
72 - this.refreshInterval, this.sw.getStringId()); 72 + */
73 - timeout.getTimer().newTimeout(this, refreshInterval, TimeUnit.SECONDS); 73 + public synchronized void start() {
74 + log.info("Starting Port Stats collection thread for {}", sw.getStringId());
75 + task = new InternalTimerTask();
76 + SharedExecutors.getTimer().scheduleAtFixedRate(task, 1 * SECONDS,
77 + refreshInterval * SECONDS);
74 } 78 }
79 +
80 + /**
81 + * Stops the port statistic collector.
82 + */
83 + public synchronized void stop() {
84 + log.info("Stopping Port Stats collection thread for {}", sw.getStringId());
85 + task.cancel();
86 + task = null;
75 } 87 }
76 88
77 - synchronized void adjustPollInterval(int pollInterval) { 89 + /**
90 + * Adjusts poll interval of the port statistic collector and restart.
91 + *
92 + * @param pollInterval period of collecting port statistic
93 + */
94 + public synchronized void adjustPollInterval(int pollInterval) {
78 this.refreshInterval = pollInterval; 95 this.refreshInterval = pollInterval;
79 - // task.cancel(); 96 + task.cancel();
80 - // task = new InternalTimerTask(); 97 + task = new InternalTimerTask();
81 - // timer.scheduleAtFixedRate(task, pollInterval * SECONDS, pollInterval * 1000); 98 + timer.scheduleAtFixedRate(task, refreshInterval * SECONDS,
99 + refreshInterval * SECONDS);
82 } 100 }
83 101
84 /** 102 /**
...@@ -95,22 +113,4 @@ public class PortStatsCollector implements TimerTask { ...@@ -95,22 +113,4 @@ public class PortStatsCollector implements TimerTask {
95 .build(); 113 .build();
96 sw.sendMsg(statsRequest); 114 sw.sendMsg(statsRequest);
97 } 115 }
98 -
99 - /**
100 - * Starts the collector.
101 - */
102 - public synchronized void start() {
103 - log.info("Starting Port Stats collection thread for {}", sw.getStringId());
104 - stopped = false;
105 - timeout = timer.newTimeout(this, 1, TimeUnit.SECONDS);
106 - }
107 -
108 - /**
109 - * Stops the collector.
110 - */
111 - public synchronized void stop() {
112 - log.info("Stopping Port Stats collection thread for {}", sw.getStringId());
113 - stopped = true;
114 - timeout.cancel();
115 - }
116 } 116 }
...\ No newline at end of file ...\ No newline at end of file
......