private void kickOutBadDevice(DeviceId deviceId) { Device badDevice = getDevice(deviceId); if (badDevice != null) { removeDevice(deviceId); } } }
@Override protected DeviceProviderService createProviderService( DeviceProvider provider) { return new InternalDeviceProviderService(provider); }
PortAnnotationOperator(NetworkConfigService networkConfigService) { bindService(networkConfigService); }
checkNotNull(deviceId, DEVICE_ID_NULL); checkNotNull(deviceDescription, DEVICE_DESCRIPTION_NULL); checkValidity(); deviceLocalStatus.put(deviceId, new LocalStatus(true, Instant.now())); deviceDescription = BasicDeviceOperator.combine(cfg, deviceDescription); DeviceAnnotationConfig annoConfig = networkConfigService.getConfig(deviceId, DeviceAnnotationConfig.class); if (annoConfig != null) { deviceDescription = deviceAnnotationOp.combine(deviceId, deviceDescription, Optional.of(annoConfig)); DeviceEvent event = store.createOrUpdateDevice(provider().id(), deviceId, deviceDescription); applyRole(deviceId, role); List<PortDescription> complete = store.getPortDescriptions(provider().id(), deviceId) .collect(Collectors.toList()); complete.addAll(portConfig.portDescriptions()); .map(e -> applyAllPortOps(deviceId, e)) .collect(Collectors.toList()); store.updatePorts(provider().id(), deviceId, portDescriptions);
kickOutBadDevice(did); } else { Device dev = getDevice(did); DeviceDescription desc = (dev == null) ? null : BasicDeviceOperator.descriptionOf(dev); desc = BasicDeviceOperator.combine(cfg, desc); if (desc != null && dp != null) { de = store.createOrUpdateDevice(dp.id(), did, desc); DeviceProvider dp = getProvider(did); if (!event.config().isPresent() || getDevice(did) == null || dp == null) { DeviceId did = (DeviceId) event.subject(); DeviceProvider dp = getProvider(did); Device dev = getDevice(did); DeviceDescription desc = (dev == null) ? null : BasicDeviceOperator.descriptionOf(dev); Optional<Config> prevConfig = event.prevConfig(); desc = deviceAnnotationOp.combine(did, desc, prevConfig); if (desc != null && dp != null) { de = store.createOrUpdateDevice(dp.id(), did, desc);
private void handlePortRequest(InternalPortUpDownEvent event) { DeviceId deviceId = event.deviceId(); checkNotNull(deviceId, DEVICE_ID_NULL); checkNotNull(deviceId, PORT_NUMBER_NULL); checkState(mastershipService.isLocalMaster(deviceId), EVENT_NON_MASTER); changePortStateAtMaster(event.deviceId(), event.portNumber(), event.isEnable()); }
private boolean isReachable(DeviceId deviceId) { if (deviceId == null) { return false; } DeviceProvider provider = getProvider(deviceId); if (provider != null) { boolean reachable = provider.isReachable(deviceId); if (reachable && !isLocallyConnected(deviceId)) { deviceLocalStatus.put(deviceId, new LocalStatus(true, Instant.now())); } else if (!reachable && isLocallyConnected(deviceId)) { deviceLocalStatus.put(deviceId, new LocalStatus(false, Instant.now())); } return reachable; } else { log.debug("Provider not found for {}", deviceId); return false; } }
@Activate public void activate() { portAnnotationOp = new PortAnnotationOperator(networkConfigService); deviceAnnotationOp = new DeviceAnnotationOperator(networkConfigService); portOpsIndex.put(PortAnnotationConfig.class, portAnnotationOp); backgroundService = newSingleThreadScheduledExecutor( groupedThreads("onos/device", "manager-background", log)); localNodeId = clusterService.getLocalNode().id(); store.setDelegate(delegate); eventDispatcher.addSink(DeviceEvent.class, listenerRegistry); mastershipService.addListener(mastershipListener); networkConfigService.addListener(networkConfigListener); backgroundService.scheduleWithFixedDelay(() -> { try { mastershipCheck(); } catch (Exception e) { log.error("Exception thrown during integrity check", e); } }, 1, 1, TimeUnit.MINUTES); portReqeustExecutor = newSingleThreadExecutor(); communicationService.<InternalPortUpDownEvent>addSubscriber( PORT_UPDOWN_SUBJECT, SERIALIZER::decode, this::handlePortRequest, portReqeustExecutor); log.info("Started"); }
@Override public void deletePort(DeviceId deviceId, PortDescription basePortDescription) { checkNotNull(deviceId, DEVICE_ID_NULL); checkNotNull(basePortDescription, PORT_DESCRIPTION_NULL); checkValidity(); if (!mastershipService.isLocalMaster(deviceId)) { // Never been a master for this device // any update will be ignored. log.trace("Ignoring {} port update on standby node. {}", deviceId, basePortDescription); return; } Device device = getDevice(deviceId); if (device == null) { log.trace("Device not found: {}", deviceId); } PortDescription newPortDescription = DefaultPortDescription.builder(basePortDescription) .isRemoved(true) .build(); final DeviceEvent event = store.updatePortStatus(this.provider().id(), deviceId, newPortDescription); if (event != null) { log.info("Device {} port {} status changed", deviceId, event.port().number()); post(event); } }
@Override public void updatePortStatistics(DeviceId deviceId, Collection<PortStatistics> portStatistics) { checkNotNull(deviceId, DEVICE_ID_NULL); checkNotNull(portStatistics, "Port statistics list cannot be null"); checkValidity(); DeviceEvent event = store.updatePortStatistics(this.provider().id(), deviceId, portStatistics); post(event); } }
@Override public void changePortState(DeviceId deviceId, PortNumber portNumber, boolean enable) { checkNotNull(deviceId, DEVICE_ID_NULL); checkNotNull(deviceId, PORT_NUMBER_NULL); NodeId masterId = mastershipService.getMasterFor(deviceId); if (masterId == null) { // No master found; device is offline log.info("No master found for port state change for {}", deviceId); return; } if (!masterId.equals(localNodeId)) { //Send the request to the master node for the device log.info("Device {} is managed by {}, forwarding the request to the MASTER", deviceId, masterId); communicationService.unicast( new InternalPortUpDownEvent(deviceId, portNumber, enable), PORT_UPDOWN_SUBJECT, SERIALIZER::encode, masterId).whenComplete((r, error) -> { if (error != null) { log.warn("Failed to send packet-updown-req to {}", masterId, error); } }); } else { changePortStateAtMaster(deviceId, portNumber, enable); } }
private void changePortStateAtMaster(DeviceId deviceId, PortNumber portNumber, boolean enable) { DeviceProvider provider = getProvider(deviceId); if (provider != null) { log.info("Port {} on device {} being administratively brought {}", portNumber, deviceId, (enable) ? "UP" : "DOWN"); provider.changePortState(deviceId, portNumber, enable); } else { log.warn("Provider not found for {}", deviceId); } }
DeviceAnnotationOperator(NetworkConfigService networkConfigService) { bindService(networkConfigService); }
/** * Merges the appropriate PortConfig with the description. * * @param cpt ConnectPoint where the port is attached * @param desc {@link PortDescription} * @return merged {@link PortDescription} */ private PortDescription applyAllPortOps(ConnectPoint cpt, PortDescription desc) { PortDescription work = desc; for (PortConfigOperator portOp : portOps) { work = portOp.combine(cpt, work); } return portAnnotationOp.combine(cpt, work); }
@Override public void removeDevice(DeviceId deviceId) { checkNotNull(deviceId, DEVICE_ID_NULL); DeviceEvent event = store.removeDevice(deviceId); if (event != null) { log.info("Device {} administratively removed", deviceId); post(event); } }
/** * Merges the appropriate PortConfig with the description. * * @param did ID of the Device where the port is attached * @param desc {@link PortDescription} * @return merged {@link PortDescription} */ private PortDescription applyAllPortOps(DeviceId did, PortDescription desc) { return applyAllPortOps(new ConnectPoint(did, desc.portNumber()), desc); }
/** * Apply role in reaction to provider event. * * @param deviceId device identifier * @param newRole new role to apply to the device * @return true if the request was sent to provider */ private boolean applyRole(DeviceId deviceId, MastershipRole newRole) { if (newRole.equals(MastershipRole.NONE)) { //no-op return true; } DeviceProvider provider = provider(); if (provider == null) { log.warn("Provider for {} was not found. Cannot apply role {}", deviceId, newRole); return false; } provider.roleChanged(deviceId, newRole); // not triggering probe when triggered by provider service event return true; }
/** * Generates an annotation from an existing annotation and DeviceConfig. * * @param cfg the device config entity from network config * @param an the annotation * @return annotation combining both sources */ public static SparseAnnotations combine(BasicDeviceConfig cfg, SparseAnnotations an) { DefaultAnnotations.Builder builder = DefaultAnnotations.builder(); builder.putAll(an); if (!Objects.equals(cfg.driver(), an.value(AnnotationKeys.DRIVER))) { builder.set(AnnotationKeys.DRIVER, cfg.driver()); } combineElementAnnotations(cfg, builder); if (cfg.managementAddress() != null) { builder.set(AnnotationKeys.MANAGEMENT_ADDRESS, cfg.managementAddress()); } return builder.build(); }
@Override public PortDescription combine(ConnectPoint cp, PortDescription descr) { PortAnnotationConfig cfg = lookupConfig(cp); if (cfg == null) { return descr; } Map<String, String> annotations = cfg.annotations(); if (annotations.isEmpty()) { return descr; } Builder builder = DefaultAnnotations.builder(); builder.putAll(descr.annotations()); builder.putAll(annotations); return DefaultPortDescription.builder(descr) .annotations(builder.build()) .build(); }
/** * Apply role to device and send probe if MASTER. * * @param deviceId device identifier * @param newRole new role to apply to the device * @return true if the request was sent to provider */ private boolean applyRoleAndProbe(DeviceId deviceId, MastershipRole newRole) { if (newRole.equals(MastershipRole.NONE)) { //no-op return true; } DeviceProvider provider = getProvider(deviceId); if (provider == null) { log.warn("Provider for {} was not found. Cannot apply role {}", deviceId, newRole); return false; } provider.roleChanged(deviceId, newRole); if (newRole.equals(MastershipRole.MASTER)) { log.debug("sent TriggerProbe({})", deviceId); // only trigger event when request was sent to provider provider.triggerProbe(deviceId); } return true; }