From 09ab5e2d7dd8b64e56e98dfd84987d8b030986d2 Mon Sep 17 00:00:00 2001 From: Diego Garcia Date: Tue, 18 Dec 2018 11:47:01 +0100 Subject: [PATCH] A new RestSB driver named TapiDeviceDescriptionDiscovery.java is included within onos-odtn drivers subproject. This driver accounts for the deviceDescriptionDiscovery behavior. Removed unneeded imports and star imports, added explicit imports. Removed logs or changed them to debug level. Removed stalled references. Changed pakage to org.onosproject.drivers.odtn.tapi. Changed the class of port number to ONOS PortNumber. Changed the store of mapping information between TAPI SIP's uuid and ONOS device port Numbers to annotations instead of a hashtable. Removed CreatePortDescription function because it is unnecessary. Created checkValidEndpoint fuction to identify just valid OLS SIPs. Created getOchSignal fuction to complete the OchSignal info with the TAPI SIP information. Change-Id: I863ea0ddb233dbcc0b82c5cc67beff1f072cb35a --- .../org/onosproject/net/ChannelSpacing.java | 3 +- drivers/odtn-driver/BUILD | 4 + .../tapi/TapiDeviceDescriptionDiscovery.java | 269 ++++++++++++++++++ .../drivers/odtn/tapi/package-info.java | 19 ++ .../src/main/resources/odtn-drivers.xml | 6 + 5 files changed, 300 insertions(+), 1 deletion(-) create mode 100644 drivers/odtn-driver/src/main/java/org/onosproject/drivers/odtn/tapi/TapiDeviceDescriptionDiscovery.java create mode 100644 drivers/odtn-driver/src/main/java/org/onosproject/drivers/odtn/tapi/package-info.java diff --git a/core/api/src/main/java/org/onosproject/net/ChannelSpacing.java b/core/api/src/main/java/org/onosproject/net/ChannelSpacing.java index bae78e9277..2b21f9191e 100644 --- a/core/api/src/main/java/org/onosproject/net/ChannelSpacing.java +++ b/core/api/src/main/java/org/onosproject/net/ChannelSpacing.java @@ -25,7 +25,8 @@ public enum ChannelSpacing { CHL_50GHZ(50_000), // 50 GHz CHL_25GHZ(25_000), // 25 GHz CHL_12P5GHZ(12_500), // 12.5 GHz - CHL_6P25GHZ(6_250); // 6.25 GHz + CHL_6P25GHZ(6_250), // 6.25 GHz + CHL_0GHZ(0); // 0 GHz (Unknown) private final Frequency frequency; diff --git a/drivers/odtn-driver/BUILD b/drivers/odtn-driver/BUILD index 657d568812..bb48507280 100644 --- a/drivers/odtn-driver/BUILD +++ b/drivers/odtn-driver/BUILD @@ -2,7 +2,10 @@ COMPILE_DEPS = CORE_DEPS + [ "@commons_jxpath//jar", "//drivers/utilities:onos-drivers-utilities", "//protocols/netconf/api:onos-protocols-netconf-api", + "//protocols/rest/api:onos-protocols-rest-api", "//apps/odtn/api:onos-apps-odtn-api", + "@jackson_databind//jar", + "@javax_ws_rs_api//jar", "//apps/optical-model:onos-apps-optical-model", "//drivers/optical:onos-drivers-optical", ] @@ -30,6 +33,7 @@ onos_app( description = "Drivers related to ODTN", included_bundles = BUNDLES, required_apps = [ + "org.onosproject.restsb", "org.onosproject.netconf", "org.onosproject.config", "org.onosproject.odtn-api", diff --git a/drivers/odtn-driver/src/main/java/org/onosproject/drivers/odtn/tapi/TapiDeviceDescriptionDiscovery.java b/drivers/odtn-driver/src/main/java/org/onosproject/drivers/odtn/tapi/TapiDeviceDescriptionDiscovery.java new file mode 100644 index 0000000000..e2c12c95ce --- /dev/null +++ b/drivers/odtn-driver/src/main/java/org/onosproject/drivers/odtn/tapi/TapiDeviceDescriptionDiscovery.java @@ -0,0 +1,269 @@ +/* + * Copyright 2018-present Open Networking Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This work was partially supported by EC H2020 project METRO-HAUL (761727). + */ +package org.onosproject.drivers.odtn.tapi; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Lists; +import org.onlab.packet.ChassisId; +import org.onosproject.net.Device; +import org.onosproject.net.PortNumber; +import org.onosproject.net.DeviceId; +import org.onosproject.net.device.PortDescription; +import org.onosproject.net.device.DefaultDeviceDescription; +import org.onosproject.net.device.DeviceDescription; +import org.onosproject.net.device.DeviceDescriptionDiscovery; +import org.onosproject.net.device.DeviceService; +import org.onosproject.net.driver.AbstractHandlerBehaviour; +import org.onosproject.net.OchSignal; +import org.onosproject.net.OduSignalType; +import org.onosproject.net.GridType; +import org.onosproject.net.ChannelSpacing; +import org.onosproject.net.DefaultAnnotations; +import org.onosproject.protocol.rest.RestSBController; +import org.slf4j.Logger; + +import javax.ws.rs.core.MediaType; +import java.io.IOException; +import java.io.InputStream; +import java.util.Iterator; +import java.util.List; + +import static com.google.common.base.Preconditions.checkNotNull; +import static org.onosproject.net.optical.device.OchPortHelper.ochPortDescription; +import static org.slf4j.LoggerFactory.getLogger; + +/** + * Driver Implementation of the DeviceDescrption discovery for ONF Transport-API (TAPI) v2.1 based + * open line systems (OLS). + */ + +public class TapiDeviceDescriptionDiscovery + extends AbstractHandlerBehaviour + implements DeviceDescriptionDiscovery { + + private static final Logger log = getLogger(TapiDeviceDescriptionDiscovery.class); + private static final String SIP_REQUEST_DATA_API = "/data/context/"; + public static final String SERVICE_INTERFACE_POINT = "service-interface-point"; + public static final String UUID = "uuid"; + public static final String MEDIA_CHANNEL_SERVICE_INTERFACE_POINT_SPEC = + "media-channel-service-interface-point-spec"; + public static final String MC_POOL = "mc-pool"; + public static final String LAYER_PROTOCOL_NAME = "layer-protocol-name"; + public static final String PHOTONIC_MEDIA = "PHOTONIC_MEDIA"; + public static final String SUPPORTED_LAYER_PROTOCOL_QUALIFIER = "supported-layer-protocol-qualifier"; + public static final String PHOTONIC_LAYER_QUALIFIER_NMC = "PHOTONIC_LAYER_QUALIFIER_NMC"; + public static final String FREQUENCY_CONSTRAINT = "frequency-constraint"; + public static final String GRID_TYPE = "grid-type"; + public static final String ADJUSTMENT_GRANULARITY = "adjustment-granularity"; + public static final String UPPER_FREQUENCY = "upper-frequency"; + public static final String LOWER_FREQUENCY = "lower-frequency"; + public static final String AVAILABLE_SPECTRUM = "available-spectrum"; + private static PortNumber nPort = PortNumber.portNumber(1); + private static final long BASE_FREQUENCY = 193100000; //Working in Mhz + + /** + * Get the deviceId for which the methods apply. + * + * @return The deviceId as contained in the handler data + */ + private DeviceId did() { + return handler().data().deviceId(); + } + + @Override + public DeviceDescription discoverDeviceDetails() { + log.debug("Getting device description"); + DeviceService deviceService = checkNotNull(handler().get(DeviceService.class)); + DeviceId deviceId = handler().data().deviceId(); + Device device = deviceService.getDevice(deviceId); + + if (device == null) { + return new DefaultDeviceDescription(deviceId.uri(), + Device.Type.OLS, + "tapi-swagger", + "0", + "2.1", + "Unknown", + new ChassisId()); + } else { + return new DefaultDeviceDescription(device.id().uri(), + Device.Type.OLS, + device.manufacturer(), + device.hwVersion(), + device.swVersion(), + device.serialNumber(), + device.chassisId()); + } + } + + @Override + public List discoverPortDetails() { + log.debug("Discovering port details."); + RestSBController controller = checkNotNull(handler().get(RestSBController.class)); + DeviceId deviceId = handler().data().deviceId(); + + try { + InputStream inputStream = controller.get(deviceId, SIP_REQUEST_DATA_API, MediaType.APPLICATION_JSON_TYPE); + JsonNode jsonNode = new ObjectMapper().readTree(inputStream); + return parseTapiPorts(jsonNode); + } catch (IOException e) { + log.error("Exception discoverPortDetails() {}", did(), e); + return ImmutableList.of(); + } + } + + protected List parseTapiPorts(JsonNode tapiContext) { + List ports = Lists.newArrayList(); + int counter = 0; + + /** + This annotations are used to store persistent mapping information between TAPI SIP's uuid + and ONOS device portNumbers. This is needed to be publicly available at least within ODTN app + when connectivity services will be sent to OLS Controller. + **/ + DefaultAnnotations.Builder annotations = DefaultAnnotations.builder(); + + JsonNode sips = tapiContext.get(SERVICE_INTERFACE_POINT); + Iterator iter = sips.iterator(); + while (iter.hasNext()) { + JsonNode sipAttributes = iter.next(); + if (checkValidEndpoint(sipAttributes)) { + String uuid = sipAttributes.get(UUID).textValue(); + JsonNode mcPool = sipAttributes.get(MEDIA_CHANNEL_SERVICE_INTERFACE_POINT_SPEC).get(MC_POOL); + + OchSignal ochSignal = getOchSignal(mcPool); + //annotations(portNumber-uuid) + annotations.set(nPort.toString(), uuid); + + //add och port + ports.add(ochPortDescription(nPort, true, OduSignalType.ODU4, + false, ochSignal, annotations.build())); + + nPort = PortNumber.portNumber(counter++); + } else { + log.error("SIP {} is not valid", sipAttributes); + } + } + log.debug("PortList: {}", ports); + return ImmutableList.copyOf(ports); + } + + /** + * Create a filter method to identify just valid OLS SIPs.This method must check the + * tapi object: "layer-protocol-name" and matching only if equals to "PHOTONIC-MEDIA" SIPs. + * Moreover,the filtering could be enhanced by reading also: + * "supported-layer-protocol-qualifier", to identify valid protocol-qualifier values such: + * [PHOTONIC_LAYER_QUALIFIER_NMC, PHOTONIC_LAYER_QUALIFIER_NMCA, PHOTONIC_LAYER_QUALIFIER_OTSI...] + **/ + private boolean checkValidEndpoint(JsonNode sipAttributes) { + return (sipAttributes.get(LAYER_PROTOCOL_NAME).toString().contains(PHOTONIC_MEDIA) && + sipAttributes.get(SUPPORTED_LAYER_PROTOCOL_QUALIFIER).toString() + .contains(PHOTONIC_LAYER_QUALIFIER_NMC)); + } + + /** + * If SIP info match our criteria, SIP component shall includes mc-pool information which must be obtained in order + * to complete the OchSignal info. with the TAPI SIP information included in spectrum-supported, spectrum-available + * and spectrum-occupied tapi objects. + **/ + private OchSignal getOchSignal(JsonNode mcPool) { + long availableUpperFrec = 0, availableLowerFrec = 0; + String availableAdjustmentGranularity = "", availableGridType = ""; + JsonNode availableSpectrum = mcPool.get(AVAILABLE_SPECTRUM); + + /**At this time only the latest availableSpectrum is used**/ + Iterator iterAvailable = availableSpectrum.iterator(); + while (iterAvailable.hasNext()) { + JsonNode availableSpec = iterAvailable.next(); + availableUpperFrec = availableSpec.get(UPPER_FREQUENCY).asLong(); + availableLowerFrec = availableSpec.get(LOWER_FREQUENCY).asLong(); + availableAdjustmentGranularity = availableSpec.get(FREQUENCY_CONSTRAINT) + .get(ADJUSTMENT_GRANULARITY).textValue(); + availableGridType = availableSpec.get(FREQUENCY_CONSTRAINT).get(GRID_TYPE).textValue(); + } + + int spacingMult = 0, slotGranularity = 1; + ChannelSpacing chSpacing = getChannelSpacing(availableAdjustmentGranularity); + long spacingFrequency = chSpacing.frequency().asHz(); + long centralFrequency = (availableUpperFrec - (availableUpperFrec - availableLowerFrec) / 2); + + GridType gridType = getGridType(availableGridType); + if (gridType == GridType.DWDM) { + spacingMult = (int) ((centralFrequency - BASE_FREQUENCY) / toMbpsFromHz(spacingFrequency)); + } else if (gridType == GridType.CWDM) { + log.warn("GridType CWDM. Not implemented"); + } else if (gridType == GridType.FLEX) { + log.warn("GridType FLEX. Not implemented"); + slotGranularity = getSlotGranularity(chSpacing); + } else { + log.warn("Unknown GridType"); + } + return new OchSignal(gridType, chSpacing, spacingMult, slotGranularity); + } + + private int getSlotGranularity(ChannelSpacing chSpacing) { + if (chSpacing.equals(ChannelSpacing.CHL_100GHZ)) { + return 8; + } else if (chSpacing.equals(ChannelSpacing.CHL_50GHZ)) { + return 4; + } else if (chSpacing.equals(ChannelSpacing.CHL_25GHZ)) { + return 2; + } else if (chSpacing.equals(ChannelSpacing.CHL_12P5GHZ)) { + return 1; + } else { + return 0; + } + } + + private GridType getGridType(String gridType) { + switch (gridType) { + case "DWDM": + return GridType.DWDM; + case "CWDM": + return GridType.CWDM; + case "FLEX": + return GridType.FLEX; + default: + return GridType.UNKNOWN; + } + } + + private ChannelSpacing getChannelSpacing(String adjustmentGranularity) { + switch (adjustmentGranularity) { + case "G_100GHZ ": + return ChannelSpacing.CHL_100GHZ; + case "G_50GHZ": + return ChannelSpacing.CHL_50GHZ; + case "G_25GHZ": + return ChannelSpacing.CHL_25GHZ; + case "G_12_5GHZ ": + return ChannelSpacing.CHL_12P5GHZ; + case "G_6_25GHZ ": + return ChannelSpacing.CHL_6P25GHZ; + default: + return ChannelSpacing.CHL_0GHZ; + } + } + + private static long toMbpsFromHz(long speed) { + return speed / 1000000; + } + +} diff --git a/drivers/odtn-driver/src/main/java/org/onosproject/drivers/odtn/tapi/package-info.java b/drivers/odtn-driver/src/main/java/org/onosproject/drivers/odtn/tapi/package-info.java new file mode 100644 index 0000000000..25dc05c326 --- /dev/null +++ b/drivers/odtn-driver/src/main/java/org/onosproject/drivers/odtn/tapi/package-info.java @@ -0,0 +1,19 @@ +/* + * Copyright 2018-present Open Networking Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * ODTN Driver. + */ +package org.onosproject.drivers.odtn.tapi; diff --git a/drivers/odtn-driver/src/main/resources/odtn-drivers.xml b/drivers/odtn-driver/src/main/resources/odtn-drivers.xml index e4e6890cdd..bd3dff4630 100644 --- a/drivers/odtn-driver/src/main/resources/odtn-drivers.xml +++ b/drivers/odtn-driver/src/main/resources/odtn-drivers.xml @@ -15,6 +15,12 @@ ~ limitations under the License. --> + + + +