use of org.onosproject.net.MastershipRole in project onos by opennetworkinglab.
the class DeviceManager method handleMastershipEvent.
private void handleMastershipEvent(MastershipEvent event) {
log.debug("Handling mastership event");
final DeviceId did = event.subject();
// myNextRole suggested by MastershipService event
MastershipRole myNextRole;
if (event.type() == MastershipEvent.Type.SUSPENDED) {
// FIXME STANDBY OR NONE?
myNextRole = NONE;
} else if (localNodeId.equals(event.roleInfo().master())) {
// confirm latest info
MastershipTerm term = termService.getMastershipTerm(did);
final boolean iHaveControl = term != null && localNodeId.equals(term.master());
if (iHaveControl) {
myNextRole = MASTER;
} else {
myNextRole = STANDBY;
}
} else if (event.roleInfo().backups().contains(localNodeId)) {
myNextRole = STANDBY;
} else {
myNextRole = NONE;
}
log.debug("Device {} local status is {}", did, localStatus(did));
final boolean isGracePeriodOn = inGracePeriod(did);
final boolean isReachable = isReachable(did, isGracePeriodOn);
// Passed the grace period and it is still not reachable
if (!isGracePeriodOn && !isReachable) {
// device is not connected to this node, nevertheless we should get a role
if (mastershipService.getLocalRole(did) == NONE) {
log.debug("Node was instructed to be {} role for {}, " + "but this node cannot reach the device " + "and role is already None. Asking a new role " + "and then apply the disconnection protocol.", myNextRole, did);
try {
mastershipService.requestRoleFor(did).get();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
log.error("Interrupted waiting for Mastership", e);
} catch (ExecutionException e) {
log.error("Encountered an error waiting for Mastership", e);
}
} else if (myNextRole != NONE) {
log.warn("Node was instructed to be {} role for {}, " + "but this node cannot reach the device. " + "Apply the disconnection protocol.", myNextRole, did);
}
// Let's put some order in the candidates list
roleToAcknowledge.remove(did);
updateMastershipFor(did);
} else if (isReachable) {
// cost us a lot as it is equivalent to a probe.
if (store.getDevice(did) != null) {
log.info("{} is reachable - reasserting the role", did);
reassertRole(did, myNextRole);
} else {
log.debug("Device is not yet/no longer in the store: {}", did);
}
} else {
// Do not proceed furthermore if the grace period is still on
log.debug("Skipping mastership event {}", event);
}
}
use of org.onosproject.net.MastershipRole in project onos by opennetworkinglab.
the class DeviceManager method updateMastershipFor.
/**
* Update the mastership for this device. If there is a node able
* to reach the device and this node is the master move the
* mastership to the next node still connected to this device.
* If the current node is a backup, it demotes itself to the bottom
* of the candidates list
*
* @param deviceId the device for which we have to update the mastership
* @return the NodeId of any node that can reach the device, or null if
* none of the ONOS instances can reach the device
*/
private NodeId updateMastershipFor(DeviceId deviceId) {
Map<NodeId, CompletableFuture<Boolean>> probes = Maps.newHashMap();
// Request a probe only if the node is ready
for (ControllerNode onosNode : clusterService.getNodes()) {
if (!clusterService.getState(onosNode.id()).isReady() || localNodeId.equals(onosNode.id())) {
continue;
}
probes.put(onosNode.id(), communicationService.sendAndReceive(deviceId, PROBE_SUBJECT, SERIALIZER::encode, SERIALIZER::decode, onosNode.id()));
}
// Returns the first node able to reach the device
// FIXME [SDFAB-935] optimize by looking at the MastershipInfo
boolean isReachable;
NodeId nextMaster = null;
// FIXME Should we expose timeout? Understand if there is need to signal to the caller
for (Map.Entry<NodeId, CompletableFuture<Boolean>> probe : probes.entrySet()) {
isReachable = Tools.futureGetOrElse(probe.getValue(), PROBE_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS, Boolean.FALSE);
if (isReachable) {
nextMaster = probe.getKey();
}
}
// FIXME [SDFAB-935] optimize demote by looking at the MastershipInfo;
if (nextMaster != null) {
log.info("Device {} is still connected to {}", deviceId, nextMaster);
MastershipRole myRole = mastershipService.getLocalRole(deviceId);
if (myRole == MASTER) {
log.info("Handing over the mastership of {} to next master {}", deviceId, nextMaster);
mastershipAdminService.setRole(nextMaster, deviceId, MASTER);
// Do not demote here because setRole can return before the mastership has been passed.
// Current implementation promotes first the nextMaster as top of candidate list and then
// transfer the leadership. We can use the BACKUP events to do demote or leverage periodic
// checks.
} else if (myRole == STANDBY) {
log.info("Demote current instance to the bottom of the candidates list for {}", deviceId);
mastershipAdminService.demote(localNodeId, deviceId);
} else {
log.debug("No valid role for {}", deviceId);
}
}
return nextMaster;
}
use of org.onosproject.net.MastershipRole in project onos by opennetworkinglab.
the class SimpleMastershipStore method setStandby.
@Override
public synchronized CompletableFuture<MastershipEvent> setStandby(NodeId nodeId, DeviceId deviceId) {
MastershipRole role = getRole(nodeId, deviceId);
switch(role) {
case MASTER:
NodeId backup = reelect(deviceId, nodeId);
if (backup == null) {
// no master alternative
masterMap.remove(deviceId);
// TODO: Should there be new event type for no MASTER?
return CompletableFuture.completedFuture(new MastershipEvent(MASTER_CHANGED, deviceId, getMastership(deviceId)));
} else {
NodeId prevMaster = masterMap.put(deviceId, backup);
incrementTerm(deviceId);
addToBackup(deviceId, prevMaster);
return CompletableFuture.completedFuture(new MastershipEvent(MASTER_CHANGED, deviceId, getMastership(deviceId)));
}
case STANDBY:
case NONE:
boolean modified = addToBackup(deviceId, nodeId);
if (modified) {
return CompletableFuture.completedFuture(new MastershipEvent(BACKUPS_CHANGED, deviceId, getMastership(deviceId)));
}
break;
default:
log.warn("unknown Mastership Role {}", role);
}
return null;
}
use of org.onosproject.net.MastershipRole in project onos by opennetworkinglab.
the class ConsistentDeviceMastershipStore method requestRole.
@Override
public CompletableFuture<MastershipRole> requestRole(DeviceId deviceId) {
checkArgument(deviceId != null, DEVICE_ID_NULL);
String leadershipTopic = createDeviceMastershipTopic(deviceId);
Leadership leadership = leadershipService.runForLeadership(leadershipTopic);
NodeId leader = leadership == null ? null : leadership.leaderNodeId();
List<NodeId> candidates = leadership == null ? ImmutableList.of() : ImmutableList.copyOf(leadership.candidates());
MastershipRole role = Objects.equals(localNodeId, leader) ? MastershipRole.MASTER : candidates.contains(localNodeId) ? MastershipRole.STANDBY : MastershipRole.NONE;
return CompletableFuture.completedFuture(role);
}
use of org.onosproject.net.MastershipRole in project onos by opennetworkinglab.
the class DeviceRoleCommand method doExecute.
@Override
protected void doExecute() {
MastershipAdminService service = get(MastershipAdminService.class);
MastershipRole mastershipRole = MastershipRole.valueOf(role.toUpperCase());
Futures.getUnchecked(service.setRole(new NodeId(node), deviceId(uri), mastershipRole));
}
Aggregations