Ayaka Koshibe

vertical feedback path for Role replies

Change-Id: I31bdb85f90901ec79147adeea0df8ceae00ed1dc
...@@ -61,12 +61,12 @@ public interface DeviceProviderService extends ProviderService<DeviceProvider> { ...@@ -61,12 +61,12 @@ public interface DeviceProviderService extends ProviderService<DeviceProvider> {
61 void portStatusChanged(DeviceId deviceId, PortDescription portDescription); 61 void portStatusChanged(DeviceId deviceId, PortDescription portDescription);
62 62
63 /** 63 /**
64 - * Notifies the core about the providers inability to assert the specified 64 + * Notifies the core about the result of a RoleRequest sent to a device.
65 - * mastership role on the device.
66 * 65 *
67 * @param deviceId identity of the device 66 * @param deviceId identity of the device
68 - * @param role mastership role that was asserted but failed 67 + * @param requested mastership role that was requested by the node
68 + * @param replied mastership role the switch accepted
69 */ 69 */
70 - void unableToAssertRole(DeviceId deviceId, MastershipRole role); 70 + void receivedRoleReply(DeviceId deviceId, MastershipRole requested, MastershipRole response);
71 71
72 } 72 }
......
...@@ -367,17 +367,49 @@ public class DeviceManager ...@@ -367,17 +367,49 @@ public class DeviceManager
367 } 367 }
368 368
369 @Override 369 @Override
370 - public void unableToAssertRole(DeviceId deviceId, MastershipRole role) { 370 + public void receivedRoleReply(
371 + DeviceId deviceId, MastershipRole requested, MastershipRole response) {
372 + // Several things can happen here:
373 + // 1. request and response match
374 + // 2. request and response don't match
375 + // 3. MastershipRole and requested match (and 1 or 2 are true)
376 + // 4. MastershipRole and requested don't match (and 1 or 2 are true)
377 + //
378 + // 2, 4, and 3 with case 2 are failure modes.
379 +
371 // FIXME: implement response to this notification 380 // FIXME: implement response to this notification
372 - log.warn("Failed to assert role [{}] onto Device {}", role, 381 +
373 - deviceId); 382 + log.info("got reply to a role request for {}: asked for {}, and got {}",
374 - if (role == MastershipRole.MASTER) { 383 + deviceId, requested, response);
384 +
385 + if (requested == null && response == null) {
386 + // something was off with DeviceProvider, maybe check channel too?
387 + log.warn("Failed to assert role [{}] onto Device {}", requested, deviceId);
388 + mastershipService.relinquishMastership(deviceId);
389 + return;
390 + }
391 +
392 + if (requested.equals(response)) {
393 + if (requested.equals(mastershipService.getLocalRole(deviceId))) {
394 +
395 + return;
396 + } else {
397 + return;
398 + // FIXME roleManager got the device to comply, but doesn't agree with
399 + // the store; use the store's view, then try to reassert.
400 + }
401 + } else {
402 + // we didn't get back what we asked for. Reelect someone else.
403 + log.warn("Failed to assert role [{}] onto Device {}", response, deviceId);
404 + if (response == MastershipRole.MASTER) {
375 mastershipService.relinquishMastership(deviceId); 405 mastershipService.relinquishMastership(deviceId);
376 // TODO: Shouldn't we be triggering event? 406 // TODO: Shouldn't we be triggering event?
377 //final Device device = getDevice(deviceId); 407 //final Device device = getDevice(deviceId);
378 //post(new DeviceEvent(DEVICE_MASTERSHIP_CHANGED, device)); 408 //post(new DeviceEvent(DEVICE_MASTERSHIP_CHANGED, device));
379 } 409 }
380 } 410 }
411 +
412 + }
381 } 413 }
382 414
383 // Posts the specified event to the local event dispatcher. 415 // Posts the specified event to the local event dispatcher.
......
...@@ -121,11 +121,12 @@ public interface OpenFlowSwitch { ...@@ -121,11 +121,12 @@ public interface OpenFlowSwitch {
121 public void disconnectSwitch(); 121 public void disconnectSwitch();
122 122
123 /** 123 /**
124 - * Notifies the controller that role assertion has failed. 124 + * Notifies the controller that the device has responded to a set-role request.
125 * 125 *
126 - * @param role the failed role 126 + * @param requested the role requested by the controller
127 + * @param response the role set at the device
127 */ 128 */
128 - public void returnRoleAssertFailure(RoleState role); 129 + public void returnRoleReply(RoleState requested, RoleState reponse);
129 130
130 /** 131 /**
131 * Indicates if this switch is optical. 132 * Indicates if this switch is optical.
......
...@@ -53,5 +53,5 @@ public interface OpenFlowSwitchListener { ...@@ -53,5 +53,5 @@ public interface OpenFlowSwitchListener {
53 * @param dpid the switch that failed role assertion 53 * @param dpid the switch that failed role assertion
54 * @param role the role imposed by the controller 54 * @param role the role imposed by the controller
55 */ 55 */
56 - public void roleAssertFailed(Dpid dpid, RoleState role); 56 + public void receivedRoleReply(Dpid dpid, RoleState requested, RoleState response);
57 } 57 }
......
...@@ -217,8 +217,8 @@ public abstract class AbstractOpenFlowSwitch implements OpenFlowSwitchDriver { ...@@ -217,8 +217,8 @@ public abstract class AbstractOpenFlowSwitch implements OpenFlowSwitchDriver {
217 } 217 }
218 218
219 @Override 219 @Override
220 - public void returnRoleAssertFailure(RoleState role) { 220 + public void returnRoleReply(RoleState requested, RoleState response) {
221 - this.agent.returnRoleAssertFailed(dpid, role); 221 + this.agent.returnRoleReply(dpid, requested, response);
222 } 222 }
223 223
224 @Override 224 @Override
...@@ -300,6 +300,7 @@ public abstract class AbstractOpenFlowSwitch implements OpenFlowSwitchDriver { ...@@ -300,6 +300,7 @@ public abstract class AbstractOpenFlowSwitch implements OpenFlowSwitchDriver {
300 this.transitionToEqualSwitch(); 300 this.transitionToEqualSwitch();
301 } 301 }
302 } else { 302 } else {
303 + log.warn(">>> mismatch with expected role - got {} - Disconnecting", r);
303 this.disconnectSwitch(); 304 this.disconnectSwitch();
304 } 305 }
305 } 306 }
......
...@@ -97,5 +97,5 @@ public interface OpenFlowAgent { ...@@ -97,5 +97,5 @@ public interface OpenFlowAgent {
97 * @param dpid the switch that failed role assertion 97 * @param dpid the switch that failed role assertion
98 * @param role the failed role 98 * @param role the failed role
99 */ 99 */
100 - public void returnRoleAssertFailed(Dpid dpid, RoleState role); 100 + public void returnRoleReply(Dpid dpid, RoleState requested, RoleState response);
101 } 101 }
......
...@@ -374,9 +374,9 @@ public class OpenFlowControllerImpl implements OpenFlowController { ...@@ -374,9 +374,9 @@ public class OpenFlowControllerImpl implements OpenFlowController {
374 } 374 }
375 375
376 @Override 376 @Override
377 - public void returnRoleAssertFailed(Dpid dpid, RoleState role) { 377 + public void returnRoleReply(Dpid dpid, RoleState requested, RoleState response) {
378 for (OpenFlowSwitchListener l : ofSwitchListener) { 378 for (OpenFlowSwitchListener l : ofSwitchListener) {
379 - l.roleAssertFailed(dpid, role); 379 + l.receivedRoleReply(dpid, requested, response);
380 } 380 }
381 } 381 }
382 } 382 }
......
...@@ -224,8 +224,8 @@ class RoleManager implements RoleHandler { ...@@ -224,8 +224,8 @@ class RoleManager implements RoleHandler {
224 } 224 }
225 225
226 int xid = (int) rri.getXid(); 226 int xid = (int) rri.getXid();
227 - RoleState role = rri.getRole(); 227 + RoleState receivedRole = rri.getRole();
228 - // XXX S should check generation id meaningfully and other cases of expectations 228 + // XXX Should check generation id meaningfully and other cases of expectations
229 229
230 if (pendingXid != xid) { 230 if (pendingXid != xid) {
231 log.debug("Received older role reply from " + 231 log.debug("Received older role reply from " +
...@@ -236,10 +236,12 @@ class RoleManager implements RoleHandler { ...@@ -236,10 +236,12 @@ class RoleManager implements RoleHandler {
236 return RoleRecvStatus.OLD_REPLY; 236 return RoleRecvStatus.OLD_REPLY;
237 } 237 }
238 238
239 - if (pendingRole == role) { 239 + sw.returnRoleReply(pendingRole, receivedRole);
240 +
241 + if (pendingRole == receivedRole) {
240 log.debug("Received role reply message from {} that matched " 242 log.debug("Received role reply message from {} that matched "
241 + "expected role-reply {} with expectations {}", 243 + "expected role-reply {} with expectations {}",
242 - new Object[] {sw.getStringId(), role, expectation}); 244 + new Object[] {sw.getStringId(), receivedRole, expectation});
243 245
244 if (expectation == RoleRecvStatus.MATCHED_CURRENT_ROLE || 246 if (expectation == RoleRecvStatus.MATCHED_CURRENT_ROLE ||
245 expectation == RoleRecvStatus.MATCHED_SET_ROLE) { 247 expectation == RoleRecvStatus.MATCHED_SET_ROLE) {
...@@ -247,8 +249,6 @@ class RoleManager implements RoleHandler { ...@@ -247,8 +249,6 @@ class RoleManager implements RoleHandler {
247 } else { 249 } else {
248 return RoleRecvStatus.OTHER_EXPECTATION; 250 return RoleRecvStatus.OTHER_EXPECTATION;
249 } 251 }
250 - } else {
251 - sw.returnRoleAssertFailure(pendingRole);
252 } 252 }
253 253
254 // if xids match but role's don't, perhaps its a query (OF1.3) 254 // if xids match but role's don't, perhaps its a query (OF1.3)
......
...@@ -175,11 +175,6 @@ public class RoleManagerTest { ...@@ -175,11 +175,6 @@ public class RoleManagerTest {
175 } 175 }
176 176
177 @Override 177 @Override
178 - public void returnRoleAssertFailure(RoleState role) {
179 - failed = role;
180 - }
181 -
182 - @Override
183 public boolean isOptical() { 178 public boolean isOptical() {
184 return false; 179 return false;
185 } 180 }
...@@ -300,5 +295,10 @@ public class RoleManagerTest { ...@@ -300,5 +295,10 @@ public class RoleManagerTest {
300 public void write(List<OFMessage> msgs) { 295 public void write(List<OFMessage> msgs) {
301 } 296 }
302 297
298 + @Override
299 + public void returnRoleReply(RoleState requested, RoleState response) {
300 + failed = requested;
301 + }
302 +
303 } 303 }
304 } 304 }
......
...@@ -226,23 +226,31 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr ...@@ -226,23 +226,31 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr
226 } 226 }
227 227
228 @Override 228 @Override
229 - public void roleAssertFailed(Dpid dpid, RoleState role) { 229 + public void receivedRoleReply(Dpid dpid, RoleState requested, RoleState response) {
230 - MastershipRole failed; 230 + MastershipRole request = roleOf(requested);
231 - switch (role) { 231 + MastershipRole reply = roleOf(response);
232 +
233 + providerService.receivedRoleReply(deviceId(uri(dpid)), request, reply);
234 + }
235 +
236 + /**
237 + * Translates a RoleState to the corresponding MastershipRole.
238 + *
239 + * @param response
240 + * @return a MastershipRole
241 + */
242 + private MastershipRole roleOf(RoleState response) {
243 + switch (response) {
232 case MASTER: 244 case MASTER:
233 - failed = MastershipRole.MASTER; 245 + return MastershipRole.MASTER;
234 - break;
235 case EQUAL: 246 case EQUAL:
236 - failed = MastershipRole.STANDBY; 247 + return MastershipRole.STANDBY;
237 - break;
238 case SLAVE: 248 case SLAVE:
239 - failed = MastershipRole.NONE; 249 + return MastershipRole.NONE;
240 - break;
241 default: 250 default:
242 - LOG.warn("unknown role {}", role); 251 + LOG.warn("unknown role {}", response);
243 - return; 252 + return null;
244 } 253 }
245 - providerService.unableToAssertRole(deviceId(uri(dpid)), failed);
246 } 254 }
247 255
248 /** 256 /**
......
...@@ -136,12 +136,13 @@ public class OpenFlowDeviceProviderTest { ...@@ -136,12 +136,13 @@ public class OpenFlowDeviceProviderTest {
136 } 136 }
137 137
138 @Test 138 @Test
139 - public void roleAssertFailed() { 139 + public void receivedRoleReply() {
140 - controller.listener.roleAssertFailed(DPID1, RoleState.MASTER); 140 + // check translation capabilities
141 + controller.listener.receivedRoleReply(DPID1, RoleState.MASTER, RoleState.MASTER);
141 assertEquals("wrong role reported", DPID1, registry.roles.get(MASTER)); 142 assertEquals("wrong role reported", DPID1, registry.roles.get(MASTER));
142 - controller.listener.roleAssertFailed(DPID1, RoleState.EQUAL); 143 + controller.listener.receivedRoleReply(DPID1, RoleState.EQUAL, RoleState.MASTER);
143 assertEquals("wrong role reported", DPID1, registry.roles.get(STANDBY)); 144 assertEquals("wrong role reported", DPID1, registry.roles.get(STANDBY));
144 - controller.listener.roleAssertFailed(DPID1, RoleState.SLAVE); 145 + controller.listener.receivedRoleReply(DPID1, RoleState.SLAVE, RoleState.MASTER);
145 assertEquals("wrong role reported", DPID1, registry.roles.get(NONE)); 146 assertEquals("wrong role reported", DPID1, registry.roles.get(NONE));
146 } 147 }
147 148
...@@ -210,8 +211,9 @@ public class OpenFlowDeviceProviderTest { ...@@ -210,8 +211,9 @@ public class OpenFlowDeviceProviderTest {
210 } 211 }
211 212
212 @Override 213 @Override
213 - public void unableToAssertRole(DeviceId deviceId, MastershipRole role) { 214 + public void receivedRoleReply(DeviceId deviceId,
214 - roles.put(role, Dpid.dpid(deviceId.uri())); 215 + MastershipRole requested, MastershipRole response) {
216 + roles.put(requested, Dpid.dpid(deviceId.uri()));
215 } 217 }
216 218
217 } 219 }
...@@ -372,12 +374,12 @@ public class OpenFlowDeviceProviderTest { ...@@ -372,12 +374,12 @@ public class OpenFlowDeviceProviderTest {
372 } 374 }
373 375
374 @Override 376 @Override
375 - public void returnRoleAssertFailure(RoleState role) { 377 + public boolean isOptical() {
378 + return false;
376 } 379 }
377 380
378 @Override 381 @Override
379 - public boolean isOptical() { 382 + public void returnRoleReply(RoleState requested, RoleState reponse) {
380 - return false;
381 } 383 }
382 384
383 } 385 }
......
...@@ -302,7 +302,10 @@ public class OpenFlowRuleProvider extends AbstractProvider implements FlowRulePr ...@@ -302,7 +302,10 @@ public class OpenFlowRuleProvider extends AbstractProvider implements FlowRulePr
302 } 302 }
303 303
304 @Override 304 @Override
305 - public void roleAssertFailed(Dpid dpid, RoleState role) {} 305 + public void receivedRoleReply(Dpid dpid, RoleState requested,
306 + RoleState response) {
307 + // Do nothing here for now.
308 + }
306 309
307 private synchronized void pushFlowMetrics(Dpid dpid, OFStatsReply stats) { 310 private synchronized void pushFlowMetrics(Dpid dpid, OFStatsReply stats) {
308 if (stats.getStatsType() != OFStatsType.FLOW) { 311 if (stats.getStatsType() != OFStatsType.FLOW) {
......
...@@ -160,7 +160,8 @@ public class OpenFlowLinkProvider extends AbstractProvider implements LinkProvid ...@@ -160,7 +160,8 @@ public class OpenFlowLinkProvider extends AbstractProvider implements LinkProvid
160 } 160 }
161 161
162 @Override 162 @Override
163 - public void roleAssertFailed(Dpid dpid, RoleState role) { 163 + public void receivedRoleReply(Dpid dpid, RoleState requested,
164 + RoleState response) {
164 // do nothing for this. 165 // do nothing for this.
165 } 166 }
166 167
......
...@@ -479,12 +479,12 @@ public class OpenFlowLinkProviderTest { ...@@ -479,12 +479,12 @@ public class OpenFlowLinkProviderTest {
479 } 479 }
480 480
481 @Override 481 @Override
482 - public void returnRoleAssertFailure(RoleState role) { 482 + public boolean isOptical() {
483 + return false;
483 } 484 }
484 485
485 @Override 486 @Override
486 - public boolean isOptical() { 487 + public void returnRoleReply(RoleState requested, RoleState reponse) {
487 - return false;
488 } 488 }
489 489
490 } 490 }
......
...@@ -410,12 +410,12 @@ public class OpenFlowPacketProviderTest { ...@@ -410,12 +410,12 @@ public class OpenFlowPacketProviderTest {
410 } 410 }
411 411
412 @Override 412 @Override
413 - public void returnRoleAssertFailure(RoleState role) { 413 + public boolean isOptical() {
414 + return false;
414 } 415 }
415 416
416 @Override 417 @Override
417 - public boolean isOptical() { 418 + public void returnRoleReply(RoleState requested, RoleState reponse) {
418 - return false;
419 } 419 }
420 420
421 } 421 }
......