TL1 device provider with driver for Lumentum WaveReady.
ONOS-5800 & ONOS-5801
Change-Id: Icd820285eb8db2fd92c03ebf11ce022b6a82b48a
diff --git a/drivers/lumentum/BUCK b/drivers/lumentum/BUCK
index 0feb6ee..02ea7ea 100644
--- a/drivers/lumentum/BUCK
+++ b/drivers/lumentum/BUCK
@@ -3,6 +3,8 @@
'//lib:org.apache.servicemix.bundles.snmp4j',
'//drivers/utilities:onos-drivers-utilities',
'//protocols/snmp/api:onos-protocols-snmp-api',
+ '//protocols/tl1/api:onos-protocols-tl1-api',
+ '//protocols/tl1/ctl:onos-protocols-tl1-ctl',
'//incubator/api:onos-incubator-api',
'//apps/optical-model:onos-apps-optical-model',
]
@@ -25,5 +27,6 @@
category = 'Drivers',
url = 'http://onosproject.org',
description = 'ONOS Lumentum Device Drivers application.',
- required_apps = [ 'org.onosproject.snmp', 'org.onosproject.faultmanagement', 'org.onosproject.optical-model' ],
+ required_apps = [ 'org.onosproject.snmp', 'org.onosproject.faultmanagement', 'org.onosproject.optical-model',
+ 'org.onosproject.tl1'],
)
diff --git a/drivers/lumentum/pom.xml b/drivers/lumentum/pom.xml
index fdfd5a3..6dce6cd 100644
--- a/drivers/lumentum/pom.xml
+++ b/drivers/lumentum/pom.xml
@@ -38,7 +38,8 @@
<onos.app.requires>
org.onosproject.snmp,
org.onosproject.faultmanagement,
- org.onosproject.optical-model
+ org.onosproject.optical-model,
+ org.onosproject.tl1
</onos.app.requires>
</properties>
@@ -59,5 +60,15 @@
<artifactId>onos-snmp-api</artifactId>
<version>${project.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.onosproject</groupId>
+ <artifactId>onos-tl1-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.onosproject</groupId>
+ <artifactId>onos-tl1-ctl</artifactId>
+ <version>${project.version}</version>
+ </dependency>
</dependencies>
</project>
diff --git a/drivers/lumentum/src/main/java/org/onosproject/drivers/lumentum/LumentumRoadmDeviceDescription.java b/drivers/lumentum/src/main/java/org/onosproject/drivers/lumentum/LumentumRoadmDiscovery.java
similarity index 97%
rename from drivers/lumentum/src/main/java/org/onosproject/drivers/lumentum/LumentumRoadmDeviceDescription.java
rename to drivers/lumentum/src/main/java/org/onosproject/drivers/lumentum/LumentumRoadmDiscovery.java
index 46e0887..c49d6ed 100644
--- a/drivers/lumentum/src/main/java/org/onosproject/drivers/lumentum/LumentumRoadmDeviceDescription.java
+++ b/drivers/lumentum/src/main/java/org/onosproject/drivers/lumentum/LumentumRoadmDiscovery.java
@@ -46,7 +46,7 @@
/**
* Device description behaviour for Lumentum Snmp devices.
*/
-public class LumentumRoadmDeviceDescription extends AbstractHandlerBehaviour implements DeviceDescriptionDiscovery {
+public class LumentumRoadmDiscovery extends AbstractHandlerBehaviour implements DeviceDescriptionDiscovery {
private final Logger log = getLogger(getClass());
diff --git a/drivers/lumentum/src/main/java/org/onosproject/drivers/lumentum/LumentumFlowRuleProgrammable.java b/drivers/lumentum/src/main/java/org/onosproject/drivers/lumentum/LumentumSdnRoadmFlowRuleProgrammable.java
similarity index 98%
rename from drivers/lumentum/src/main/java/org/onosproject/drivers/lumentum/LumentumFlowRuleProgrammable.java
rename to drivers/lumentum/src/main/java/org/onosproject/drivers/lumentum/LumentumSdnRoadmFlowRuleProgrammable.java
index 21f9b24..7dde491 100644
--- a/drivers/lumentum/src/main/java/org/onosproject/drivers/lumentum/LumentumFlowRuleProgrammable.java
+++ b/drivers/lumentum/src/main/java/org/onosproject/drivers/lumentum/LumentumSdnRoadmFlowRuleProgrammable.java
@@ -58,10 +58,10 @@
import static com.google.common.base.Preconditions.checkArgument;
// TODO: need to convert between OChSignal and XC channel number
-public class LumentumFlowRuleProgrammable extends AbstractHandlerBehaviour implements FlowRuleProgrammable {
+public class LumentumSdnRoadmFlowRuleProgrammable extends AbstractHandlerBehaviour implements FlowRuleProgrammable {
private static final Logger log =
- LoggerFactory.getLogger(LumentumFlowRuleProgrammable.class);
+ LoggerFactory.getLogger(LumentumSdnRoadmFlowRuleProgrammable.class);
// Default values
private static final int DEFAULT_TARGET_GAIN_PREAMP = 150;
diff --git a/drivers/lumentum/src/main/java/org/onosproject/drivers/lumentum/LambdaQueryLumentumRoadm.java b/drivers/lumentum/src/main/java/org/onosproject/drivers/lumentum/LumentumSdnRoadmLambdaQuery.java
similarity index 94%
rename from drivers/lumentum/src/main/java/org/onosproject/drivers/lumentum/LambdaQueryLumentumRoadm.java
rename to drivers/lumentum/src/main/java/org/onosproject/drivers/lumentum/LumentumSdnRoadmLambdaQuery.java
index e61dc24..55f2aa7 100644
--- a/drivers/lumentum/src/main/java/org/onosproject/drivers/lumentum/LambdaQueryLumentumRoadm.java
+++ b/drivers/lumentum/src/main/java/org/onosproject/drivers/lumentum/LumentumSdnRoadmLambdaQuery.java
@@ -31,7 +31,7 @@
*
* Device supports 96 wavelengths of 50 GHz, between center frequencies 191.350 THz and 196.075 THz.
*/
-public class LambdaQueryLumentumRoadm extends AbstractHandlerBehaviour implements LambdaQuery {
+public class LumentumSdnRoadmLambdaQuery extends AbstractHandlerBehaviour implements LambdaQuery {
private static final int LAMBDA_COUNT = 96;
@Override
diff --git a/drivers/lumentum/src/main/java/org/onosproject/drivers/lumentum/LumentumWaveReadyDiscovery.java b/drivers/lumentum/src/main/java/org/onosproject/drivers/lumentum/LumentumWaveReadyDiscovery.java
new file mode 100644
index 0000000..cf9ad21
--- /dev/null
+++ b/drivers/lumentum/src/main/java/org/onosproject/drivers/lumentum/LumentumWaveReadyDiscovery.java
@@ -0,0 +1,231 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * 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.
+ */
+package org.onosproject.drivers.lumentum;
+
+import org.onlab.packet.ChassisId;
+import org.onosproject.net.ChannelSpacing;
+import org.onosproject.net.CltSignalType;
+import org.onosproject.net.DefaultAnnotations;
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.GridType;
+import org.onosproject.net.OchSignal;
+import org.onosproject.net.OduSignalType;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.SparseAnnotations;
+import org.onosproject.net.device.DefaultDeviceDescription;
+import org.onosproject.net.device.DeviceDescription;
+import org.onosproject.net.device.DeviceDescriptionDiscovery;
+import org.onosproject.net.device.PortDescription;
+import org.onosproject.net.driver.AbstractHandlerBehaviour;
+import org.onosproject.tl1.Tl1Command;
+import org.onosproject.tl1.Tl1Controller;
+import org.onosproject.tl1.Tl1Device;
+import org.onosproject.tl1.impl.DefaultTl1Command;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Optional;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.onosproject.net.optical.device.OchPortHelper.ochPortDescription;
+import static org.onosproject.net.optical.device.OduCltPortHelper.oduCltPortDescription;
+
+/**
+ * Device description behaviour for Lumentum WaveReady devices.
+ *
+ * Tested with Lumentum WaveReady 3100 transponder.
+ */
+public class LumentumWaveReadyDiscovery extends AbstractHandlerBehaviour implements DeviceDescriptionDiscovery {
+ private final Logger log = LoggerFactory.getLogger(LumentumWaveReadyDiscovery.class);
+
+ // Time to wait for device response in milliseconds
+ private static final int TIMEOUT = 10000;
+
+ private static final String LUMENTUM = "Lumentum";
+ private static final String WAVEREADY = "WaveReady";
+ private static final String SWVERSION = "1.0";
+ private static final String SERIAL = "3100";
+
+ // Some TL1 string constants
+ private static final String ACT = "ACT";
+ private static final String USER = "USER";
+ private static final String RTRV = "RTRV";
+ private static final String NETYPE = "NETYPE";
+ private static final String PLUGGABLE_INV = "PLUGGABLE-INV";
+ private static final String CANC = "CANC";
+ private static final String EIGHTFIFTY = "850";
+
+
+ @Override
+ public DeviceDescription discoverDeviceDetails() {
+ DeviceId deviceId = handler().data().deviceId();
+ Tl1Controller ctrl = checkNotNull(handler().get(Tl1Controller.class));
+ // Something reasonable, unavailable by default
+ DeviceDescription defaultDescription = new DefaultDeviceDescription(deviceId.uri(), Device.Type.OTN,
+ LUMENTUM, WAVEREADY, SWVERSION, SERIAL,
+ new ChassisId(), false, DefaultAnnotations.EMPTY);
+
+ Optional<Tl1Device> device = ctrl.getDevice(deviceId);
+ if (!device.isPresent()) {
+ return defaultDescription;
+ }
+
+ // Login
+ Tl1Command loginCmd = DefaultTl1Command.builder()
+ .withVerb(ACT)
+ .withModifier(USER)
+ .withAid(device.get().username())
+ .withCtag(100)
+ .withParameters(device.get().password())
+ .build();
+ Future<String> login = ctrl.sendMsg(deviceId, loginCmd);
+
+ try {
+ String loginResponse = login.get(TIMEOUT, TimeUnit.MILLISECONDS);
+ if (loginResponse.contains("Access denied")) {
+ log.error("Access denied: {}", loginResponse);
+ return defaultDescription;
+ }
+ } catch (InterruptedException | ExecutionException | TimeoutException e) {
+ log.error("Login failed", e);
+ return defaultDescription;
+ }
+
+ // Fetch device description
+ Tl1Command ddCmd = DefaultTl1Command.builder()
+ .withVerb(RTRV)
+ .withModifier(NETYPE)
+ .withCtag(101)
+ .build();
+ Future<String> dd = ctrl.sendMsg(deviceId, ddCmd);
+
+ try {
+ String ddResponse = dd.get(TIMEOUT, TimeUnit.MILLISECONDS);
+
+ return new DefaultDeviceDescription(defaultDescription, true, extractAnnotations(ddResponse));
+ } catch (InterruptedException | ExecutionException | TimeoutException e) {
+ log.error("Device description not found", e);
+ return defaultDescription;
+ }
+ }
+
+ @Override
+ public List<PortDescription> discoverPortDetails() {
+ DeviceId deviceId = handler().data().deviceId();
+ Tl1Controller ctrl = checkNotNull(handler().get(Tl1Controller.class));
+
+ // Assume we're successfully logged in
+ // Fetch port descriptions
+ Tl1Command pdCmd = DefaultTl1Command.builder()
+ .withVerb(RTRV)
+ .withModifier(PLUGGABLE_INV)
+ .withCtag(102)
+ .build();
+ Future<String> pd = ctrl.sendMsg(deviceId, pdCmd);
+
+ try {
+ String pdResponse = pd.get(TIMEOUT, TimeUnit.MILLISECONDS);
+
+ return extractPorts(pdResponse);
+ } catch (InterruptedException | ExecutionException | TimeoutException e) {
+ log.error("Port description not found", e);
+ return Collections.EMPTY_LIST;
+ }
+ }
+
+ private SparseAnnotations extractAnnotations(String s) {
+ DefaultAnnotations.Builder annot = DefaultAnnotations.builder();
+
+ Arrays.stream(s.split(",")).forEach(w -> {
+ String[] pair = w.replaceAll("\\\\\"", "").split("=");
+ if (pair.length == 2) {
+ annot.set(pair[0], pair[1]);
+ } else {
+ annot.set(pair[0], "");
+ }
+ });
+
+ return annot.build();
+ }
+
+ // Extract ports from response on pluggable inventory retrieval.
+ // Client ports are identified by 850nm, everything else is a network port.
+ private List<PortDescription> extractPorts(String s) {
+ List<PortDescription> ports = new ArrayList<>();
+
+ if (s.length() == 0) {
+ return ports;
+ }
+
+ Arrays.stream(s.split("\"\"")).forEach(p -> {
+ if (p.contains(EIGHTFIFTY)) {
+ PortDescription cltPort = oduCltPortDescription(
+ PortNumber.portNumber(ports.size() + 1),
+ true,
+ CltSignalType.CLT_10GBE,
+ extractAnnotations(p));
+ ports.add(cltPort);
+ } else {
+ PortDescription netPort = ochPortDescription(
+ PortNumber.portNumber(ports.size() + 1),
+ true,
+ OduSignalType.ODU2e,
+ true,
+ new OchSignal(GridType.DWDM, ChannelSpacing.CHL_50GHZ, 0, 4),
+ extractAnnotations(p));
+ ports.add(netPort);
+ }
+ });
+
+ return ports;
+ }
+
+ // Unused but provided here for convenience.
+ private void logout() {
+ DeviceId deviceId = handler().data().deviceId();
+ Tl1Controller ctrl = checkNotNull(handler().get(Tl1Controller.class));
+
+ Optional<Tl1Device> device = ctrl.getDevice(deviceId);
+ if (!device.isPresent()) {
+ return;
+ }
+
+ // Logout command
+ Tl1Command logoutCmd = DefaultTl1Command.builder()
+ .withVerb(CANC)
+ .withModifier(USER)
+ .withAid(device.get().username())
+ .withCtag(103)
+ .build();
+ Future<String> logout = ctrl.sendMsg(deviceId, logoutCmd);
+
+ try {
+ String logoutResponse = logout.get(TIMEOUT, TimeUnit.MILLISECONDS);
+
+ } catch (InterruptedException | ExecutionException | TimeoutException e) {
+ log.error("Lougout failed", e);
+ }
+ }
+}
diff --git a/drivers/lumentum/src/main/resources/lumentum-drivers.xml b/drivers/lumentum/src/main/resources/lumentum-drivers.xml
index bb4b87b..230cc34 100644
--- a/drivers/lumentum/src/main/resources/lumentum-drivers.xml
+++ b/drivers/lumentum/src/main/resources/lumentum-drivers.xml
@@ -15,17 +15,23 @@
~ limitations under the License.
-->
<drivers>
- <driver name="lumentum" manufacturer="Lumentum" hwVersion="SDN ROADM" swVersion="1.0">
+ <driver name="lumentum-sdn" manufacturer="Lumentum" hwVersion="SDN ROADM" swVersion="1.0">
<behaviour api="org.onosproject.net.device.DeviceDescriptionDiscovery"
- impl="org.onosproject.drivers.lumentum.LumentumRoadmDeviceDescription"/>
+ impl="org.onosproject.drivers.lumentum.LumentumRoadmDiscovery"/>
<behaviour api="org.onosproject.net.behaviour.LambdaQuery"
- impl="org.onosproject.drivers.lumentum.LambdaQueryLumentumRoadm"/>
+ impl="org.onosproject.drivers.lumentum.LumentumSdnRoadmLambdaQuery"/>
<behaviour api="org.onosproject.net.flow.FlowRuleProgrammable"
- impl="org.onosproject.drivers.lumentum.LumentumFlowRuleProgrammable"/>
+ impl="org.onosproject.drivers.lumentum.LumentumSdnRoadmFlowRuleProgrammable"/>
<behaviour api="org.onosproject.incubator.net.faultmanagement.alarm.AlarmConsumer"
impl="org.onosproject.drivers.lumentum.LumentumAlarmConsumer"/>
<behaviour api="org.onosproject.net.optical.OpticalDevice"
impl="org.onosproject.net.optical.DefaultOpticalDevice"/>
</driver>
+ <driver name="lumentum-waveready" manufacturer="Lumentum" hwVersion="WR*">
+ <behaviour api="org.onosproject.net.device.DeviceDescriptionDiscovery"
+ impl="org.onosproject.drivers.lumentum.LumentumWaveReadyDiscovery"/>
+ <behaviour api="org.onosproject.net.optical.OpticalDevice"
+ impl="org.onosproject.net.optical.DefaultOpticalDevice"/>
+ </driver>
</drivers>
diff --git a/drivers/lumentum/src/test/java/org/onosproject/drivers/lumentum/LumentumDriversLoaderTest.java b/drivers/lumentum/src/test/java/org/onosproject/drivers/lumentum/LumentumDriversLoaderTest.java
deleted file mode 100644
index 1723337..0000000
--- a/drivers/lumentum/src/test/java/org/onosproject/drivers/lumentum/LumentumDriversLoaderTest.java
+++ /dev/null
@@ -1,15 +0,0 @@
-package org.onosproject.drivers.lumentum;
-
-import org.junit.Before;
-import org.onosproject.net.driver.AbstractDriverLoaderTest;
-
-/**
- * Lumentum drivers loader test.
- */
-public class LumentumDriversLoaderTest extends AbstractDriverLoaderTest {
-
- @Before
- public void setUp() {
- loader = new LumentumDriversLoader();
- }
-}