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
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 ec0b124..7480462 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 @@
},
new ConfigFactory<ConnectPoint, OpticalPortConfig>(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 36686d8..a7d488b 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 @@
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 d1bcae7..b0b3abe 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.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.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.slf4j.LoggerFactory.getLogger;
import static org.onosproject.security.AppPermission.Type.*;
-
/**
* Provides implementation of the device SB & NB APIs.
*/
@@ -92,6 +93,7 @@
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 @@
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 @@
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 @@
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 void updatePorts(DeviceId deviceId,
List<PortDescription> 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 @@
log.trace("Ignoring {} port updates on standby node. {}", deviceId, portDescriptions);
return;
}
-
+ portDescriptions = portDescriptions.stream()
+ .map(e -> consolidate(deviceId, e))
+ .collect(Collectors.toList());
List<DeviceEvent> events = store.updatePorts(this.provider().id(),
deviceId, portDescriptions);
for (DeviceEvent event : events) {
@@ -433,16 +430,28 @@
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 @@
}
}
+ // 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 @@
myNextRole = NONE;
}
-
final boolean isReachable = isReachable(did);
if (!isReachable) {
// device is not connected to this node
@@ -695,23 +708,54 @@
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 af0092d..15f0879 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 @@
}
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);
+ }
+ }
}