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
diff --git a/drivers/odtn-driver/BUILD b/drivers/odtn-driver/BUILD
index 657d568..bb48507 100644
--- a/drivers/odtn-driver/BUILD
+++ b/drivers/odtn-driver/BUILD
@@ -2,7 +2,10 @@
"@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 @@
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 0000000..e2c12c9
--- /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<PortDescription> 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<PortDescription> parseTapiPorts(JsonNode tapiContext) {
+ List<PortDescription> 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<JsonNode> 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<JsonNode> 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 0000000..25dc05c
--- /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 e4e6890..bd3dff4 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.
-->
<drivers>
+ <driver name="ols" manufacturer="tapi-swagger" hwVersion="0" swVersion="2.1">
+ <behaviour api="org.onosproject.net.device.DeviceDescriptionDiscovery"
+ impl="org.onosproject.drivers.odtn.tapi.TapiDeviceDescriptionDiscovery"/>
+ <!--<behaviour api="org.onosproject.net.flow.FlowRuleProgrammable"
+ impl="org.onosproject.drivers.odtn.TapiFlowRuleProgrammable-->
+ </driver>
<driver name="odtn" manufacturer="" hwVersion="" swVersion="">
<behaviour api="org.onosproject.net.device.DeviceDescriptionDiscovery"
impl="org.onosproject.drivers.odtn.OpenConfigDeviceDiscovery"/>