HIGUCHI Yuta
Committed by Gerrit Code Review

Bug fixes for ONOS-3509

- Forwarding behavior added to {Device,Link}Store by ONOS-490
  cauesed false update information sent from ONOS node, which has been detached from the cluster,
  to be accepted by rest of the cluster after the detached node has rejoined cluster.

- Fix for periodic mastership check was left out
  when MastershipService#requestRoleFor(..) return value was changed to Future.

- Fix for triggerProbe() related messages getting dropped,
  right after STANDBY -> MASTER role change.

- Local state (connectedDevices) was preventing
  vertical (Core -> switch) Mastership state synchronization.

- Various debug log, comment added during investigation.

Change-Id: I777beadf04db8a879830a07bfdc7ab0e2279f190
...@@ -31,20 +31,23 @@ public class LeadershipEvent extends AbstractEvent<LeadershipEvent.Type, Leaders ...@@ -31,20 +31,23 @@ public class LeadershipEvent extends AbstractEvent<LeadershipEvent.Type, Leaders
31 */ 31 */
32 public enum Type { 32 public enum Type {
33 /** 33 /**
34 - * Signifies that the leader has been elected. The event subject is the 34 + * Signifies that the leader has been elected.
35 - * new leader. 35 + * The event subject is the new leader.
36 + * This event does not guarantee accurate candidate information.
36 */ 37 */
37 LEADER_ELECTED, 38 LEADER_ELECTED,
38 39
39 /** 40 /**
40 - * Signifies that the leader has been re-elected. The event subject is the 41 + * Signifies that the leader has been re-elected.
41 - * leader. 42 + * The event subject is the leader.
43 + * This event does not guarantee accurate candidate information.
42 */ 44 */
43 LEADER_REELECTED, 45 LEADER_REELECTED,
44 46
45 /** 47 /**
46 - * Signifies that the leader has been booted and lost leadership. The 48 + * Signifies that the leader has been booted and lost leadership.
47 - * event subject is the former leader. 49 + * The event subject is the former leader.
50 + * This event does not guarantee accurate candidate information.
48 */ 51 */
49 LEADER_BOOTED, 52 LEADER_BOOTED,
50 53
......
...@@ -491,9 +491,12 @@ public class DeviceManager ...@@ -491,9 +491,12 @@ public class DeviceManager
491 if (Objects.equals(requested, mastershipService.getLocalRole(deviceId))) { 491 if (Objects.equals(requested, mastershipService.getLocalRole(deviceId))) {
492 return; 492 return;
493 } else { 493 } else {
494 - return; 494 + log.warn("Role mismatch on {}. set to {}, but store demands {}",
495 - // FIXME roleManager got the device to comply, but doesn't agree with 495 + deviceId, response, mastershipService.getLocalRole(deviceId));
496 + // roleManager got the device to comply, but doesn't agree with
496 // the store; use the store's view, then try to reassert. 497 // the store; use the store's view, then try to reassert.
498 + backgroundService.submit(() -> reassertRole(deviceId, mastershipService.getLocalRole(deviceId)));
499 + return;
497 } 500 }
498 } else { 501 } else {
499 // we didn't get back what we asked for. Reelect someone else. 502 // we didn't get back what we asked for. Reelect someone else.
...@@ -547,6 +550,7 @@ public class DeviceManager ...@@ -547,6 +550,7 @@ public class DeviceManager
547 provider.roleChanged(deviceId, newRole); 550 provider.roleChanged(deviceId, newRole);
548 551
549 if (newRole.equals(MastershipRole.MASTER)) { 552 if (newRole.equals(MastershipRole.MASTER)) {
553 + log.debug("sent TriggerProbe({})", deviceId);
550 // only trigger event when request was sent to provider 554 // only trigger event when request was sent to provider
551 provider.triggerProbe(deviceId); 555 provider.triggerProbe(deviceId);
552 } 556 }
...@@ -565,12 +569,19 @@ public class DeviceManager ...@@ -565,12 +569,19 @@ public class DeviceManager
565 569
566 MastershipRole myNextRole = nextRole; 570 MastershipRole myNextRole = nextRole;
567 if (myNextRole == NONE) { 571 if (myNextRole == NONE) {
568 - mastershipService.requestRoleFor(did); 572 + try {
569 - MastershipTerm term = termService.getMastershipTerm(did); 573 + mastershipService.requestRoleFor(did).get();
570 - if (term != null && localNodeId.equals(term.master())) { 574 + MastershipTerm term = termService.getMastershipTerm(did);
571 - myNextRole = MASTER; 575 + if (term != null && localNodeId.equals(term.master())) {
572 - } else { 576 + myNextRole = MASTER;
573 - myNextRole = STANDBY; 577 + } else {
578 + myNextRole = STANDBY;
579 + }
580 + } catch (InterruptedException e) {
581 + Thread.currentThread().interrupt();
582 + log.error("Interrupted waiting for Mastership", e);
583 + } catch (ExecutionException e) {
584 + log.error("Encountered an error waiting for Mastership", e);
574 } 585 }
575 } 586 }
576 587
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
15 */ 15 */
16 package org.onosproject.store.cluster.impl; 16 package org.onosproject.store.cluster.impl;
17 17
18 +import com.google.common.base.MoreObjects;
18 import com.google.common.collect.ImmutableSet; 19 import com.google.common.collect.ImmutableSet;
19 import com.google.common.collect.Maps; 20 import com.google.common.collect.Maps;
20 21
...@@ -163,7 +164,7 @@ public class DistributedClusterStore ...@@ -163,7 +164,7 @@ public class DistributedClusterStore
163 @Override 164 @Override
164 public State getState(NodeId nodeId) { 165 public State getState(NodeId nodeId) {
165 checkNotNull(nodeId, INSTANCE_ID_NULL); 166 checkNotNull(nodeId, INSTANCE_ID_NULL);
166 - return nodeStates.get(nodeId); 167 + return MoreObjects.firstNonNull(nodeStates.get(nodeId), State.INACTIVE);
167 } 168 }
168 169
169 @Override 170 @Override
......
...@@ -96,17 +96,26 @@ public class DistributedLeadershipManager implements LeadershipService { ...@@ -96,17 +96,26 @@ public class DistributedLeadershipManager implements LeadershipService {
96 protected EventDeliveryService eventDispatcher; 96 protected EventDeliveryService eventDispatcher;
97 97
98 private final Logger log = getLogger(getClass()); 98 private final Logger log = getLogger(getClass());
99 +
99 private ScheduledExecutorService electionRunner; 100 private ScheduledExecutorService electionRunner;
100 private ScheduledExecutorService lockExecutor; 101 private ScheduledExecutorService lockExecutor;
101 private ScheduledExecutorService staleLeadershipPurgeExecutor; 102 private ScheduledExecutorService staleLeadershipPurgeExecutor;
102 private ScheduledExecutorService leadershipRefresher; 103 private ScheduledExecutorService leadershipRefresher;
103 104
105 + // leader for each topic
104 private ConsistentMap<String, NodeId> leaderMap; 106 private ConsistentMap<String, NodeId> leaderMap;
107 + // list of candidates (includes chosen leader) for each topic
105 private ConsistentMap<String, List<NodeId>> candidateMap; 108 private ConsistentMap<String, List<NodeId>> candidateMap;
106 109
107 private ListenerRegistry<LeadershipEvent, LeadershipEventListener> listenerRegistry; 110 private ListenerRegistry<LeadershipEvent, LeadershipEventListener> listenerRegistry;
111 +
112 + // cached copy of leaderMap
113 + // Note: Map value, Leadership, does not contain proper candidates info
108 private final Map<String, Leadership> leaderBoard = Maps.newConcurrentMap(); 114 private final Map<String, Leadership> leaderBoard = Maps.newConcurrentMap();
115 + // cached copy of candidateMap
116 + // Note: Map value, Leadership, does not contain proper leader info
109 private final Map<String, Leadership> candidateBoard = Maps.newConcurrentMap(); 117 private final Map<String, Leadership> candidateBoard = Maps.newConcurrentMap();
118 +
110 private final ClusterEventListener clusterEventListener = new InternalClusterEventListener(); 119 private final ClusterEventListener clusterEventListener = new InternalClusterEventListener();
111 120
112 private NodeId localNodeId; 121 private NodeId localNodeId;
......
...@@ -286,6 +286,11 @@ public class ECDeviceStore ...@@ -286,6 +286,11 @@ public class ECDeviceStore
286 deviceDescriptions.put(new DeviceKey(providerId, deviceId), deviceDescription); 286 deviceDescriptions.put(new DeviceKey(providerId, deviceId), deviceDescription);
287 return refreshDeviceCache(providerId, deviceId); 287 return refreshDeviceCache(providerId, deviceId);
288 } else { 288 } else {
289 + // Only forward for ConfigProvider
290 + // Forwarding was added as a workaround for ONOS-490
291 + if (!providerId.equals("cfg")) {
292 + return null;
293 + }
289 DeviceInjectedEvent deviceInjectedEvent = new DeviceInjectedEvent(providerId, deviceId, deviceDescription); 294 DeviceInjectedEvent deviceInjectedEvent = new DeviceInjectedEvent(providerId, deviceId, deviceDescription);
290 return Futures.getUnchecked( 295 return Futures.getUnchecked(
291 clusterCommunicator.sendAndReceive(deviceInjectedEvent, 296 clusterCommunicator.sendAndReceive(deviceInjectedEvent,
...@@ -413,6 +418,11 @@ public class ECDeviceStore ...@@ -413,6 +418,11 @@ public class ECDeviceStore
413 }); 418 });
414 deviceEvents = refreshDevicePortCache(providerId, deviceId, Optional.empty()); 419 deviceEvents = refreshDevicePortCache(providerId, deviceId, Optional.empty());
415 } else { 420 } else {
421 + // Only forward for ConfigProvider
422 + // Forwarding was added as a workaround for ONOS-490
423 + if (!providerId.equals("cfg")) {
424 + return null;
425 + }
416 if (master == null) { 426 if (master == null) {
417 return Collections.emptyList(); 427 return Collections.emptyList();
418 } 428 }
......
...@@ -330,6 +330,11 @@ public class GossipDeviceStore ...@@ -330,6 +330,11 @@ public class GossipDeviceStore
330 } 330 }
331 331
332 } else { 332 } else {
333 + // Only forward for ConfigProvider
334 + // Forwarding was added as a workaround for ONOS-490
335 + if (!providerId.equals("cfg")) {
336 + return null;
337 + }
333 // FIXME Temporary hack for NPE (ONOS-1171). 338 // FIXME Temporary hack for NPE (ONOS-1171).
334 // Proper fix is to implement forwarding to master on ConfigProvider 339 // Proper fix is to implement forwarding to master on ConfigProvider
335 // redo ONOS-490 340 // redo ONOS-490
...@@ -579,6 +584,11 @@ public class GossipDeviceStore ...@@ -579,6 +584,11 @@ public class GossipDeviceStore
579 } 584 }
580 585
581 } else { 586 } else {
587 + // Only forward for ConfigProvider
588 + // Forwarding was added as a workaround for ONOS-490
589 + if (!providerId.equals("cfg")) {
590 + return null;
591 + }
582 // FIXME Temporary hack for NPE (ONOS-1171). 592 // FIXME Temporary hack for NPE (ONOS-1171).
583 // Proper fix is to implement forwarding to master on ConfigProvider 593 // Proper fix is to implement forwarding to master on ConfigProvider
584 // redo ONOS-490 594 // redo ONOS-490
......
...@@ -218,6 +218,13 @@ public class ECLinkStore ...@@ -218,6 +218,13 @@ public class ECLinkStore
218 linkDescriptions.compute(internalLinkKey, (k, v) -> createOrUpdateLinkInternal(v , linkDescription)); 218 linkDescriptions.compute(internalLinkKey, (k, v) -> createOrUpdateLinkInternal(v , linkDescription));
219 return refreshLinkCache(linkKey); 219 return refreshLinkCache(linkKey);
220 } else { 220 } else {
221 + // Only forward for ConfigProvider
222 + // Forwarding was added as a workaround for ONOS-490
223 + if (!providerId.equals("cfg")) {
224 + return null;
225 + }
226 + // Temporary hack for NPE (ONOS-1171).
227 + // Proper fix is to implement forwarding to master on ConfigProvider
221 if (dstNodeId == null) { 228 if (dstNodeId == null) {
222 return null; 229 return null;
223 } 230 }
......
...@@ -323,6 +323,11 @@ public class GossipLinkStore ...@@ -323,6 +323,11 @@ public class GossipLinkStore
323 } 323 }
324 324
325 } else { 325 } else {
326 + // Only forward for ConfigProvider
327 + // Forwarding was added as a workaround for ONOS-490
328 + if (!providerId.equals("cfg")) {
329 + return null;
330 + }
326 // FIXME Temporary hack for NPE (ONOS-1171). 331 // FIXME Temporary hack for NPE (ONOS-1171).
327 // Proper fix is to implement forwarding to master on ConfigProvider 332 // Proper fix is to implement forwarding to master on ConfigProvider
328 // redo ONOS-490 333 // redo ONOS-490
......
...@@ -159,20 +159,12 @@ public class ConsistentDeviceMastershipStore ...@@ -159,20 +159,12 @@ public class ConsistentDeviceMastershipStore
159 checkArgument(deviceId != null, DEVICE_ID_NULL); 159 checkArgument(deviceId != null, DEVICE_ID_NULL);
160 160
161 String leadershipTopic = createDeviceMastershipTopic(deviceId); 161 String leadershipTopic = createDeviceMastershipTopic(deviceId);
162 - if (connectedDevices.add(deviceId)) { 162 + connectedDevices.add(deviceId);
163 - return leadershipService.runForLeadership(leadershipTopic) 163 + return leadershipService.runForLeadership(leadershipTopic)
164 - .thenApply(leadership -> { 164 + .thenApply(leadership -> {
165 - return Objects.equal(localNodeId, leadership.leader()) 165 + return Objects.equal(localNodeId, leadership.leader())
166 - ? MastershipRole.MASTER : MastershipRole.STANDBY; 166 + ? MastershipRole.MASTER : MastershipRole.STANDBY;
167 - }); 167 + });
168 - } else {
169 - NodeId leader = leadershipService.getLeader(leadershipTopic);
170 - if (Objects.equal(localNodeId, leader)) {
171 - return CompletableFuture.completedFuture(MastershipRole.MASTER);
172 - } else {
173 - return CompletableFuture.completedFuture(MastershipRole.STANDBY);
174 - }
175 - }
176 } 168 }
177 169
178 @Override 170 @Override
......
...@@ -97,6 +97,9 @@ public abstract class AbstractOpenFlowSwitch extends AbstractHandlerBehaviour ...@@ -97,6 +97,9 @@ public abstract class AbstractOpenFlowSwitch extends AbstractHandlerBehaviour
97 protected ExecutorService executorMsgs = 97 protected ExecutorService executorMsgs =
98 Executors.newFixedThreadPool(2, groupedThreads("onos/of", "ctrl-msg-stats-%d")); 98 Executors.newFixedThreadPool(2, groupedThreads("onos/of", "ctrl-msg-stats-%d"));
99 99
100 + // messagesPendingMastership is used as synchronization variable for
101 + // all mastership related changes. In this block, mastership (including
102 + // role update) will have either occurred or not.
100 private final AtomicReference<List<OFMessage>> messagesPendingMastership 103 private final AtomicReference<List<OFMessage>> messagesPendingMastership
101 = new AtomicReference<>(); 104 = new AtomicReference<>();
102 105
...@@ -275,6 +278,8 @@ public abstract class AbstractOpenFlowSwitch extends AbstractHandlerBehaviour ...@@ -275,6 +278,8 @@ public abstract class AbstractOpenFlowSwitch extends AbstractHandlerBehaviour
275 public final void handleMessage(OFMessage m) { 278 public final void handleMessage(OFMessage m) {
276 if (this.role == RoleState.MASTER || m instanceof OFPortStatus) { 279 if (this.role == RoleState.MASTER || m instanceof OFPortStatus) {
277 this.agent.processMessage(dpid, m); 280 this.agent.processMessage(dpid, m);
281 + } else {
282 + log.trace("Dropping received message {}, was not MASTER", m);
278 } 283 }
279 } 284 }
280 285
...@@ -309,7 +314,8 @@ public abstract class AbstractOpenFlowSwitch extends AbstractHandlerBehaviour ...@@ -309,7 +314,8 @@ public abstract class AbstractOpenFlowSwitch extends AbstractHandlerBehaviour
309 synchronized (messagesPendingMastership) { 314 synchronized (messagesPendingMastership) {
310 List<OFMessage> messages = messagesPendingMastership.get(); 315 List<OFMessage> messages = messagesPendingMastership.get();
311 if (messages != null) { 316 if (messages != null) {
312 - this.sendMsg(messages); 317 + // Cannot use sendMsg here. It will only append to pending list.
318 + sendMsgsOnChannel(messages);
313 log.debug("Sending {} pending messages to switch {}", 319 log.debug("Sending {} pending messages to switch {}",
314 messages.size(), dpid); 320 messages.size(), dpid);
315 messagesPendingMastership.set(null); 321 messagesPendingMastership.set(null);
......
...@@ -73,12 +73,12 @@ import java.util.LinkedList; ...@@ -73,12 +73,12 @@ import java.util.LinkedList;
73 import java.util.List; 73 import java.util.List;
74 import java.util.Set; 74 import java.util.Set;
75 import java.util.concurrent.ConcurrentHashMap; 75 import java.util.concurrent.ConcurrentHashMap;
76 +import java.util.concurrent.ConcurrentMap;
76 import java.util.concurrent.CopyOnWriteArraySet; 77 import java.util.concurrent.CopyOnWriteArraySet;
77 import java.util.concurrent.ExecutorService; 78 import java.util.concurrent.ExecutorService;
78 import java.util.concurrent.Executors; 79 import java.util.concurrent.Executors;
79 import java.util.concurrent.locks.Lock; 80 import java.util.concurrent.locks.Lock;
80 import java.util.concurrent.locks.ReentrantLock; 81 import java.util.concurrent.locks.ReentrantLock;
81 -
82 import static org.onlab.util.Tools.groupedThreads; 82 import static org.onlab.util.Tools.groupedThreads;
83 83
84 @Component(immediate = true) 84 @Component(immediate = true)
...@@ -118,11 +118,11 @@ public class OpenFlowControllerImpl implements OpenFlowController { ...@@ -118,11 +118,11 @@ public class OpenFlowControllerImpl implements OpenFlowController {
118 private final ExecutorService executorBarrier = 118 private final ExecutorService executorBarrier =
119 Executors.newFixedThreadPool(4, groupedThreads("onos/of", "event-barrier-%d")); 119 Executors.newFixedThreadPool(4, groupedThreads("onos/of", "event-barrier-%d"));
120 120
121 - protected ConcurrentHashMap<Dpid, OpenFlowSwitch> connectedSwitches = 121 + protected ConcurrentMap<Dpid, OpenFlowSwitch> connectedSwitches =
122 new ConcurrentHashMap<>(); 122 new ConcurrentHashMap<>();
123 - protected ConcurrentHashMap<Dpid, OpenFlowSwitch> activeMasterSwitches = 123 + protected ConcurrentMap<Dpid, OpenFlowSwitch> activeMasterSwitches =
124 new ConcurrentHashMap<>(); 124 new ConcurrentHashMap<>();
125 - protected ConcurrentHashMap<Dpid, OpenFlowSwitch> activeEqualSwitches = 125 + protected ConcurrentMap<Dpid, OpenFlowSwitch> activeEqualSwitches =
126 new ConcurrentHashMap<>(); 126 new ConcurrentHashMap<>();
127 127
128 protected OpenFlowSwitchAgent agent = new OpenFlowSwitchAgent(); 128 protected OpenFlowSwitchAgent agent = new OpenFlowSwitchAgent();
...@@ -280,6 +280,7 @@ public class OpenFlowControllerImpl implements OpenFlowController { ...@@ -280,6 +280,7 @@ public class OpenFlowControllerImpl implements OpenFlowController {
280 executorMsgs.submit(new OFMessageHandler(dpid, msg)); 280 executorMsgs.submit(new OFMessageHandler(dpid, msg));
281 break; 281 break;
282 case ERROR: 282 case ERROR:
283 + log.debug("Received error message from {}: {}", dpid, msg);
283 executorMsgs.submit(new OFMessageHandler(dpid, msg)); 284 executorMsgs.submit(new OFMessageHandler(dpid, msg));
284 break; 285 break;
285 case STATS_REPLY: 286 case STATS_REPLY:
......
...@@ -64,6 +64,7 @@ import org.onosproject.net.config.NetworkConfigEvent; ...@@ -64,6 +64,7 @@ import org.onosproject.net.config.NetworkConfigEvent;
64 import org.onosproject.net.config.NetworkConfigListener; 64 import org.onosproject.net.config.NetworkConfigListener;
65 import org.onosproject.net.config.NetworkConfigRegistry; 65 import org.onosproject.net.config.NetworkConfigRegistry;
66 import org.onosproject.net.device.DeviceEvent; 66 import org.onosproject.net.device.DeviceEvent;
67 +import org.onosproject.net.device.DeviceEvent.Type;
67 import org.onosproject.net.device.DeviceListener; 68 import org.onosproject.net.device.DeviceListener;
68 import org.onosproject.net.device.DeviceService; 69 import org.onosproject.net.device.DeviceService;
69 import org.onosproject.net.flow.DefaultTrafficSelector; 70 import org.onosproject.net.flow.DefaultTrafficSelector;
...@@ -568,6 +569,9 @@ public class LldpLinkProvider extends AbstractProvider implements LinkProvider { ...@@ -568,6 +569,9 @@ public class LldpLinkProvider extends AbstractProvider implements LinkProvider {
568 private class InternalDeviceListener implements DeviceListener { 569 private class InternalDeviceListener implements DeviceListener {
569 @Override 570 @Override
570 public void event(DeviceEvent event) { 571 public void event(DeviceEvent event) {
572 + if (event.type() == Type.PORT_STATS_UPDATED) {
573 + return;
574 + }
571 Device device = event.subject(); 575 Device device = event.subject();
572 Port port = event.port(); 576 Port port = event.port();
573 if (device == null) { 577 if (device == null) {
......
...@@ -268,7 +268,7 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr ...@@ -268,7 +268,7 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr
268 LOG.error("Unknown Mastership state : {}", newRole); 268 LOG.error("Unknown Mastership state : {}", newRole);
269 269
270 } 270 }
271 - LOG.debug("Accepting mastership role change for device {}", deviceId); 271 + LOG.debug("Accepting mastership role change to {} for device {}", newRole, deviceId);
272 } 272 }
273 273
274 274
...@@ -297,7 +297,7 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr ...@@ -297,7 +297,7 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr
297 } 297 }
298 298
299 private void pushPortMetrics(Dpid dpid, List<OFPortStatsEntry> portStatsEntries) { 299 private void pushPortMetrics(Dpid dpid, List<OFPortStatsEntry> portStatsEntries) {
300 - DeviceId deviceId = DeviceId.deviceId(dpid.uri(dpid)); 300 + DeviceId deviceId = DeviceId.deviceId(Dpid.uri(dpid));
301 Collection<PortStatistics> stats = buildPortStatistics(deviceId, portStatsEntries); 301 Collection<PortStatistics> stats = buildPortStatistics(deviceId, portStatsEntries);
302 providerService.updatePortStatistics(deviceId, stats); 302 providerService.updatePortStatistics(deviceId, stats);
303 } 303 }
...@@ -434,6 +434,7 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr ...@@ -434,6 +434,7 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr
434 434
435 @Override 435 @Override
436 public void switchChanged(Dpid dpid) { 436 public void switchChanged(Dpid dpid) {
437 + LOG.debug("switchChanged({})", dpid);
437 if (providerService == null) { 438 if (providerService == null) {
438 return; 439 return;
439 } 440 }
...@@ -442,17 +443,21 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr ...@@ -442,17 +443,21 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr
442 if (sw == null) { 443 if (sw == null) {
443 return; 444 return;
444 } 445 }
445 - providerService.updatePorts(did, buildPortDescriptions(sw)); 446 + final List<PortDescription> ports = buildPortDescriptions(sw);
447 + LOG.debug("switchChanged({}) {}", did, ports);
448 + providerService.updatePorts(did, ports);
446 } 449 }
447 450
448 @Override 451 @Override
449 public void portChanged(Dpid dpid, OFPortStatus status) { 452 public void portChanged(Dpid dpid, OFPortStatus status) {
453 + LOG.debug("portChanged({},{})", dpid, status);
450 PortDescription portDescription = buildPortDescription(status); 454 PortDescription portDescription = buildPortDescription(status);
451 providerService.portStatusChanged(deviceId(uri(dpid)), portDescription); 455 providerService.portStatusChanged(deviceId(uri(dpid)), portDescription);
452 } 456 }
453 457
454 @Override 458 @Override
455 public void receivedRoleReply(Dpid dpid, RoleState requested, RoleState response) { 459 public void receivedRoleReply(Dpid dpid, RoleState requested, RoleState response) {
460 + LOG.debug("receivedRoleReply({},{},{})", dpid, requested, response);
456 MastershipRole request = roleOf(requested); 461 MastershipRole request = roleOf(requested);
457 MastershipRole reply = roleOf(response); 462 MastershipRole reply = roleOf(response);
458 providerService.receivedRoleReply(deviceId(uri(dpid)), request, reply); 463 providerService.receivedRoleReply(deviceId(uri(dpid)), request, reply);
...@@ -503,7 +508,7 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr ...@@ -503,7 +508,7 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr
503 LOG.debug("Ports Of{}", portsOf); 508 LOG.debug("Ports Of{}", portsOf);
504 portsOf.forEach( 509 portsOf.forEach(
505 op -> { 510 op -> {
506 - portDescs.add(buildPortDescription(type, (OFObject) op)); 511 + portDescs.add(buildPortDescription(type, op));
507 } 512 }
508 ); 513 );
509 }); 514 });
......
...@@ -353,10 +353,12 @@ public class OpenFlowGroupProvider extends AbstractProvider implements GroupProv ...@@ -353,10 +353,12 @@ public class OpenFlowGroupProvider extends AbstractProvider implements GroupProv
353 return; 353 return;
354 } 354 }
355 if (isGroupSupported(sw)) { 355 if (isGroupSupported(sw)) {
356 - GroupStatsCollector gsc = new GroupStatsCollector( 356 + GroupStatsCollector gsc = new GroupStatsCollector(sw, POLL_INTERVAL);
357 - controller.getSwitch(dpid), POLL_INTERVAL);
358 gsc.start(); 357 gsc.start();
359 - collectors.put(dpid, gsc); 358 + GroupStatsCollector prevGsc = collectors.put(dpid, gsc);
359 + if (prevGsc != null) {
360 + prevGsc.stop();
361 + }
360 } 362 }
361 363
362 //figure out race condition 364 //figure out race condition
......