From d0ab3c02ef12ff57f3de1f95e74d5303a3a0cc47 Mon Sep 17 00:00:00 2001 From: Ayaka Koshibe Date: Fri, 4 Sep 2015 15:43:46 -0700 Subject: [PATCH] Misc device/optical config features: o devices and optical ports are updated with network configs o refactored AllowedEntity checks in DeviceManager o "basic" -> "optical" for OpticalPort config key o Device and OpticalPort operators can create descriptions Change-Id: I59edc368f3a8ff931954b174d4a898f6b4add5d5 --- .../net/config/impl/BasicNetworkConfigs.java | 2 +- .../net/device/impl/BasicDeviceOperator.java | 9 ++ .../net/device/impl/DeviceManager.java | 116 ++++++++++++------ .../net/device/impl/OpticalPortOperator.java | 33 +++++ 4 files changed, 123 insertions(+), 37 deletions(-) diff --git a/core/net/src/main/java/org/onosproject/net/config/impl/BasicNetworkConfigs.java b/core/net/src/main/java/org/onosproject/net/config/impl/BasicNetworkConfigs.java index ec0b1244dd..7480462232 100644 --- a/core/net/src/main/java/org/onosproject/net/config/impl/BasicNetworkConfigs.java +++ b/core/net/src/main/java/org/onosproject/net/config/impl/BasicNetworkConfigs.java @@ -84,7 +84,7 @@ public class BasicNetworkConfigs { }, new ConfigFactory(CONNECT_POINT_SUBJECT_FACTORY, OpticalPortConfig.class, - "basic") { + "optical") { @Override public OpticalPortConfig createConfig() { return new OpticalPortConfig(); diff --git a/core/net/src/main/java/org/onosproject/net/device/impl/BasicDeviceOperator.java b/core/net/src/main/java/org/onosproject/net/device/impl/BasicDeviceOperator.java index 36686d8623..a7d488b3f5 100644 --- a/core/net/src/main/java/org/onosproject/net/device/impl/BasicDeviceOperator.java +++ b/core/net/src/main/java/org/onosproject/net/device/impl/BasicDeviceOperator.java @@ -16,6 +16,7 @@ package org.onosproject.net.device.impl; import static org.slf4j.LoggerFactory.getLogger; +import static com.google.common.base.Preconditions.checkNotNull; import org.onosproject.net.config.ConfigOperator; import org.onosproject.net.config.basics.BasicDeviceConfig; @@ -93,4 +94,12 @@ public final class BasicDeviceOperator implements ConfigOperator { DefaultAnnotations newAnnotations = newBuilder.build(); return DefaultAnnotations.union(an, newAnnotations); } + + public static DeviceDescription descriptionOf(Device device) { + checkNotNull(device, "Must supply non-null Device"); + return new DefaultDeviceDescription(device.id().uri(), device.type(), + device.manufacturer(), device.hwVersion(), + device.swVersion(), device.serialNumber(), + device.chassisId(), (SparseAnnotations) device.annotations()); + } } diff --git a/core/net/src/main/java/org/onosproject/net/device/impl/DeviceManager.java b/core/net/src/main/java/org/onosproject/net/device/impl/DeviceManager.java index d1bcae77fb..b0b3abe2b7 100644 --- a/core/net/src/main/java/org/onosproject/net/device/impl/DeviceManager.java +++ b/core/net/src/main/java/org/onosproject/net/device/impl/DeviceManager.java @@ -31,11 +31,13 @@ import org.onosproject.net.config.NetworkConfigEvent; import org.onosproject.net.config.NetworkConfigListener; import org.onosproject.net.config.NetworkConfigService; import org.onosproject.net.config.basics.BasicDeviceConfig; +import org.onosproject.net.config.basics.OpticalPortConfig; import org.onosproject.mastership.MastershipEvent; import org.onosproject.mastership.MastershipListener; import org.onosproject.mastership.MastershipService; import org.onosproject.mastership.MastershipTerm; import org.onosproject.mastership.MastershipTermService; +import org.onosproject.net.ConnectPoint; import org.onosproject.net.Device; import org.onosproject.net.Device.Type; import org.onosproject.net.DeviceId; @@ -64,13 +66,13 @@ import java.util.HashSet; import java.util.List; import java.util.Objects; import java.util.Set; +import java.util.stream.Collectors; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.base.Preconditions.checkState; import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor; import static org.onlab.util.Tools.groupedThreads; import static org.onosproject.net.MastershipRole.*; @@ -78,7 +80,6 @@ import static org.onosproject.security.AppGuard.checkPermission; import static org.slf4j.LoggerFactory.getLogger; import static org.onosproject.security.AppPermission.Type.*; - /** * Provides implementation of the device SB & NB APIs. */ @@ -92,6 +93,7 @@ public class DeviceManager private static final String PORT_NUMBER_NULL = "Port number cannot be null"; private static final String DEVICE_DESCRIPTION_NULL = "Device description cannot be null"; private static final String PORT_DESCRIPTION_NULL = "Port description cannot be null"; + private static final String PORT_DESC_LIST_NULL = "Port description list cannot be null"; private final Logger log = getLogger(getClass()); @@ -265,8 +267,7 @@ public class DeviceManager continue; } - log.info("{} is reachable but did not have a valid role, reasserting", - deviceId); + log.info("{} is reachable but did not have a valid role, reasserting", deviceId); // isReachable but was not MASTER or STANDBY, get a role and apply // Note: NONE triggers request to MastershipService @@ -309,16 +310,20 @@ public class DeviceManager return true; } - @Override public void deviceConnected(DeviceId deviceId, DeviceDescription deviceDescription) { checkNotNull(deviceId, DEVICE_ID_NULL); checkNotNull(deviceDescription, DEVICE_DESCRIPTION_NULL); checkValidity(); - deviceDescription = validateDevice(deviceDescription, deviceId); - // Establish my Role + BasicDeviceConfig cfg = networkConfigService.getConfig(deviceId, BasicDeviceConfig.class); + if (!isAllowed(cfg)) { + log.warn("Device {} is not allowed", deviceId); + return; + } + // Generate updated description and establish my Role + deviceDescription = BasicDeviceOperator.combine(cfg, deviceDescription); Futures.getUnchecked(mastershipService.requestRoleFor(deviceId) .thenAccept(role -> { log.info("Local role is {} for {}", role, deviceId); @@ -327,22 +332,13 @@ public class DeviceManager DeviceEvent event = store.createOrUpdateDevice(provider().id(), deviceId, deviceDescription); + log.info("Device {} connected", deviceId); if (event != null) { log.trace("event: {} {}", event.type(), event); post(event); } } - // returns a DeviceDescription made from the union of the BasicDeviceConfig - // annotations if it exists - private DeviceDescription validateDevice(DeviceDescription deviceDescription, DeviceId deviceId) { - BasicDeviceConfig cfg = networkConfigService.getConfig(deviceId, BasicDeviceConfig.class); - checkState(cfg == null || cfg.isAllowed(), "Device " + deviceId + " is not allowed"); - log.info("Device {} connected", deviceId); - - return BasicDeviceOperator.combine(cfg, deviceDescription); - } - @Override public void deviceDisconnected(DeviceId deviceId) { checkNotNull(deviceId, DEVICE_ID_NULL); @@ -402,8 +398,7 @@ public class DeviceManager public void updatePorts(DeviceId deviceId, List portDescriptions) { checkNotNull(deviceId, DEVICE_ID_NULL); - checkNotNull(portDescriptions, - "Port descriptions list cannot be null"); + checkNotNull(portDescriptions, PORT_DESC_LIST_NULL); checkValidity(); if (!mastershipService.isLocalMaster(deviceId)) { // Never been a master for this device @@ -411,7 +406,9 @@ public class DeviceManager log.trace("Ignoring {} port updates on standby node. {}", deviceId, portDescriptions); return; } - + portDescriptions = portDescriptions.stream() + .map(e -> consolidate(deviceId, e)) + .collect(Collectors.toList()); List events = store.updatePorts(this.provider().id(), deviceId, portDescriptions); for (DeviceEvent event : events) { @@ -433,16 +430,28 @@ public class DeviceManager portDescription); return; } - + portDescription = consolidate(deviceId, portDescription); final DeviceEvent event = store.updatePortStatus(this.provider().id(), deviceId, portDescription); if (event != null) { - log.info("Device {} port {} status changed", deviceId, event - .port().number()); + log.info("Device {} port {} status changed", deviceId, event.port().number()); post(event); } } + // merges the appropriate PortConfig with the description. + private PortDescription consolidate(DeviceId did, PortDescription desc) { + switch (desc.type()) { + case COPPER: + case VIRTUAL: + return desc; + default: + OpticalPortConfig opc = networkConfigService.getConfig( + new ConnectPoint(did, desc.portNumber()), OpticalPortConfig.class); + return OpticalPortOperator.combine(opc, desc); + } + } + @Override public void receivedRoleReply(DeviceId deviceId, MastershipRole requested, MastershipRole response) { @@ -498,6 +507,11 @@ public class DeviceManager } } + // by default allowed, otherwise check flag + private boolean isAllowed(BasicDeviceConfig cfg) { + return (cfg == null || cfg.isAllowed()); + } + // Applies the specified role to the device; ignores NONE /** @@ -617,7 +631,6 @@ public class DeviceManager myNextRole = NONE; } - final boolean isReachable = isReachable(did); if (!isReachable) { // device is not connected to this node @@ -695,23 +708,54 @@ public class DeviceManager private class InternalNetworkConfigListener implements NetworkConfigListener { @Override public boolean isRelevant(NetworkConfigEvent event) { - return (event.type() == NetworkConfigEvent.Type.CONFIG_ADDED || - event.type() == NetworkConfigEvent.Type.CONFIG_UPDATED) - && event.configClass().equals(BasicDeviceConfig.class); + return (event.type() == NetworkConfigEvent.Type.CONFIG_ADDED + || event.type() == NetworkConfigEvent.Type.CONFIG_UPDATED) + && (event.configClass().equals(BasicDeviceConfig.class) + || event.configClass().equals(OpticalPortConfig.class)); } @Override public void event(NetworkConfigEvent event) { - log.info("Detected Device network config event {}", event.type()); - kickOutBadDevice(((DeviceId) event.subject())); - } - } + DeviceEvent de = null; + if (event.configClass().equals(BasicDeviceConfig.class)) { + log.info("Detected Device network config event {}", event.type()); + DeviceId did = (DeviceId) event.subject(); + BasicDeviceConfig cfg = networkConfigService.getConfig(did, BasicDeviceConfig.class); - // checks if the specified device is allowed by the BasicDeviceConfig - // and if not, removes it - private void kickOutBadDevice(DeviceId deviceId) { - BasicDeviceConfig cfg = networkConfigService.getConfig(deviceId, BasicDeviceConfig.class); - if (!cfg.isAllowed()) { + if (!isAllowed(cfg)) { + kickOutBadDevice(did); + } else { + Device dev = getDevice(did); + DeviceDescription desc = (dev == null) ? null : BasicDeviceOperator.descriptionOf(dev); + desc = BasicDeviceOperator.combine(cfg, desc); + if (getProvider(did) != null) { + de = store.createOrUpdateDevice(getProvider(did).id(), did, desc); + } + } + } + if (event.configClass().equals(OpticalPortConfig.class)) { + ConnectPoint cpt = (ConnectPoint) event.subject(); + DeviceId did = cpt.deviceId(); + Port dpt = getPort(did, cpt.port()); + + if (dpt != null) { + OpticalPortConfig opc = networkConfigService.getConfig(cpt, OpticalPortConfig.class); + PortDescription desc = OpticalPortOperator.descriptionOf(dpt); + desc = OpticalPortOperator.combine(opc, desc); + if (getProvider(did) != null) { + de = store.updatePortStatus(getProvider(did).id(), did, desc); + } + } + } + + if (de != null) { + post(de); + } + } + + // checks if the specified device is allowed by the BasicDeviceConfig + // and if not, removes it + private void kickOutBadDevice(DeviceId deviceId) { Device badDevice = getDevice(deviceId); if (badDevice != null) { removeDevice(deviceId); diff --git a/core/net/src/main/java/org/onosproject/net/device/impl/OpticalPortOperator.java b/core/net/src/main/java/org/onosproject/net/device/impl/OpticalPortOperator.java index af0092d5a4..15f087919c 100644 --- a/core/net/src/main/java/org/onosproject/net/device/impl/OpticalPortOperator.java +++ b/core/net/src/main/java/org/onosproject/net/device/impl/OpticalPortOperator.java @@ -16,11 +16,16 @@ package org.onosproject.net.device.impl; import static org.slf4j.LoggerFactory.getLogger; +import static com.google.common.base.Preconditions.checkNotNull; import org.onosproject.net.config.ConfigOperator; import org.onosproject.net.config.basics.OpticalPortConfig; import org.onosproject.net.AnnotationKeys; import org.onosproject.net.DefaultAnnotations; +import org.onosproject.net.OchPort; +import org.onosproject.net.OduCltPort; +import org.onosproject.net.OmsPort; +import org.onosproject.net.Port; import org.onosproject.net.PortNumber; import org.onosproject.net.SparseAnnotations; import org.onosproject.net.device.DefaultPortDescription; @@ -137,4 +142,32 @@ public final class OpticalPortOperator implements ConfigOperator { } return DefaultAnnotations.union(an, b.build()); } + + /** + * Returns a description built from an existing port. + * + * @param port the device port + * @return a PortDescription based on the port + */ + public static PortDescription descriptionOf(Port port) { + checkNotNull(port, "Must supply non-null Port"); + final PortNumber ptn = port.number(); + final boolean isup = port.isEnabled(); + final SparseAnnotations an = (SparseAnnotations) port.annotations(); + switch (port.type()) { + case OMS: + OmsPort oms = (OmsPort) port; + return new OmsPortDescription(ptn, isup, oms.minFrequency(), + oms.maxFrequency(), oms.grid(), an); + case OCH: + OchPort och = (OchPort) port; + return new OchPortDescription(ptn, isup, och.signalType(), + och.isTunable(), och.lambda(), an); + case ODUCLT: + OduCltPort odu = (OduCltPort) port; + return new OduCltPortDescription(ptn, isup, odu.signalType(), an); + default: + return new DefaultPortDescription(ptn, isup, port.type(), port.portSpeed(), an); + } + } }