[ONOS-7948] Netconf driver for Lumentum ROADM-20.
Added support for flowrules coming from the compilation of an OpticalConnectivityIntent.
FlowRules coming from ROADM app are still supported.
Minor updates to DeviceDiscovery and PowerConfig.
Patch 2: Driver and OpticalPathIntent support for partner-ports.
Now bidirectional intents can be configured also in presence of unidirectional links.
ROADM app visualizes devices of type TERMINAL_DEVICE and partner port details.
Checkstyle.
Patch 3: [ONOS-7974] [ONOS-79076] partner-port renamed to reverse-port. Bug fix.
Addressed comments by Ramon Casellas and Andrea Campanella. Checkstyles.
Patch 4: documentation.
Patch 5: addressed comments by Andrea Campanella.
Patch 6: checkstyle.
Change-Id: Ie5ca41eee6cb6f8f87f076f2af19c99cadd6d851
diff --git a/apps/optical-model/src/main/java/org/onosproject/net/optical/intent/impl/compiler/OpticalPathIntentCompiler.java b/apps/optical-model/src/main/java/org/onosproject/net/optical/intent/impl/compiler/OpticalPathIntentCompiler.java
index d269843..f2a20fa 100644
--- a/apps/optical-model/src/main/java/org/onosproject/net/optical/intent/impl/compiler/OpticalPathIntentCompiler.java
+++ b/apps/optical-model/src/main/java/org/onosproject/net/optical/intent/impl/compiler/OpticalPathIntentCompiler.java
@@ -17,6 +17,12 @@
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Lists;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Link;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.Port;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Deactivate;
@@ -24,11 +30,7 @@
import org.osgi.service.component.annotations.ReferenceCardinality;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
-import org.onosproject.net.ConnectPoint;
-import org.onosproject.net.Device;
import org.onosproject.net.Device.Type;
-import org.onosproject.net.DeviceId;
-import org.onosproject.net.Link;
import org.onosproject.net.device.DeviceService;
import org.onosproject.net.device.DeviceServiceAdapter;
import org.onosproject.net.flow.DefaultFlowRule;
@@ -204,7 +206,7 @@
*/
private List<FlowRule> createReverseRules(OpticalPathIntent intent) {
TrafficSelector.Builder selectorBuilder = DefaultTrafficSelector.builder();
- selectorBuilder.matchInPort(intent.dst().port());
+ selectorBuilder.matchInPort(reversePort(intent.dst().deviceId(), intent.dst().port()));
List<FlowRule> rules = new LinkedList<>();
@@ -219,7 +221,7 @@
if (!isTransparent(intent.src().deviceId())) {
treatmentBuilder.add(Instructions.modL0Lambda(intent.lambda()));
}
- treatmentBuilder.setOutput(intent.src().port());
+ treatmentBuilder.setOutput(reversePort(intent.src().deviceId(), intent.src().port()));
FlowRule rule = DefaultFlowRule.builder()
.forDevice(intent.src().deviceId())
@@ -240,7 +242,7 @@
if (!isTransparent(current.deviceId())) {
treatmentBuilder.add(Instructions.modL0Lambda(intent.lambda()));
}
- treatmentBuilder.setOutput(link.dst().port());
+ treatmentBuilder.setOutput(reversePort(link.dst().deviceId(), link.dst().port()));
FlowRule rule = DefaultFlowRule.builder()
.forDevice(current.deviceId())
@@ -257,7 +259,7 @@
}
current = link.src();
- selectorBuilder.matchInPort(link.src().port());
+ selectorBuilder.matchInPort(reversePort(link.src().deviceId(), link.src().port()));
if (!isTransparent(current.deviceId())) {
selectorBuilder.add(Criteria.matchLambda(intent.lambda()));
selectorBuilder.add(Criteria.matchOchSignalType(intent.signalType()));
@@ -266,7 +268,7 @@
// Build the egress ROADM rule
TrafficTreatment.Builder treatmentLast = DefaultTrafficTreatment.builder();
- treatmentLast.setOutput(intent.src().port());
+ treatmentLast.setOutput(reversePort(intent.src().deviceId(), intent.src().port()));
FlowRule rule = new DefaultFlowRule.Builder()
.forDevice(intent.src().deviceId())
@@ -285,6 +287,25 @@
}
/**
+ * Returns the PortNum of reverse port if annotation is present, otherwise return PortNum of the port itself.
+ * In the OpenROADM YANG models it is used the term "partner-port.
+ *
+ * @param portNumber the port
+ * @return the PortNum of reverse port if annotation is present, otherwise PortNum of the port itself.
+ */
+ private PortNumber reversePort(DeviceId deviceId, PortNumber portNumber) {
+ Port port = deviceService.getPort(deviceId, portNumber);
+
+ String reversePort = port.annotations().value(OpticalPathIntent.REVERSE_PORT_ANNOTATION_KEY);
+ if (reversePort != null) {
+ PortNumber reversePortNumber = PortNumber.portNumber(reversePort);
+ return reversePortNumber;
+ } else {
+ return portNumber;
+ }
+ }
+
+ /**
* Returns true if device does not accept flow rules, false otherwise.
*
* @param deviceId the device
diff --git a/apps/roadm/src/main/java/org/onosproject/roadm/RoadmDeviceViewMessageHandler.java b/apps/roadm/src/main/java/org/onosproject/roadm/RoadmDeviceViewMessageHandler.java
index 926b576..51c8946 100644
--- a/apps/roadm/src/main/java/org/onosproject/roadm/RoadmDeviceViewMessageHandler.java
+++ b/apps/roadm/src/main/java/org/onosproject/roadm/RoadmDeviceViewMessageHandler.java
@@ -92,7 +92,8 @@
protected void populateTable(TableModel tm, ObjectNode payload) {
for (Device device : deviceService.getDevices()) {
Type type = device.type();
- if (type == Type.ROADM || type == Type.OPTICAL_AMPLIFIER || type == Type.FIBER_SWITCH) {
+ if (type == Type.ROADM || type == Type.TERMINAL_DEVICE
+ || type == Type.OPTICAL_AMPLIFIER || type == Type.FIBER_SWITCH) {
populateRow(tm.addRow(), device);
}
}
diff --git a/apps/roadm/src/main/java/org/onosproject/roadm/RoadmPortViewMessageHandler.java b/apps/roadm/src/main/java/org/onosproject/roadm/RoadmPortViewMessageHandler.java
index 52a73d5..192eb2e 100644
--- a/apps/roadm/src/main/java/org/onosproject/roadm/RoadmPortViewMessageHandler.java
+++ b/apps/roadm/src/main/java/org/onosproject/roadm/RoadmPortViewMessageHandler.java
@@ -31,6 +31,7 @@
import org.onosproject.net.OchSignal;
import org.onosproject.net.Port;
import org.onosproject.net.PortNumber;
+import org.onosproject.net.intent.OpticalPathIntent;
import org.onosproject.net.optical.OpticalAnnotations;
import org.onosproject.ui.RequestHandler;
import org.onosproject.ui.UiConnection;
@@ -69,6 +70,7 @@
private static final String ROADM_SET_OPS_MODE_RESP = "roadmSetOpsModeResponse";
private static final String ID = "id";
+ private static final String REVERSE_PORT = "reversePort";
private static final String NAME = "name";
private static final String TYPE = "type";
private static final String ENABLED = "enabled";
@@ -82,7 +84,7 @@
private static final String SERVICE_STATE = "serviceState";
private static final String[] COLUMN_IDS = {
- ID, TYPE, NAME, ENABLED, MIN_FREQ, MAX_FREQ, GRID, POWER_RANGE,
+ ID, REVERSE_PORT, TYPE, NAME, ENABLED, MIN_FREQ, MAX_FREQ, GRID, POWER_RANGE,
CURRENT_POWER, SERVICE_STATE, TARGET_POWER, HAS_TARGET_POWER
};
@@ -139,6 +141,8 @@
PortNumber portNum = port.number();
getFrequencyLimit(deviceId, portNum);
row.cell(ID, portNum.toLong())
+ .cell(REVERSE_PORT, RoadmUtil.getAnnotation(port.annotations(),
+ OpticalPathIntent.REVERSE_PORT_ANNOTATION_KEY))
.cell(TYPE, port.type())
.cell(ENABLED, port.isEnabled())
.cell(NAME, RoadmUtil.getAnnotation(port.annotations(), AnnotationKeys.PORT_NAME))
diff --git a/apps/roadm/src/main/resources/app/view/roadmPort/roadmPort.html b/apps/roadm/src/main/resources/app/view/roadmPort/roadmPort.html
index f896ebd..57cc441 100644
--- a/apps/roadm/src/main/resources/app/view/roadmPort/roadmPort.html
+++ b/apps/roadm/src/main/resources/app/view/roadmPort/roadmPort.html
@@ -31,6 +31,7 @@
<table>
<tr>
<td colId="id" sortable>Port Number </td>
+ <td colId="reversePort" sortable>Reverse </td>
<td colId="name" sortable>Name </td>
<td colId="type" sortable>Type </td>
<td colId="enabled" sortable>Enabled </td>
@@ -56,6 +57,7 @@
<tr ng-repeat="item in tableData track by $index"
ng-class="{selected: item.id === selId}">
<td>{{item.id}}</td>
+ <td>{{item.reversePort}}</td>
<td>{{item.name}}</td>
<td>{{item.type}}</td>
<td>{{item.enabled}}</td>
diff --git a/core/api/src/main/java/org/onosproject/net/intent/OpticalPathIntent.java b/core/api/src/main/java/org/onosproject/net/intent/OpticalPathIntent.java
index 1369098..b2e7a3c 100644
--- a/core/api/src/main/java/org/onosproject/net/intent/OpticalPathIntent.java
+++ b/core/api/src/main/java/org/onosproject/net/intent/OpticalPathIntent.java
@@ -41,6 +41,8 @@
private final OchSignalType signalType;
private final boolean isBidirectional;
+ public static final String REVERSE_PORT_ANNOTATION_KEY = "reverse-port";
+
private OpticalPathIntent(ApplicationId appId,
Key key,
ConnectPoint src,
diff --git a/drivers/lumentum/src/main/java/org/onosproject/drivers/lumentum/LumentumConnection.java b/drivers/lumentum/src/main/java/org/onosproject/drivers/lumentum/LumentumConnection.java
index c63ac1e..58c5b78 100644
--- a/drivers/lumentum/src/main/java/org/onosproject/drivers/lumentum/LumentumConnection.java
+++ b/drivers/lumentum/src/main/java/org/onosproject/drivers/lumentum/LumentumConnection.java
@@ -16,7 +16,6 @@
package org.onosproject.drivers.lumentum;
-import org.onosproject.driver.optical.flowrule.CrossConnectFlowRule;
import org.onosproject.net.OchSignal;
import org.onosproject.net.PortNumber;
import org.slf4j.Logger;
@@ -45,6 +44,8 @@
protected double inputPower;
protected double outputPower;
+ protected LumentumFlowRule rule;
+
//TODO: compute target attenuation to obtain the desired targetPower
/**
@@ -54,7 +55,7 @@
* @param flowRuleHash the hash code associated to the Flow Rule
* @param xc the cross connect flow rule
*/
- public LumentumConnection(Integer id, Integer flowRuleHash, CrossConnectFlowRule xc) {
+ public LumentumConnection(Integer id, Integer flowRuleHash, LumentumFlowRule xc) {
connectionId = id;
hashCode = flowRuleHash;
@@ -64,6 +65,7 @@
attenuation = 0.0; //dB
inputPower = 0.0; //dBm
outputPower = 0.0; //dBm
+ rule = xc;
if (isAddRule) {
outPortNumber = LumentumNetconfRoadmFlowRuleProgrammable.LINE_PORT_NUMBER;
diff --git a/drivers/lumentum/src/main/java/org/onosproject/drivers/lumentum/LumentumFlowRule.java b/drivers/lumentum/src/main/java/org/onosproject/drivers/lumentum/LumentumFlowRule.java
new file mode 100644
index 0000000..9489ff1
--- /dev/null
+++ b/drivers/lumentum/src/main/java/org/onosproject/drivers/lumentum/LumentumFlowRule.java
@@ -0,0 +1,161 @@
+/*
+ * Copyright 2017-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.
+ */
+
+package org.onosproject.drivers.lumentum;
+
+import org.onosproject.net.OchSignal;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.flow.DefaultFlowRule;
+import org.onosproject.net.flow.FlowRule;
+import org.onosproject.net.flow.criteria.Criterion;
+import org.onosproject.net.flow.criteria.OchSignalCriterion;
+import org.onosproject.net.flow.criteria.OchSignalTypeCriterion;
+import org.onosproject.net.flow.criteria.PortCriterion;
+import org.onosproject.net.flow.instructions.Instruction;
+import org.onosproject.net.flow.instructions.Instructions;
+import org.onosproject.net.flow.instructions.L0ModificationInstruction;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.List;
+import java.util.Set;
+
+import static com.google.common.base.Preconditions.checkArgument;
+
+public class LumentumFlowRule extends DefaultFlowRule {
+ private static final Logger log = LoggerFactory.getLogger(LumentumFlowRule.class);
+
+ protected enum Type {
+ OPTICAL_CONNECTIVITY_INTENT_RULE,
+ ROADM_APP_RULE
+ }
+ public Type type;
+
+ private PortNumber addDrop;
+
+ private PortNumber inputPort;
+ private PortNumber outputPort;
+
+ private OchSignal ochSignal;
+ private boolean isAddRule;
+
+ //As generated by the OpticalConnectivityIntentCompiler
+ private static final int NUM_CRITERIA_INTENT = 3;
+ private static final int NUM_INSTRUCTIONS_INTENT = 2;
+
+ //As generated dy ROADM app
+ private static final int NUM_CRITERIA_ROADM = 3;
+ private static final int NUM_INSTRUCTIONS_ROADM = 1;
+
+ public LumentumFlowRule(FlowRule rule, List<PortNumber> linePorts) {
+ super(rule);
+
+ Set<Criterion> criteria = rule.selector().criteria();
+ List<Instruction> instructions = rule.treatment().immediate();
+
+ // Proper cross connect has criteria for input port, OChSignal and OCh signal type.
+ // Instruction is only output to port (rule generated by ROADM app).
+ // Instruction includes output port and OChSignal (rule generated by OpticalConnectivityIntent).
+ checkArgument((criteria.size() == NUM_CRITERIA_INTENT) ||
+ (criteria.size() == NUM_CRITERIA_ROADM),
+ "Wrong size of flow rule criteria for cross connect.");
+ checkArgument((instructions.size() == NUM_INSTRUCTIONS_INTENT) ||
+ (instructions.size() == NUM_INSTRUCTIONS_ROADM),
+ "Wrong size of flow rule instructions for cross connect.");
+
+ // FIXME: Ensure criteria has exactly one of each match type
+ criteria.forEach(
+ c -> checkArgument(c instanceof OchSignalCriterion ||
+ c instanceof OchSignalTypeCriterion ||
+ c instanceof PortCriterion,
+ "Incompatible flow rule criteria for LumentumROADM: " + criteria
+ )
+ );
+
+ instructions.forEach(
+ c -> checkArgument(c instanceof Instructions.OutputInstruction ||
+ c instanceof L0ModificationInstruction,
+ "Incompatible flow rule instruction for LumentumROADM: " + instructions
+ )
+ );
+
+ if (criteria.size() == NUM_CRITERIA_INTENT && instructions.size() == NUM_INSTRUCTIONS_INTENT) {
+ log.info("Lumentum device, FlowRule coming from OpticalConnectivityIntentCompiler");
+
+ type = Type.OPTICAL_CONNECTIVITY_INTENT_RULE;
+ } else {
+ log.info("Lumentum device, FlowRule coming from ROADM app");
+
+ type = Type.ROADM_APP_RULE;
+ }
+
+ ochSignal = criteria.stream()
+ .filter(c -> c instanceof OchSignalCriterion)
+ .map(c -> ((OchSignalCriterion) c).lambda())
+ .findAny()
+ .orElse(null);
+
+ inputPort = criteria.stream()
+ .filter(c -> c instanceof PortCriterion)
+ .map(c -> ((PortCriterion) c).port())
+ .findAny()
+ .orElse(null);
+
+ outputPort = instructions.stream()
+ .filter(c -> c instanceof Instructions.OutputInstruction)
+ .map(c -> ((Instructions.OutputInstruction) c).port())
+ .findAny()
+ .orElse(null);
+
+ // Add or drop rule? Get the output instruction
+ Instructions.OutputInstruction outInstruction = (Instructions.OutputInstruction) instructions.stream()
+ .filter(c -> c instanceof Instructions.OutputInstruction)
+ .findAny()
+ .orElse(null);
+
+ if (linePorts.contains(outInstruction.port())) {
+ addDrop = criteria.stream()
+ .filter(c -> c instanceof PortCriterion)
+ .map(c -> ((PortCriterion) c).port())
+ .findAny()
+ .orElse(null);
+ isAddRule = true;
+ } else {
+ addDrop = outInstruction.port();
+ isAddRule = false;
+ }
+ }
+
+ public PortNumber addDrop() {
+ return addDrop;
+ }
+
+ public OchSignal ochSignal() {
+ return ochSignal;
+ }
+
+ public boolean isAddRule() {
+ return isAddRule;
+ }
+
+ public PortNumber getInputPort() {
+ return inputPort;
+ }
+
+ public PortNumber getOutputPort() {
+ return outputPort;
+ }
+}
diff --git a/drivers/lumentum/src/main/java/org/onosproject/drivers/lumentum/LumentumNetconfRoadmDiscovery.java b/drivers/lumentum/src/main/java/org/onosproject/drivers/lumentum/LumentumNetconfRoadmDiscovery.java
index 2cdcc1a..eea8b59 100644
--- a/drivers/lumentum/src/main/java/org/onosproject/drivers/lumentum/LumentumNetconfRoadmDiscovery.java
+++ b/drivers/lumentum/src/main/java/org/onosproject/drivers/lumentum/LumentumNetconfRoadmDiscovery.java
@@ -23,14 +23,17 @@
import org.apache.commons.configuration.XMLConfiguration;
import org.apache.commons.lang3.StringUtils;
+import org.onlab.packet.ChassisId;
+import org.onlab.util.Frequency;
import org.onosproject.drivers.utilities.XmlConfigParser;
+import org.onosproject.net.ChannelSpacing;
+import org.onosproject.net.SparseAnnotations;
+import org.onosproject.net.DefaultAnnotations;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Device;
import org.onosproject.net.Port;
import org.onosproject.net.PortNumber;
-import org.onosproject.net.DefaultAnnotations;
-import org.onosproject.net.SparseAnnotations;
import org.onosproject.net.AnnotationKeys;
-import org.onosproject.net.Device;
-import org.onosproject.net.DeviceId;
import org.onosproject.net.device.DefaultDeviceDescription;
import org.onosproject.net.device.DefaultPortDescription;
import org.onosproject.net.device.DeviceDescription;
@@ -38,6 +41,7 @@
import org.onosproject.net.device.DeviceService;
import org.onosproject.net.device.PortDescription;
import org.onosproject.net.driver.AbstractHandlerBehaviour;
+import org.onosproject.net.intent.OpticalPathIntent;
import org.onosproject.netconf.NetconfController;
import org.onosproject.netconf.NetconfException;
import org.onosproject.netconf.NetconfSession;
@@ -49,6 +53,7 @@
import java.util.List;
import static com.google.common.base.Preconditions.checkNotNull;
+import static org.onosproject.net.optical.device.OmsPortHelper.omsPortDescription;
import static org.slf4j.LoggerFactory.getLogger;
/**
@@ -72,27 +77,33 @@
private static final String IN_SERVICE = "in-service";
private static final String PORT_NAME = "entity-description";
+ public static final ChannelSpacing CHANNEL_SPACING_50 = ChannelSpacing.CHL_50GHZ;
+ public static final Frequency START_CENTER_FREQ_50 = Frequency.ofGHz(191_350);
+ public static final Frequency END_CENTER_FREQ_50 = Frequency.ofGHz(196_100);
+
+ private static final int MIN_MUX_PORT = 4101;
+ private static final int MAX_MUX_PORT = 4120;
+ private static final int MIN_DEM_PORT = 5201;
+ private static final int MAX_DEM_PORT = 5220;
+ private static final int DELTA_MUX_DEM_PORT = MIN_DEM_PORT - MIN_MUX_PORT;
+
private final Logger log = getLogger(getClass());
@Override
public DeviceDescription discoverDeviceDetails() {
+ SparseAnnotations annotations = DefaultAnnotations.builder().build();
+
+ log.info("Lumentum NETCONF - starting discoverDeviceDetails");
// Some defaults values
String vendor = "Lumentum";
String hwVersion = "not loaded";
String swVersion = "not loaded";
String serialNumber = "not loaded";
- String chassisId = "not loaded";
+ String chassisData = "ne=1;chassis=10";
+ ChassisId chassisId = null;
DeviceId deviceId = handler().data().deviceId();
- DeviceService deviceService = checkNotNull(handler().get(DeviceService.class));
- Device device = deviceService.getDevice(deviceId);
-
- //Get the configuration from the device
- if (device == null) {
- log.error("Lumentum NETCONF - device object not found for {}", deviceId);
- return null;
- }
NetconfSession session = getNetconfSession();
@@ -131,7 +142,10 @@
hwVersion = xconf.getString("data.chassis-list.chassis.state.loteq:hardware-rev", hwVersion);
serialNumber = xconf.getString("data.chassis-list.chassis.state.loteq:serial-no", serialNumber);
- chassisId = xconf.getString("data.chassis-list.chassis.dn", chassisId);
+ chassisData = xconf.getString("data.chassis-list.chassis.dn", chassisData);
+
+ String[] parts = chassisData.split("chassis=");
+ chassisId = new ChassisId(Long.valueOf(parts[1], 10));
} catch (NetconfException e) {
log.error("Lumentum NETCONF error in session.get", e);
@@ -151,8 +165,7 @@
//Return the Device Description
return new DefaultDeviceDescription(deviceId.uri(), Device.Type.ROADM,
- vendor, hwVersion, swVersion, serialNumber,
- device.chassisId(), (SparseAnnotations) device.annotations());
+ vendor, hwVersion, swVersion, serialNumber, chassisId, annotations);
}
@Override
@@ -246,6 +259,27 @@
log.error("Port Type not correctly loaded");
}
+ //Store reverse port index in the annotations
+ Long reversePortId;
+
+ /**
+ * Setting the reverse port value for the unidirectional ports.
+ *
+ * In this device each port includes an input fiber and an output fiber.
+ * The 20 input fibers are numbered from MIN_MUX_PORT = 4101 to MAX_MUX_PORT = 4120.
+ * The 20 output fibers are numbered from MIN_DEM_PORT = 5201 to MAX_DEM_PORT = 5220.
+ *
+ * Where port 520x is always the reverse of 410x.
+ */
+ if ((portNum.toLong() >= MIN_MUX_PORT) && (portNum.toLong() <= MAX_MUX_PORT)) {
+ reversePortId = portNum.toLong() + DELTA_MUX_DEM_PORT;
+ annotations.set(OpticalPathIntent.REVERSE_PORT_ANNOTATION_KEY, reversePortId.toString());
+ }
+ if ((portNum.toLong() >= MIN_DEM_PORT) && (portNum.toLong() <= MAX_DEM_PORT)) {
+ reversePortId = portNum.toLong() - DELTA_MUX_DEM_PORT;
+ annotations.set(OpticalPathIntent.REVERSE_PORT_ANNOTATION_KEY, reversePortId.toString());
+ }
+
//Load other information
pcfg.getKeys().forEachRemaining(k -> {
if (!k.contains(DN) && !k.contains(PORT_SPEED) && !k.contains(PORT_EXTENSION)
@@ -271,14 +305,23 @@
log.debug("Lumentum NETCONF - retrieved port {},{},{},{},{}",
portNum, isEnabled, type, speed, annotations.build());
- DefaultPortDescription.Builder portDescriptionBuilder = DefaultPortDescription.builder();
- portDescriptionBuilder.withPortNumber(portNum)
- .isEnabled(isEnabled)
- .type(type)
- .portSpeed(speed)
- .annotations(annotations.build());
+ if (type == Port.Type.FIBER) {
+ portDescriptions.add(omsPortDescription(portNum,
+ isEnabled,
+ START_CENTER_FREQ_50,
+ END_CENTER_FREQ_50,
+ CHANNEL_SPACING_50.frequency(),
+ annotations.build()));
+ } else {
+ DefaultPortDescription.Builder portDescriptionBuilder = DefaultPortDescription.builder();
+ portDescriptionBuilder.withPortNumber(portNum)
+ .isEnabled(isEnabled)
+ .type(type)
+ .portSpeed(speed)
+ .annotations(annotations.build());
- portDescriptions.add(portDescriptionBuilder.build());
+ portDescriptions.add(portDescriptionBuilder.build());
+ }
});
return portDescriptions;
diff --git a/drivers/lumentum/src/main/java/org/onosproject/drivers/lumentum/LumentumNetconfRoadmFlowRuleProgrammable.java b/drivers/lumentum/src/main/java/org/onosproject/drivers/lumentum/LumentumNetconfRoadmFlowRuleProgrammable.java
index ccf2c5a..13f82eb 100644
--- a/drivers/lumentum/src/main/java/org/onosproject/drivers/lumentum/LumentumNetconfRoadmFlowRuleProgrammable.java
+++ b/drivers/lumentum/src/main/java/org/onosproject/drivers/lumentum/LumentumNetconfRoadmFlowRuleProgrammable.java
@@ -22,7 +22,6 @@
import org.onlab.util.Frequency;
import org.onlab.util.Spectrum;
import org.onosproject.driver.optical.flowrule.CrossConnectCache;
-import org.onosproject.driver.optical.flowrule.CrossConnectFlowRule;
import org.onosproject.drivers.utilities.XmlConfigParser;
import org.onosproject.net.ChannelSpacing;
import org.onosproject.net.GridType;
@@ -42,6 +41,7 @@
import org.onosproject.net.flow.TrafficSelector;
import org.onosproject.net.flow.TrafficTreatment;
import org.onosproject.net.flow.criteria.Criteria;
+import org.onosproject.net.flow.instructions.Instructions;
import org.onosproject.netconf.NetconfController;
import org.onosproject.netconf.NetconfException;
import org.onosproject.netconf.NetconfSession;
@@ -127,14 +127,14 @@
public Collection<FlowRule> applyFlowRules(Collection<FlowRule> rules) {
// Apply the rules on the device
Collection<FlowRule> added = rules.stream()
- .map(r -> new CrossConnectFlowRule(r, getLinePorts()))
+ .map(r -> new LumentumFlowRule(r, getLinePorts()))
.filter(xc -> rpcAddConnection(xc))
.collect(Collectors.toList());
// Cache the cookie/priority
CrossConnectCache cache = this.handler().get(CrossConnectCache.class);
added.forEach(xc -> cache.set(
- Objects.hash(data().deviceId(), xc.selector(), xc.treatment()),
+ Objects.hash(data().deviceId(), xc.selector()),
xc.id(),
xc.priority()));
@@ -148,14 +148,14 @@
public Collection<FlowRule> removeFlowRules(Collection<FlowRule> rules) {
// Remove the valid rules from the device
Collection<FlowRule> removed = rules.stream()
- .map(r -> new CrossConnectFlowRule(r, getLinePorts()))
+ .map(r -> new LumentumFlowRule(r, getLinePorts()))
.filter(xc -> rpcDeleteConnection(xc))
.collect(Collectors.toList());
// Remove flow rule from cache
CrossConnectCache cache = this.handler().get(CrossConnectCache.class);
removed.forEach(xc -> cache.remove(
- Objects.hash(data().deviceId(), xc.selector(), xc.treatment())));
+ Objects.hash(data().deviceId(), xc.selector())));
removed.forEach(xc -> log.debug("Lumentum NETCONF - removed cached FlowRule selector {} treatment {}",
xc.selector(), xc.treatment()));
@@ -261,14 +261,11 @@
.add(Criteria.matchOchSignalType(OchSignalType.FIXED_GRID))
.add(Criteria.matchLambda(toOchSignal(startFreq, endFreq)))
.build();
- TrafficTreatment treatment = DefaultTrafficTreatment.builder()
- .setOutput(pair.getLeft() == 1 ? LINE_PORT_NUMBER : portNumber)
- .build();
log.debug("Lumentum NETCONF - retrieved FlowRule startFreq {} endFreq {}", startFreq, endFreq);
// Lookup flow ID and priority
- int hash = Objects.hash(data().deviceId(), selector, treatment);
+ int hash = Objects.hash(data().deviceId(), selector);
CrossConnectCache cache = this.handler().get(CrossConnectCache.class);
Pair<FlowId, Integer> lookup = cache.get(hash);
@@ -277,6 +274,18 @@
.findFirst()
.orElse(null);
+ TrafficTreatment treatment;
+ if (conn.rule.type == LumentumFlowRule.Type.OPTICAL_CONNECTIVITY_INTENT_RULE) {
+ treatment = DefaultTrafficTreatment.builder()
+ .add(Instructions.modL0Lambda(toOchSignal(startFreq, endFreq)))
+ .setOutput(pair.getLeft() == 1 ? LINE_PORT_NUMBER : portNumber)
+ .build();
+ } else { // This is ROADM_APP_RULE
+ treatment = DefaultTrafficTreatment.builder()
+ .setOutput(pair.getLeft() == 1 ? LINE_PORT_NUMBER : portNumber)
+ .build();
+ }
+
//If the flow entry is not in the cache: return null/publish the flow rule
if ((lookup == null) || (conn == null)) {
log.error("Lumentum NETCONF connection not in connectionSet {}", pair.getRight());
@@ -328,7 +337,7 @@
* @param xc the cross connect flow rule
* @return pair of module (1 for MUX/ADD, 2 for DEMUX/DROP) and connection number
*/
- private Pair<Short, Short> setModuleConnection(CrossConnectFlowRule xc, Integer id) {
+ private Pair<Short, Short> setModuleConnection(LumentumFlowRule xc, Integer id) {
if (xc.isAddRule()) {
return Pair.of((short) 1, id.shortValue());
} else {
@@ -341,12 +350,12 @@
*
* Connection number is incremental within the class and associated to the rule hash.
*
- * @param xc the cross connect flow rule
+ * @param xc the cross connect flow
* @return pair of module (1 for MUX/ADD, 2 for DEMUX/DROP) and connection number
*/
- private Pair<Short, Short> retrieveModuleConnection(CrossConnectFlowRule xc) {
+ private Pair<Short, Short> retrieveModuleConnection(LumentumFlowRule xc) {
- int hash = Objects.hash(data().deviceId(), xc.selector(), xc.treatment());
+ int hash = Objects.hash(data().deviceId(), xc.selector());
LumentumConnection retrievedConnection = CONNECTION_SET.stream()
.filter(conn -> conn.getHash() == hash)
@@ -372,7 +381,7 @@
}
//Following Lumentum documentation rpc operation to configure a new connection
- private boolean rpcAddConnection(CrossConnectFlowRule xc) {
+ private boolean rpcAddConnection(LumentumFlowRule xc) {
int currentConnectionId = generateConnectionId();
@@ -382,7 +391,7 @@
}
LumentumConnection connection = new LumentumConnection(currentConnectionId,
- Objects.hash(data().deviceId(), xc.selector(), xc.treatment()), xc);
+ Objects.hash(data().deviceId(), xc.selector()), xc);
CONNECTION_SET.add(connection);
@@ -464,7 +473,7 @@
}
//Following Lumentum documentation rpc operation to delete a new connection
- private boolean rpcDeleteConnection(CrossConnectFlowRule xc) {
+ private boolean rpcDeleteConnection(LumentumFlowRule xc) {
Pair<Short, Short> pair = retrieveModuleConnection(xc);
if (pair == null) {
diff --git a/drivers/lumentum/src/main/java/org/onosproject/drivers/lumentum/LumentumPowerConfig.java b/drivers/lumentum/src/main/java/org/onosproject/drivers/lumentum/LumentumPowerConfig.java
index e292947..16000bd 100644
--- a/drivers/lumentum/src/main/java/org/onosproject/drivers/lumentum/LumentumPowerConfig.java
+++ b/drivers/lumentum/src/main/java/org/onosproject/drivers/lumentum/LumentumPowerConfig.java
@@ -102,7 +102,7 @@
//TODO implement actual get configuration from the device
//This is used by ROADM application to retrieve attenuation parameter, with T instanceof OchSignal
private Long acquireTargetPower(PortNumber port, T component) {
- log.info("Lumentum get port {} target power...", port);
+ log.debug("Lumentum get port {} target power...", port);
if (component instanceof OchSignal) {
//FIXME include port in the filter
@@ -112,10 +112,10 @@
.orElse(null);
if (conn == null) {
- log.info("Lumentum NETCONF fail to retrieve attenuation signal {} port {}", component, port);
+ log.debug("Lumentum NETCONF fail to retrieve attenuation signal {} port {}", component, port);
return 0L;
} else {
- log.info("Lumentum NETCONF on port {} attenuation {}", port, conn.attenuation);
+ log.debug("Lumentum NETCONF on port {} attenuation {}", port, conn.attenuation);
return ((long) (conn.attenuation * 100));
}
}
@@ -126,7 +126,7 @@
//TODO implement actual get configuration from the device
//This is used by ROADM application to retrieve attenuation parameter, with T instanceof OchSignal
private Long acquireCurrentPower(PortNumber port, T component) {
- log.info("Lumentum get port {} current power...", port);
+ log.debug("Lumentum get port {} current power...", port);
if (component instanceof OchSignal) {
//FIXME include port in the filter
@@ -136,10 +136,10 @@
.orElse(null);
if (conn == null) {
- log.info("Lumentum NETCONF fail to retrieve power signal {} port {}", component, port);
+ log.debug("Lumentum NETCONF fail to retrieve power signal {} port {}", component, port);
return 0L;
} else {
- log.info("Lumentum NETCONF on port {} power {}", port, conn.inputPower);
+ log.debug("Lumentum NETCONF on port {} power {}", port, conn.inputPower);
return ((long) (conn.inputPower * 100));
}
}