Committed by
Gerrit Code Review
Refactoring of NullProviders (device, host, and link)
- Handling reading of integral properties - Setting change handling - Null Host ID generation fix Change-Id: Id000bafe08d7d9e7db2f4eceaede11a29e43eca9
Showing
3 changed files
with
50 additions
and
34 deletions
providers/null/device/src/main/java/org/onosproject/provider/nil/device/impl/NullDeviceProvider.java
| ... | @@ -150,13 +150,13 @@ public class NullDeviceProvider extends AbstractProvider implements DeviceProvid | ... | @@ -150,13 +150,13 @@ public class NullDeviceProvider extends AbstractProvider implements DeviceProvid |
| 150 | int newDevNum = DEF_NUMDEVICES; | 150 | int newDevNum = DEF_NUMDEVICES; |
| 151 | int newPortNum = DEF_NUMPORTS; | 151 | int newPortNum = DEF_NUMPORTS; |
| 152 | try { | 152 | try { |
| 153 | - String s = (String) properties.get("devConfigs"); | 153 | + String s = get(properties, "devConfigs"); |
| 154 | if (!isNullOrEmpty(s)) { | 154 | if (!isNullOrEmpty(s)) { |
| 155 | newDevNum = getDevicesConfig(s); | 155 | newDevNum = getDevicesConfig(s); |
| 156 | } | 156 | } |
| 157 | - s = (String) properties.get("numPorts"); | 157 | + s = get(properties, "numPorts"); |
| 158 | newPortNum = isNullOrEmpty(s) ? DEF_NUMPORTS : Integer.parseInt(s.trim()); | 158 | newPortNum = isNullOrEmpty(s) ? DEF_NUMPORTS : Integer.parseInt(s.trim()); |
| 159 | - } catch (NumberFormatException | ClassCastException e) { | 159 | + } catch (NumberFormatException e) { |
| 160 | log.warn(e.getMessage()); | 160 | log.warn(e.getMessage()); |
| 161 | newDevNum = numDevices; | 161 | newDevNum = numDevices; |
| 162 | newPortNum = numPorts; | 162 | newPortNum = numPorts; | ... | ... |
| ... | @@ -111,7 +111,7 @@ public class NullHostProvider extends AbstractProvider implements HostProvider { | ... | @@ -111,7 +111,7 @@ public class NullHostProvider extends AbstractProvider implements HostProvider { |
| 111 | public void triggerProbe(Host host) {} | 111 | public void triggerProbe(Host host) {} |
| 112 | 112 | ||
| 113 | private void addHosts(Device device) { | 113 | private void addHosts(Device device) { |
| 114 | - String nhash = toHex(nodeService.getLocalNode().hashCode()); | 114 | + String nhash = toHex(nodeService.getLocalNode().id().hashCode()); |
| 115 | String dhash = device.id().toString(); | 115 | String dhash = device.id().toString(); |
| 116 | // make sure this instance owns the device. | 116 | // make sure this instance owns the device. |
| 117 | if (!nhash.substring(nhash.length() - 3) | 117 | if (!nhash.substring(nhash.length() - 3) | ... | ... |
| ... | @@ -15,10 +15,13 @@ | ... | @@ -15,10 +15,13 @@ |
| 15 | */ | 15 | */ |
| 16 | package org.onosproject.provider.nil.link.impl; | 16 | package org.onosproject.provider.nil.link.impl; |
| 17 | 17 | ||
| 18 | +import com.google.common.base.Charsets; | ||
| 18 | import com.google.common.collect.HashMultimap; | 19 | import com.google.common.collect.HashMultimap; |
| 19 | import com.google.common.collect.Lists; | 20 | import com.google.common.collect.Lists; |
| 20 | import com.google.common.collect.Maps; | 21 | import com.google.common.collect.Maps; |
| 21 | import com.google.common.collect.Sets; | 22 | import com.google.common.collect.Sets; |
| 23 | +import com.google.common.io.Files; | ||
| 24 | + | ||
| 22 | import org.apache.felix.scr.annotations.Activate; | 25 | import org.apache.felix.scr.annotations.Activate; |
| 23 | import org.apache.felix.scr.annotations.Component; | 26 | import org.apache.felix.scr.annotations.Component; |
| 24 | import org.apache.felix.scr.annotations.Deactivate; | 27 | import org.apache.felix.scr.annotations.Deactivate; |
| ... | @@ -26,7 +29,6 @@ import org.apache.felix.scr.annotations.Modified; | ... | @@ -26,7 +29,6 @@ import org.apache.felix.scr.annotations.Modified; |
| 26 | import org.apache.felix.scr.annotations.Property; | 29 | import org.apache.felix.scr.annotations.Property; |
| 27 | import org.apache.felix.scr.annotations.Reference; | 30 | import org.apache.felix.scr.annotations.Reference; |
| 28 | import org.apache.felix.scr.annotations.ReferenceCardinality; | 31 | import org.apache.felix.scr.annotations.ReferenceCardinality; |
| 29 | -import org.onlab.util.Tools; | ||
| 30 | import org.onosproject.cfg.ComponentConfigService; | 32 | import org.onosproject.cfg.ComponentConfigService; |
| 31 | import org.onosproject.cluster.ClusterService; | 33 | import org.onosproject.cluster.ClusterService; |
| 32 | import org.onosproject.cluster.NodeId; | 34 | import org.onosproject.cluster.NodeId; |
| ... | @@ -49,7 +51,7 @@ import org.osgi.service.component.ComponentContext; | ... | @@ -49,7 +51,7 @@ import org.osgi.service.component.ComponentContext; |
| 49 | import org.slf4j.Logger; | 51 | import org.slf4j.Logger; |
| 50 | 52 | ||
| 51 | import java.io.BufferedReader; | 53 | import java.io.BufferedReader; |
| 52 | -import java.io.FileReader; | 54 | +import java.io.File; |
| 53 | import java.io.IOException; | 55 | import java.io.IOException; |
| 54 | import java.net.URI; | 56 | import java.net.URI; |
| 55 | import java.net.URISyntaxException; | 57 | import java.net.URISyntaxException; |
| ... | @@ -61,11 +63,12 @@ import java.util.concurrent.Executors; | ... | @@ -61,11 +63,12 @@ import java.util.concurrent.Executors; |
| 61 | import java.util.concurrent.ScheduledExecutorService; | 63 | import java.util.concurrent.ScheduledExecutorService; |
| 62 | import java.util.concurrent.TimeUnit; | 64 | import java.util.concurrent.TimeUnit; |
| 63 | 65 | ||
| 64 | -import static com.google.common.base.Strings.isNullOrEmpty; | ||
| 65 | import static org.onlab.util.Tools.groupedThreads; | 66 | import static org.onlab.util.Tools.groupedThreads; |
| 67 | +import static org.onlab.util.Tools.get; | ||
| 66 | import static org.onlab.util.Tools.toHex; | 68 | import static org.onlab.util.Tools.toHex; |
| 67 | import static org.onosproject.net.Link.Type.DIRECT; | 69 | import static org.onosproject.net.Link.Type.DIRECT; |
| 68 | import static org.slf4j.LoggerFactory.getLogger; | 70 | import static org.slf4j.LoggerFactory.getLogger; |
| 71 | +import static com.google.common.base.Strings.isNullOrEmpty; | ||
| 69 | 72 | ||
| 70 | /** | 73 | /** |
| 71 | * Provider which advertises fake/nonexistent links to the core. To be used for | 74 | * Provider which advertises fake/nonexistent links to the core. To be used for |
| ... | @@ -171,21 +174,21 @@ public class NullLinkProvider extends AbstractProvider implements LinkProvider { | ... | @@ -171,21 +174,21 @@ public class NullLinkProvider extends AbstractProvider implements LinkProvider { |
| 171 | int newRate; | 174 | int newRate; |
| 172 | String newPath; | 175 | String newPath; |
| 173 | try { | 176 | try { |
| 174 | - String s = (String) properties.get("eventRate"); | 177 | + String s = get(properties, "eventRate"); |
| 175 | newRate = isNullOrEmpty(s) ? DEFAULT_RATE : Integer.parseInt(s.trim()); | 178 | newRate = isNullOrEmpty(s) ? DEFAULT_RATE : Integer.parseInt(s.trim()); |
| 176 | s = (String) properties.get("cfgFile"); | 179 | s = (String) properties.get("cfgFile"); |
| 177 | - newPath = s.trim(); | 180 | + newPath = isNullOrEmpty(s) ? CFG_PATH : s.trim(); |
| 178 | - } catch (NumberFormatException | ClassCastException e) { | 181 | + } catch (NumberFormatException e) { |
| 179 | log.warn(e.getMessage()); | 182 | log.warn(e.getMessage()); |
| 180 | newRate = eventRate; | 183 | newRate = eventRate; |
| 181 | newPath = cfgFile; | 184 | newPath = cfgFile; |
| 182 | } | 185 | } |
| 183 | - | 186 | + // find/read topology file. |
| 184 | - // topology file configuration | ||
| 185 | if (!newPath.equals(cfgFile)) { | 187 | if (!newPath.equals(cfgFile)) { |
| 186 | cfgFile = newPath; | 188 | cfgFile = newPath; |
| 187 | } | 189 | } |
| 188 | readGraph(cfgFile, nodeService.getLocalNode().id()); | 190 | readGraph(cfgFile, nodeService.getLocalNode().id()); |
| 191 | + // check for new eventRate settings. | ||
| 189 | if (newRate != eventRate) { | 192 | if (newRate != eventRate) { |
| 190 | if (eventRate < 0) { | 193 | if (eventRate < 0) { |
| 191 | log.warn("Invalid rate, ignoring and using default"); | 194 | log.warn("Invalid rate, ignoring and using default"); |
| ... | @@ -194,11 +197,22 @@ public class NullLinkProvider extends AbstractProvider implements LinkProvider { | ... | @@ -194,11 +197,22 @@ public class NullLinkProvider extends AbstractProvider implements LinkProvider { |
| 194 | eventRate = newRate; | 197 | eventRate = newRate; |
| 195 | } | 198 | } |
| 196 | } | 199 | } |
| 200 | + configureWorkers(); | ||
| 201 | + log.info("Using settings: eventRate={}, topofile={}", eventRate, cfgFile); | ||
| 202 | + } | ||
| 203 | + | ||
| 204 | + // Configures and schedules worker threads based on settings. | ||
| 205 | + private void configureWorkers() { | ||
| 197 | if (eventRate > 0) { | 206 | if (eventRate > 0) { |
| 198 | - if (!flicker) { // previously not flickering | 207 | + // now set to 'flicker', previously not flickering |
| 208 | + if (!flicker) { | ||
| 199 | flicker = true; | 209 | flicker = true; |
| 200 | allocateLinks(); | 210 | allocateLinks(); |
| 201 | - driverMap.remove(DEFAULT); | 211 | + // kill off refresh worker for symmetry |
| 212 | + if (driverMap.containsKey(DEFAULT)) { | ||
| 213 | + driverMap.get(DEFAULT).forEach(d -> d.setTasks(Lists.newArrayList())); | ||
| 214 | + driverMap.remove(DEFAULT); | ||
| 215 | + } | ||
| 202 | for (int i = 0; i < linkTasks.size(); i++) { | 216 | for (int i = 0; i < linkTasks.size(); i++) { |
| 203 | List<LinkDescription> links = linkTasks.get(i); | 217 | List<LinkDescription> links = linkTasks.get(i); |
| 204 | LinkDriver driver = new LinkDriver(links); | 218 | LinkDriver driver = new LinkDriver(links); |
| ... | @@ -208,26 +222,31 @@ public class NullLinkProvider extends AbstractProvider implements LinkProvider { | ... | @@ -208,26 +222,31 @@ public class NullLinkProvider extends AbstractProvider implements LinkProvider { |
| 208 | driverMap.computeIfAbsent(sd, k -> Sets.newConcurrentHashSet()).add(driver); | 222 | driverMap.computeIfAbsent(sd, k -> Sets.newConcurrentHashSet()).add(driver); |
| 209 | driverMap.computeIfAbsent(dd, k -> Sets.newConcurrentHashSet()).add(driver); | 223 | driverMap.computeIfAbsent(dd, k -> Sets.newConcurrentHashSet()).add(driver); |
| 210 | }); | 224 | }); |
| 211 | - try { | 225 | + linkDriver.schedule(driver, eventRate, TimeUnit.MICROSECONDS); |
| 212 | - linkDriver.schedule(driver, eventRate, TimeUnit.MICROSECONDS); | ||
| 213 | - } catch (Exception e) { | ||
| 214 | - log.warn(e.getMessage()); | ||
| 215 | - } | ||
| 216 | } | 226 | } |
| 217 | } | 227 | } |
| 228 | + // no need for was flicker since eventRate will be read by workers | ||
| 218 | } else { | 229 | } else { |
| 230 | + // now set to 'refresh' was 'flicker' before | ||
| 219 | if (flicker) { | 231 | if (flicker) { |
| 220 | driverMap.forEach((dev, lds) -> lds.forEach(l -> l.deviceRemoved(dev))); | 232 | driverMap.forEach((dev, lds) -> lds.forEach(l -> l.deviceRemoved(dev))); |
| 221 | driverMap.clear(); | 233 | driverMap.clear(); |
| 222 | linkTasks.clear(); | 234 | linkTasks.clear(); |
| 235 | + flicker = false; | ||
| 236 | + LinkDriver driver = new LinkDriver(linkDescrs); | ||
| 237 | + driverMap.computeIfAbsent(DEFAULT, k -> Sets.newConcurrentHashSet()).add(driver); | ||
| 238 | + linkDriver.schedule(driver, DEFAULT_RATE, TimeUnit.SECONDS); | ||
| 239 | + // was 'refresh' - something changed or we're just starting. | ||
| 240 | + } else { | ||
| 241 | + if (driverMap.containsKey(DEFAULT)) { | ||
| 242 | + driverMap.forEach((dev, ld) -> ld.forEach(d -> d.setTasks(linkDescrs))); | ||
| 243 | + return; | ||
| 244 | + } | ||
| 245 | + LinkDriver driver = new LinkDriver(linkDescrs); | ||
| 246 | + driverMap.computeIfAbsent(DEFAULT, k -> Sets.newConcurrentHashSet()).add(driver); | ||
| 247 | + linkDriver.schedule(driver, DEFAULT_RATE, TimeUnit.SECONDS); | ||
| 223 | } | 248 | } |
| 224 | - flicker = false; | ||
| 225 | - LinkDriver driver = new LinkDriver(linkDescrs); | ||
| 226 | - driverMap.put(DEFAULT, Sets.newHashSet(driver)); | ||
| 227 | - linkDriver.schedule(driver, REFRESH_RATE, TimeUnit.SECONDS); | ||
| 228 | } | 249 | } |
| 229 | - | ||
| 230 | - log.info("Using settings: eventRate={}, topofile={}", eventRate, cfgFile); | ||
| 231 | } | 250 | } |
| 232 | 251 | ||
| 233 | // parse simplified dot-like topology graph | 252 | // parse simplified dot-like topology graph |
| ... | @@ -236,7 +255,7 @@ public class NullLinkProvider extends AbstractProvider implements LinkProvider { | ... | @@ -236,7 +255,7 @@ public class NullLinkProvider extends AbstractProvider implements LinkProvider { |
| 236 | Set<LinkDescription> read = Sets.newHashSet(); | 255 | Set<LinkDescription> read = Sets.newHashSet(); |
| 237 | BufferedReader br = null; | 256 | BufferedReader br = null; |
| 238 | try { | 257 | try { |
| 239 | - br = new BufferedReader(new FileReader(path)); | 258 | + br = Files.newReader(new File(path), Charsets.US_ASCII); |
| 240 | String cur = br.readLine(); | 259 | String cur = br.readLine(); |
| 241 | while (cur != null) { | 260 | while (cur != null) { |
| 242 | if (cur.startsWith("#")) { | 261 | if (cur.startsWith("#")) { |
| ... | @@ -280,18 +299,12 @@ public class NullLinkProvider extends AbstractProvider implements LinkProvider { | ... | @@ -280,18 +299,12 @@ public class NullLinkProvider extends AbstractProvider implements LinkProvider { |
| 280 | log.warn("Could not close topology file: {}", e); | 299 | log.warn("Could not close topology file: {}", e); |
| 281 | } | 300 | } |
| 282 | } | 301 | } |
| 283 | - Set<LinkDescription> removedLinks = null; | ||
| 284 | synchronized (linkDescrs) { | 302 | synchronized (linkDescrs) { |
| 285 | if (!read.isEmpty()) { | 303 | if (!read.isEmpty()) { |
| 286 | - removedLinks = Sets.difference(Sets.newHashSet(linkDescrs), read); | ||
| 287 | linkDescrs.clear(); | 304 | linkDescrs.clear(); |
| 288 | linkDescrs.addAll(read); | 305 | linkDescrs.addAll(read); |
| 289 | } | 306 | } |
| 290 | } | 307 | } |
| 291 | - if (!Tools.isNullOrEmpty(removedLinks)) { | ||
| 292 | - log.info("Removing {} old link(s)", removedLinks.size()); | ||
| 293 | - removedLinks.forEach(providerService::linkVanished); | ||
| 294 | - } | ||
| 295 | } | 308 | } |
| 296 | 309 | ||
| 297 | // parses a link descriptor to make a LinkDescription | 310 | // parses a link descriptor to make a LinkDescription |
| ... | @@ -348,7 +361,7 @@ public class NullLinkProvider extends AbstractProvider implements LinkProvider { | ... | @@ -348,7 +361,7 @@ public class NullLinkProvider extends AbstractProvider implements LinkProvider { |
| 348 | // recover DeviceId from configs and NodeID | 361 | // recover DeviceId from configs and NodeID |
| 349 | private DeviceId recover(String base, NodeId node) { | 362 | private DeviceId recover(String base, NodeId node) { |
| 350 | long hash = node.hashCode() << 16; | 363 | long hash = node.hashCode() << 16; |
| 351 | - int dev = Integer.valueOf(base); | 364 | + int dev = Integer.parseInt(base); |
| 352 | try { | 365 | try { |
| 353 | return DeviceId.deviceId(new URI("null", toHex(hash | dev), null)); | 366 | return DeviceId.deviceId(new URI("null", toHex(hash | dev), null)); |
| 354 | } catch (URISyntaxException e) { | 367 | } catch (URISyntaxException e) { |
| ... | @@ -360,6 +373,7 @@ public class NullLinkProvider extends AbstractProvider implements LinkProvider { | ... | @@ -360,6 +373,7 @@ public class NullLinkProvider extends AbstractProvider implements LinkProvider { |
| 360 | // adds a LinkDescription to a worker's to-be queue, for flickering | 373 | // adds a LinkDescription to a worker's to-be queue, for flickering |
| 361 | private void allocateLinks() { | 374 | private void allocateLinks() { |
| 362 | int index, lcount = 0; | 375 | int index, lcount = 0; |
| 376 | + linkTasks.clear(); | ||
| 363 | for (LinkDescription ld : linkDescrs) { | 377 | for (LinkDescription ld : linkDescrs) { |
| 364 | index = (lcount % THREADS); | 378 | index = (lcount % THREADS); |
| 365 | log.info("allocation: total={}, index={}", linkDescrs.size(), lcount, index); | 379 | log.info("allocation: total={}, index={}", linkDescrs.size(), lcount, index); |
| ... | @@ -477,15 +491,17 @@ public class NullLinkProvider extends AbstractProvider implements LinkProvider { | ... | @@ -477,15 +491,17 @@ public class NullLinkProvider extends AbstractProvider implements LinkProvider { |
| 477 | 491 | ||
| 478 | public void setTasks(List<LinkDescription> links) { | 492 | public void setTasks(List<LinkDescription> links) { |
| 479 | HashMultimap<ConnectPoint, ConnectPoint> nm = HashMultimap.create(); | 493 | HashMultimap<ConnectPoint, ConnectPoint> nm = HashMultimap.create(); |
| 494 | + List<LinkDescription> rm = Lists.newArrayList(); | ||
| 480 | links.forEach(v -> nm.put(v.src(), v.dst())); | 495 | links.forEach(v -> nm.put(v.src(), v.dst())); |
| 481 | // remove and send linkVanished for stale links. | 496 | // remove and send linkVanished for stale links. |
| 482 | for (LinkDescription l : tasks) { | 497 | for (LinkDescription l : tasks) { |
| 483 | if (!nm.containsEntry(l.src(), l.dst())) { | 498 | if (!nm.containsEntry(l.src(), l.dst())) { |
| 484 | - providerService.linkVanished(l); | 499 | + rm.add(l); |
| 485 | } | 500 | } |
| 486 | } | 501 | } |
| 487 | tasks.clear(); | 502 | tasks.clear(); |
| 488 | tasks.addAll(links); | 503 | tasks.addAll(links); |
| 504 | + rm.forEach(l -> providerService.linkVanished(l)); | ||
| 489 | } | 505 | } |
| 490 | } | 506 | } |
| 491 | 507 | ... | ... |
-
Please register or login to post a comment