Dusan Pajin

Configurable Port Stats Collection interval

Change-Id: I4999338ecf1c608f93b66ba979126b2a5deda165
...@@ -30,5 +30,10 @@ ...@@ -30,5 +30,10 @@
30 <packaging>bundle</packaging> 30 <packaging>bundle</packaging>
31 31
32 <description>ONOS OpenFlow protocol device provider</description> 32 <description>ONOS OpenFlow protocol device provider</description>
33 - 33 + <dependencies>
34 + <dependency>
35 + <groupId>org.osgi</groupId>
36 + <artifactId>org.osgi.compendium</artifactId>
37 + </dependency>
38 + </dependencies>
34 </project> 39 </project>
......
...@@ -19,12 +19,16 @@ import com.google.common.base.Strings; ...@@ -19,12 +19,16 @@ import com.google.common.base.Strings;
19 import com.google.common.collect.Lists; 19 import com.google.common.collect.Lists;
20 import com.google.common.collect.Maps; 20 import com.google.common.collect.Maps;
21 import com.google.common.collect.Sets; 21 import com.google.common.collect.Sets;
22 +
22 import org.apache.felix.scr.annotations.Activate; 23 import org.apache.felix.scr.annotations.Activate;
23 import org.apache.felix.scr.annotations.Component; 24 import org.apache.felix.scr.annotations.Component;
24 import org.apache.felix.scr.annotations.Deactivate; 25 import org.apache.felix.scr.annotations.Deactivate;
26 +import org.apache.felix.scr.annotations.Modified;
27 +import org.apache.felix.scr.annotations.Property;
25 import org.apache.felix.scr.annotations.Reference; 28 import org.apache.felix.scr.annotations.Reference;
26 import org.apache.felix.scr.annotations.ReferenceCardinality; 29 import org.apache.felix.scr.annotations.ReferenceCardinality;
27 import org.onlab.packet.ChassisId; 30 import org.onlab.packet.ChassisId;
31 +import org.onosproject.cfg.ComponentConfigService;
28 import org.onosproject.net.AnnotationKeys; 32 import org.onosproject.net.AnnotationKeys;
29 import org.onosproject.net.DefaultAnnotations; 33 import org.onosproject.net.DefaultAnnotations;
30 import org.onosproject.net.Device; 34 import org.onosproject.net.Device;
...@@ -52,6 +56,7 @@ import org.onosproject.openflow.controller.OpenFlowSwitch; ...@@ -52,6 +56,7 @@ import org.onosproject.openflow.controller.OpenFlowSwitch;
52 import org.onosproject.openflow.controller.OpenFlowSwitchListener; 56 import org.onosproject.openflow.controller.OpenFlowSwitchListener;
53 import org.onosproject.openflow.controller.PortDescPropertyType; 57 import org.onosproject.openflow.controller.PortDescPropertyType;
54 import org.onosproject.openflow.controller.RoleState; 58 import org.onosproject.openflow.controller.RoleState;
59 +import org.osgi.service.component.ComponentContext;
55 import org.projectfloodlight.openflow.protocol.OFFactory; 60 import org.projectfloodlight.openflow.protocol.OFFactory;
56 import org.projectfloodlight.openflow.protocol.OFMessage; 61 import org.projectfloodlight.openflow.protocol.OFMessage;
57 import org.projectfloodlight.openflow.protocol.OFPortConfig; 62 import org.projectfloodlight.openflow.protocol.OFPortConfig;
...@@ -73,10 +78,13 @@ import org.slf4j.Logger; ...@@ -73,10 +78,13 @@ import org.slf4j.Logger;
73 import java.util.ArrayList; 78 import java.util.ArrayList;
74 import java.util.Collection; 79 import java.util.Collection;
75 import java.util.Collections; 80 import java.util.Collections;
81 +import java.util.Dictionary;
76 import java.util.HashMap; 82 import java.util.HashMap;
77 import java.util.HashSet; 83 import java.util.HashSet;
78 import java.util.List; 84 import java.util.List;
79 85
86 +import static com.google.common.base.Strings.isNullOrEmpty;
87 +import static org.onlab.util.Tools.get;
80 import static org.onosproject.net.DeviceId.deviceId; 88 import static org.onosproject.net.DeviceId.deviceId;
81 import static org.onosproject.net.Port.Type.COPPER; 89 import static org.onosproject.net.Port.Type.COPPER;
82 import static org.onosproject.net.Port.Type.FIBER; 90 import static org.onosproject.net.Port.Type.FIBER;
...@@ -100,12 +108,18 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr ...@@ -100,12 +108,18 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr
100 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) 108 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
101 protected OpenFlowController controller; 109 protected OpenFlowController controller;
102 110
111 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
112 + protected ComponentConfigService cfgService;
113 +
103 private DeviceProviderService providerService; 114 private DeviceProviderService providerService;
104 115
105 private final InternalDeviceProvider listener = new InternalDeviceProvider(); 116 private final InternalDeviceProvider listener = new InternalDeviceProvider();
106 117
107 // TODO: We need to make the poll interval configurable. 118 // TODO: We need to make the poll interval configurable.
108 static final int POLL_INTERVAL = 5; 119 static final int POLL_INTERVAL = 5;
120 + @Property(name = "PortStatsPollFrequency", intValue = POLL_INTERVAL,
121 + label = "Frequency (in seconds) for polling switch Port statistics")
122 + private int portStatsPollFrequency = POLL_INTERVAL;
109 123
110 private HashMap<Dpid, PortStatsCollector> collectors = Maps.newHashMap(); 124 private HashMap<Dpid, PortStatsCollector> collectors = Maps.newHashMap();
111 125
...@@ -117,7 +131,8 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr ...@@ -117,7 +131,8 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr
117 } 131 }
118 132
119 @Activate 133 @Activate
120 - public void activate() { 134 + public void activate(ComponentContext context) {
135 + cfgService.registerProperties(getClass());
121 providerService = providerRegistry.register(this); 136 providerService = providerRegistry.register(this);
122 controller.addListener(listener); 137 controller.addListener(listener);
123 controller.addEventListener(listener); 138 controller.addEventListener(listener);
...@@ -130,7 +145,7 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr ...@@ -130,7 +145,7 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr
130 // disconnect to trigger switch-add later 145 // disconnect to trigger switch-add later
131 sw.disconnectSwitch(); 146 sw.disconnectSwitch();
132 } 147 }
133 - PortStatsCollector psc = new PortStatsCollector(sw, POLL_INTERVAL); 148 + PortStatsCollector psc = new PortStatsCollector(sw, portStatsPollFrequency);
134 psc.start(); 149 psc.start();
135 collectors.put(new Dpid(sw.getId()), psc); 150 collectors.put(new Dpid(sw.getId()), psc);
136 } 151 }
...@@ -138,7 +153,8 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr ...@@ -138,7 +153,8 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr
138 } 153 }
139 154
140 @Deactivate 155 @Deactivate
141 - public void deactivate() { 156 + public void deactivate(ComponentContext context) {
157 + cfgService.unregisterProperties(getClass(), false);
142 providerRegistry.unregister(this); 158 providerRegistry.unregister(this);
143 controller.removeListener(listener); 159 controller.removeListener(listener);
144 collectors.values().forEach(PortStatsCollector::stop); 160 collectors.values().forEach(PortStatsCollector::stop);
...@@ -146,6 +162,25 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr ...@@ -146,6 +162,25 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr
146 LOG.info("Stopped"); 162 LOG.info("Stopped");
147 } 163 }
148 164
165 + @Modified
166 + public void modified(ComponentContext context) {
167 + Dictionary<?, ?> properties = context.getProperties();
168 + int newPortStatsPollFrequency;
169 + try {
170 + String s = get(properties, "PortStatsPollFrequency");
171 + newPortStatsPollFrequency = isNullOrEmpty(s) ? portStatsPollFrequency : Integer.parseInt(s.trim());
172 +
173 + } catch (NumberFormatException | ClassCastException e) {
174 + newPortStatsPollFrequency = portStatsPollFrequency;
175 + }
176 +
177 + if (newPortStatsPollFrequency != portStatsPollFrequency) {
178 + portStatsPollFrequency = newPortStatsPollFrequency;
179 + collectors.values().forEach(psc -> psc.adjustPollInterval(portStatsPollFrequency));
180 + }
181 +
182 + LOG.info("Settings: portStatsPollFrequency={}", portStatsPollFrequency);
183 + }
149 184
150 @Override 185 @Override
151 public boolean isReachable(DeviceId deviceId) { 186 public boolean isReachable(DeviceId deviceId) {
...@@ -275,7 +310,7 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr ...@@ -275,7 +310,7 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr
275 providerService.updatePorts(did, buildPortDescriptions(sw)); 310 providerService.updatePorts(did, buildPortDescriptions(sw));
276 311
277 PortStatsCollector psc = 312 PortStatsCollector psc =
278 - new PortStatsCollector(controller.getSwitch(dpid), POLL_INTERVAL); 313 + new PortStatsCollector(controller.getSwitch(dpid), portStatsPollFrequency);
279 psc.start(); 314 psc.start();
280 collectors.put(dpid, psc); 315 collectors.put(dpid, psc);
281 } 316 }
......
...@@ -41,7 +41,7 @@ public class PortStatsCollector implements TimerTask { ...@@ -41,7 +41,7 @@ public class PortStatsCollector implements TimerTask {
41 private final HashedWheelTimer timer = Timer.getTimer(); 41 private final HashedWheelTimer timer = Timer.getTimer();
42 private final OpenFlowSwitch sw; 42 private final OpenFlowSwitch sw;
43 private final Logger log = getLogger(getClass()); 43 private final Logger log = getLogger(getClass());
44 - private final int refreshInterval; 44 + private int refreshInterval;
45 private final AtomicLong xidAtomic = new AtomicLong(1); 45 private final AtomicLong xidAtomic = new AtomicLong(1);
46 46
47 private Timeout timeout; 47 private Timeout timeout;
...@@ -74,6 +74,13 @@ public class PortStatsCollector implements TimerTask { ...@@ -74,6 +74,13 @@ public class PortStatsCollector implements TimerTask {
74 } 74 }
75 } 75 }
76 76
77 + synchronized void adjustPollInterval(int pollInterval) {
78 + this.refreshInterval = pollInterval;
79 + // task.cancel();
80 + // task = new InternalTimerTask();
81 + // timer.scheduleAtFixedRate(task, pollInterval * SECONDS, pollInterval * 1000);
82 + }
83 +
77 private void sendPortStatistic() { 84 private void sendPortStatistic() {
78 if (sw.getRole() != RoleState.MASTER) { 85 if (sw.getRole() != RoleState.MASTER) {
79 return; 86 return;
......
...@@ -18,9 +18,11 @@ package org.onosproject.provider.of.device.impl; ...@@ -18,9 +18,11 @@ package org.onosproject.provider.of.device.impl;
18 import com.google.common.collect.HashMultimap; 18 import com.google.common.collect.HashMultimap;
19 import com.google.common.collect.Lists; 19 import com.google.common.collect.Lists;
20 import com.google.common.collect.Multimap; 20 import com.google.common.collect.Multimap;
21 +
21 import org.junit.After; 22 import org.junit.After;
22 import org.junit.Before; 23 import org.junit.Before;
23 import org.junit.Test; 24 import org.junit.Test;
25 +import org.onosproject.cfg.ComponentConfigAdapter;
24 import org.onosproject.net.DefaultDevice; 26 import org.onosproject.net.DefaultDevice;
25 import org.onosproject.net.Device; 27 import org.onosproject.net.Device;
26 import org.onosproject.net.DeviceId; 28 import org.onosproject.net.DeviceId;
...@@ -84,8 +86,9 @@ public class OpenFlowDeviceProviderTest { ...@@ -84,8 +86,9 @@ public class OpenFlowDeviceProviderTest {
84 public void startUp() { 86 public void startUp() {
85 provider.providerRegistry = registry; 87 provider.providerRegistry = registry;
86 provider.controller = controller; 88 provider.controller = controller;
89 + provider.cfgService = new ComponentConfigAdapter();
87 controller.switchMap.put(DPID1, SW1); 90 controller.switchMap.put(DPID1, SW1);
88 - provider.activate(); 91 + provider.activate(null);
89 assertNotNull("provider should be registered", registry.provider); 92 assertNotNull("provider should be registered", registry.provider);
90 assertNotNull("listener should be registered", controller.listener); 93 assertNotNull("listener should be registered", controller.listener);
91 assertEquals("devices not added", 1, registry.connected.size()); 94 assertEquals("devices not added", 1, registry.connected.size());
...@@ -94,7 +97,7 @@ public class OpenFlowDeviceProviderTest { ...@@ -94,7 +97,7 @@ public class OpenFlowDeviceProviderTest {
94 97
95 @After 98 @After
96 public void tearDown() { 99 public void tearDown() {
97 - provider.deactivate(); 100 + provider.deactivate(null);
98 assertNull("listener should be removed", controller.listener); 101 assertNull("listener should be removed", controller.listener);
99 provider.controller = null; 102 provider.controller = null;
100 provider.providerRegistry = null; 103 provider.providerRegistry = null;
......