Search in sources :

Example 41 with NodeId

use of org.onosproject.cluster.NodeId in project onos by opennetworkinglab.

the class GeneralDeviceProvider method roleChanged.

@Override
public void roleChanged(DeviceId deviceId, MastershipRole newRole) {
    final MastershipInfo mastershipInfo = mastershipService.getMastershipFor(deviceId);
    final NodeId localNodeId = clusterService.getLocalNode().id();
    if (!mastershipInfo.getRole(localNodeId).equals(newRole)) {
        log.warn("Inconsistent mastership info for {}! Requested {}, but " + "mastership service reports {}, will apply the latter...", deviceId, newRole, mastershipInfo.getRole(localNodeId));
        newRole = mastershipInfo.getRole(localNodeId);
    }
    final DeviceHandshaker handshaker = getBehaviour(deviceId, DeviceHandshaker.class);
    if (handshaker == null) {
        log.error("Null handshaker. Unable to notify role {} to {}", newRole, deviceId);
        return;
    }
    // Derive preference value.
    final int preference;
    switch(newRole) {
        case MASTER:
            preference = 0;
            break;
        case STANDBY:
            preference = mastershipInfo.backups().indexOf(localNodeId) + 1;
            if (preference == 0) {
                // Not found in list.
                log.error("Unable to derive mastership preference for {}, " + "requested role {} but local node ID was " + "not found among list of backup nodes " + "reported by mastership service", deviceId, newRole);
                return;
            }
            break;
        case NONE:
            // No preference for NONE, apply as is.
            Pair<MastershipRole, Integer> pairRolePref = Pair.of(newRole, -1);
            if (log.isDebugEnabled()) {
                log.debug("Notifying role {} to {}", newRole, deviceId);
            } else if (!pairRolePref.equals(lastRoleRequest.get(deviceId))) {
                log.info("Notifying role {} to {}", newRole, deviceId);
            }
            lastRoleRequest.put(deviceId, pairRolePref);
            handshaker.roleChanged(newRole);
            return;
        default:
            log.error("Unrecognized mastership role {}", newRole);
            return;
    }
    Pair<MastershipRole, Integer> pairRolePref = Pair.of(newRole, preference);
    if (log.isDebugEnabled()) {
        log.debug("Notifying role {} (preference {}) for term {} to {}", newRole, preference, mastershipInfo.term(), deviceId);
    } else if (!pairRolePref.equals(lastRoleRequest.get(deviceId))) {
        log.info("Notifying role {} (preference {}) for term {} to {}", newRole, preference, mastershipInfo.term(), deviceId);
    }
    lastRoleRequest.put(deviceId, pairRolePref);
    try {
        handshaker.roleChanged(preference, mastershipInfo.term());
    } catch (UnsupportedOperationException e) {
        // Preference-based method not supported.
        handshaker.roleChanged(newRole);
    }
}
Also used : DeviceHandshaker(org.onosproject.net.device.DeviceHandshaker) NodeId(org.onosproject.cluster.NodeId) MastershipInfo(org.onosproject.mastership.MastershipInfo) MastershipRole(org.onosproject.net.MastershipRole)

Example 42 with NodeId

use of org.onosproject.cluster.NodeId in project onos by opennetworkinglab.

the class MastershipWebResource method getMasterFor.

/**
 * Returns the current master for a given device.
 *
 * @param deviceId device identifier
 * @return 200 OK with the identifier of the master controller for the device
 * @onos.rsModel NodeId
 */
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("{deviceId}/master")
public Response getMasterFor(@PathParam("deviceId") String deviceId) {
    MastershipService mastershipService = get(MastershipService.class);
    NodeId id = nullIsNotFound(mastershipService.getMasterFor(DeviceId.deviceId(deviceId)), NODE_ID_NOT_FOUND);
    ObjectNode root = mapper().createObjectNode();
    root.put(NODE_ID, id.id());
    return ok(root).build();
}
Also used : ObjectNode(com.fasterxml.jackson.databind.node.ObjectNode) NodeId(org.onosproject.cluster.NodeId) MastershipService(org.onosproject.mastership.MastershipService) Path(javax.ws.rs.Path) Produces(javax.ws.rs.Produces) GET(javax.ws.rs.GET)

Example 43 with NodeId

use of org.onosproject.cluster.NodeId in project onos by opennetworkinglab.

the class ProxyTestCommand method doExecute.

@Override
protected void doExecute() {
    ProxyTest proxyTest = get(ProxyTest.class);
    TestProxy proxy;
    if ("node".equals(type)) {
        NodeId nodeId = NodeId.nodeId(arg1);
        proxy = proxyTest.getProxyFor(nodeId);
    } else if ("master".equals(type)) {
        DeviceId deviceId = DeviceId.deviceId(arg1);
        proxy = proxyTest.getProxyFor(deviceId);
    } else {
        throw new IllegalArgumentException("Unknown operation type " + type);
    }
    if ("sync".equals(operation)) {
        print("%s", proxy.testSync(arg2));
    } else if ("async".equals(operation)) {
        try {
            print("%s", proxy.testAsync(arg2).get(10, TimeUnit.SECONDS));
        } catch (InterruptedException | ExecutionException | TimeoutException e) {
            throw new IllegalStateException(e);
        }
    } else {
        throw new IllegalArgumentException("Unknown operation " + operation);
    }
}
Also used : DeviceId(org.onosproject.net.DeviceId) NodeId(org.onosproject.cluster.NodeId)

Example 44 with NodeId

use of org.onosproject.cluster.NodeId in project onos by opennetworkinglab.

the class MastershipManager method balanceRolesInRegion.

/**
 * Balances the nodes in specified region.
 *
 * @param region               region in which nodes are to be balanced
 * @param allControllerDevices controller nodes to devices map
 * @return controller nodes that were balanced
 */
private Map<ControllerNode, Set<DeviceId>> balanceRolesInRegion(Region region, Map<ControllerNode, Set<DeviceId>> allControllerDevices) {
    // Retrieve all devices associated with specified region
    Set<DeviceId> devicesInRegion = regionService.getRegionDevices(region.id());
    log.info("Region {} has {} devices.", region.id(), devicesInRegion.size());
    if (devicesInRegion.isEmpty()) {
        // no devices in this region, so nothing to balance.
        return new HashMap<>();
    }
    List<Set<NodeId>> mastersList = region.masters();
    log.info("Region {} has {} sets of masters.", region.id(), mastersList.size());
    if (mastersList.isEmpty()) {
        // for now just leave devices alone
        return new HashMap<>();
    }
    // Get the region's preferred set of masters
    Set<DeviceId> devicesInMasters = Sets.newHashSet();
    Map<ControllerNode, Set<DeviceId>> regionalControllerDevices = getRegionsPreferredMasters(region, devicesInMasters, allControllerDevices);
    // Now re-balance the buckets until they are roughly even.
    List<CompletableFuture<Void>> balanceBucketsFutures = Lists.newArrayList();
    balanceControllerNodes(regionalControllerDevices, devicesInMasters.size(), balanceBucketsFutures);
    // Handle devices that are not currently mastered by the master node set
    Set<DeviceId> devicesNotMasteredWithControllers = Sets.difference(devicesInRegion, devicesInMasters);
    if (!devicesNotMasteredWithControllers.isEmpty()) {
        // active controllers in master node set are already balanced, just
        // assign device mastership in sequence
        List<ControllerNode> sorted = new ArrayList<>(regionalControllerDevices.keySet());
        Collections.sort(sorted, Comparator.comparingInt(o -> (regionalControllerDevices.get(o)).size()));
        int deviceIndex = 0;
        for (DeviceId deviceId : devicesNotMasteredWithControllers) {
            ControllerNode cnode = sorted.get(deviceIndex % sorted.size());
            balanceBucketsFutures.add(setRole(cnode.id(), deviceId, MASTER));
            regionalControllerDevices.get(cnode).add(deviceId);
            deviceIndex++;
        }
    }
    CompletableFuture<Void> balanceRolesFuture = allOf(balanceBucketsFutures.toArray(new CompletableFuture[balanceBucketsFutures.size()]));
    Futures.getUnchecked(balanceRolesFuture);
    // Update the map before returning
    regionalControllerDevices.forEach((controllerNode, deviceIds) -> {
        regionalControllerDevices.put(controllerNode, new HashSet<>(getDevicesOf(controllerNode.id())));
    });
    return regionalControllerDevices;
}
Also used : CLUSTER_READ(org.onosproject.security.AppPermission.Type.CLUSTER_READ) RegionService(org.onosproject.net.region.RegionService) MASTER(org.onosproject.net.MastershipRole.MASTER) OsgiPropertyConstants(org.onosproject.net.OsgiPropertyConstants) Map(java.util.Map) MastershipService(org.onosproject.mastership.MastershipService) NodeId(org.onosproject.cluster.NodeId) Region(org.onosproject.net.region.Region) UpgradeService(org.onosproject.upgrade.UpgradeService) AbstractListenerManager(org.onosproject.event.AbstractListenerManager) Deactivate(org.osgi.service.component.annotations.Deactivate) Collection(java.util.Collection) MastershipTermService(org.onosproject.mastership.MastershipTermService) MastershipInfo(org.onosproject.mastership.MastershipInfo) Set(java.util.Set) Sets(com.google.common.collect.Sets) List(java.util.List) Lists.newArrayList(com.google.common.collect.Lists.newArrayList) MastershipStore(org.onosproject.mastership.MastershipStore) Timer(com.codahale.metrics.Timer) ClusterService(org.onosproject.cluster.ClusterService) DeviceId(org.onosproject.net.DeviceId) MastershipStoreDelegate(org.onosproject.mastership.MastershipStoreDelegate) MetricsUtil.stopTimer(org.onlab.metrics.MetricsUtil.stopTimer) AppGuard.checkPermission(org.onosproject.security.AppGuard.checkPermission) MetricsService(org.onlab.metrics.MetricsService) HashMap(java.util.HashMap) CompletableFuture(java.util.concurrent.CompletableFuture) ControllerNode(org.onosproject.cluster.ControllerNode) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) MetricsHelper(org.onosproject.core.MetricsHelper) MastershipEvent(org.onosproject.mastership.MastershipEvent) Component(org.osgi.service.component.annotations.Component) Lists(com.google.common.collect.Lists) CompletableFuture.allOf(java.util.concurrent.CompletableFuture.allOf) Context(com.codahale.metrics.Timer.Context) Activate(org.osgi.service.component.annotations.Activate) ComponentConfigService(org.onosproject.cfg.ComponentConfigService) UpgradeEventListener(org.onosproject.upgrade.UpgradeEventListener) Logger(org.slf4j.Logger) Iterator(java.util.Iterator) MetricsUtil.startTimer(org.onlab.metrics.MetricsUtil.startTimer) MastershipRole(org.onosproject.net.MastershipRole) Preconditions.checkNotNull(com.google.common.base.Preconditions.checkNotNull) CLUSTER_WRITE(org.onosproject.security.AppPermission.Type.CLUSTER_WRITE) MastershipTerm(org.onosproject.mastership.MastershipTerm) ReferenceCardinality(org.osgi.service.component.annotations.ReferenceCardinality) UpgradeEvent(org.onosproject.upgrade.UpgradeEvent) Futures(com.google.common.util.concurrent.Futures) ConfigProperty(org.onosproject.cfg.ConfigProperty) Modified(org.osgi.service.component.annotations.Modified) LoggerFactory.getLogger(org.slf4j.LoggerFactory.getLogger) RoleInfo(org.onosproject.cluster.RoleInfo) MastershipListener(org.onosproject.mastership.MastershipListener) Reference(org.osgi.service.component.annotations.Reference) Comparator(java.util.Comparator) MastershipAdminService(org.onosproject.mastership.MastershipAdminService) Collections(java.util.Collections) Set(java.util.Set) HashSet(java.util.HashSet) HashMap(java.util.HashMap) DeviceId(org.onosproject.net.DeviceId) Lists.newArrayList(com.google.common.collect.Lists.newArrayList) ArrayList(java.util.ArrayList) ControllerNode(org.onosproject.cluster.ControllerNode) CompletableFuture(java.util.concurrent.CompletableFuture)

Example 45 with NodeId

use of org.onosproject.cluster.NodeId 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;
}
Also used : CompletableFuture(java.util.concurrent.CompletableFuture) NodeId(org.onosproject.cluster.NodeId) ControllerNode(org.onosproject.cluster.ControllerNode) Map(java.util.Map) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) MastershipRole(org.onosproject.net.MastershipRole)

Aggregations

NodeId (org.onosproject.cluster.NodeId)145 ClusterService (org.onosproject.cluster.ClusterService)36 DeviceId (org.onosproject.net.DeviceId)36 Set (java.util.Set)26 MastershipRole (org.onosproject.net.MastershipRole)23 ControllerNode (org.onosproject.cluster.ControllerNode)22 Test (org.junit.Test)18 Activate (org.osgi.service.component.annotations.Activate)18 List (java.util.List)16 MastershipService (org.onosproject.mastership.MastershipService)15 ObjectNode (com.fasterxml.jackson.databind.node.ObjectNode)13 Map (java.util.Map)12 ImmutableSet (com.google.common.collect.ImmutableSet)11 ArrayList (java.util.ArrayList)11 Collectors (java.util.stream.Collectors)11 HashSet (java.util.HashSet)10 Optional (java.util.Optional)10 ClusterCommunicationService (org.onosproject.store.cluster.messaging.ClusterCommunicationService)10 Component (org.osgi.service.component.annotations.Component)9 Deactivate (org.osgi.service.component.annotations.Deactivate)9