Rimon Ashkenazy
Committed by Gerrit Code Review

Add OTN device and ports

Change-Id: I18f3376d1466077e95d7324a27a660302f0123b3
Showing 21 changed files with 316 additions and 14 deletions
......@@ -28,6 +28,7 @@ import org.onosproject.net.Device;
import org.onosproject.net.OchPort;
import org.onosproject.net.OduCltPort;
import org.onosproject.net.OmsPort;
import org.onosproject.net.OtuPort;
import org.onosproject.net.Port;
import org.onosproject.net.PortNumber;
import org.onosproject.net.device.DeviceService;
......@@ -47,7 +48,7 @@ public class DevicePortsListCommand extends DevicesListCommand {
private static final String FMT = " port=%s, state=%s, type=%s, speed=%s %s";
private static final String FMT_OCH = " port=%s, state=%s, type=%s, signalType=%s, isTunable=%s %s";
private static final String FMT_ODUCLT = " port=%s, state=%s, type=%s, signalType=%s %s";
private static final String FMT_ODUCLT_OTU = " port=%s, state=%s, type=%s, signalType=%s %s";
private static final String FMT_OMS = " port=%s, state=%s, type=%s, Freqs= %s / %s / %s GHz, totalChannels=%s %s";
@Option(name = "-e", aliases = "--enabled", description = "Show only enabled ports",
......@@ -158,7 +159,7 @@ public class DevicePortsListCommand extends DevicesListCommand {
((OchPort) port).isTunable() ? "yes" : "no", annotations);
break;
case ODUCLT:
print(FMT_ODUCLT, portName, portIsEnabled, portType,
print(FMT_ODUCLT_OTU, portName, portIsEnabled, portType,
((OduCltPort) port).signalType().toString(), annotations);
break;
case OMS:
......@@ -168,6 +169,10 @@ public class DevicePortsListCommand extends DevicesListCommand {
((OmsPort) port).grid().asHz() / Frequency.ofGHz(1).asHz(),
((OmsPort) port).totalChannels(), annotations);
break;
case OTU:
print(FMT_ODUCLT_OTU, portName, portIsEnabled, portType,
((OtuPort) port).signalType().toString(), annotations);
break;
default:
print(FMT, portName, portIsEnabled, portType, port.portSpeed(), annotations);
break;
......
/*
* Copyright 2016 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.net;
import java.util.Objects;
import static com.google.common.base.MoreObjects.toStringHelper;
/**
* Implementation of OTU port (Optical channel Transport Unit).
*/
public class OtuPort extends DefaultPort {
private final OtuSignalType signalType;
/**
* Creates an OTU port in the specified network element.
*
* @param element parent network element
* @param number port number
* @param isEnabled port enabled state
* @param signalType OTU signal type
* @param annotations optional key/value annotations
*/
public OtuPort(Element element, PortNumber number, boolean isEnabled,
OtuSignalType signalType, Annotations... annotations) {
super(element, number, isEnabled, Type.OTU, 0, annotations);
this.signalType = signalType;
}
/**
* Returns OTU signal type.
*
* @return OTU signal type
*/
public OtuSignalType signalType() {
return signalType;
}
@Override
public int hashCode() {
return Objects.hash(number(), isEnabled(), type(), signalType, annotations());
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj instanceof OtuPort) {
final OtuPort other = (OtuPort) obj;
return Objects.equals(this.element().id(), other.element().id()) &&
Objects.equals(this.number(), other.number()) &&
Objects.equals(this.isEnabled(), other.isEnabled()) &&
Objects.equals(this.signalType, other.signalType) &&
Objects.equals(this.annotations(), other.annotations());
}
return false;
}
@Override
public String toString() {
return toStringHelper(this)
.add("element", element().id())
.add("number", number())
.add("isEnabled", isEnabled())
.add("type", type())
.add("signalType", signalType)
.toString();
}
}
\ No newline at end of file
/*
* Copyright 2016 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.net;
/**
* Represents OTU (Optical channel Transport Unit) signal type.
*
* <p>
* See ITU G.709 "Interfaces for the Optical Transport Network (OTN)" and
* Open Networking Foundation "Optical Transport Protocol Extensions Version 1.0".
* </p>
*/
public enum OtuSignalType {
OTU1,
OTU2,
OTU3,
OTU4
}
\ No newline at end of file
......@@ -58,7 +58,12 @@ public interface Port extends Annotated {
/**
* Signifies virtual port.
*/
VIRTUAL
VIRTUAL,
/**
* Signifies optical fiber-based OTN port.
*/
OTU
}
/**
......
/*
* Copyright 2016 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.net.device;
import com.google.common.base.MoreObjects;
import org.onosproject.net.OtuSignalType;
import org.onosproject.net.Port;
import org.onosproject.net.PortNumber;
import org.onosproject.net.SparseAnnotations;
/**
* Default implementation of immutable OTU port description.
*/
public class OtuPortDescription extends DefaultPortDescription {
private final OtuSignalType signalType;
/**
* Creates OTU port description based on the supplied information.
*
* @param number port number
* @param isEnabled port enabled state
* @param signalType OTU signal type
* @param annotations optional key/value annotations map
*/
public OtuPortDescription(PortNumber number, boolean isEnabled, OtuSignalType signalType,
SparseAnnotations... annotations) {
super(number, isEnabled, Port.Type.OTU, 0, annotations);
this.signalType = signalType;
}
/**
* Creates OTU port description based on the supplied information.
*
* @param base PortDescription to get basic information from
* @param signalType OTU signal type
* @param annotations optional key/value annotations map
*/
public OtuPortDescription(PortDescription base, OtuSignalType signalType,
SparseAnnotations annotations) {
super(base, annotations);
this.signalType = signalType;
}
/**
* Returns OTU signal type.
*
* @return OTU signal type
*/
public OtuSignalType signalType() {
return signalType;
}
@Override
public String toString() {
return MoreObjects.toStringHelper(getClass())
.add("number", portNumber())
.add("isEnabled", isEnabled())
.add("type", type())
.add("signalType", signalType)
.toString();
}
}
\ No newline at end of file
......@@ -352,7 +352,8 @@ public class DeviceManager
final Device device = getDevice(deviceId);
List<PortDescription> descs = ports.stream().map(
port -> (!(Device.Type.ROADM.equals(device.type()))) ?
port -> (!(Device.Type.ROADM.equals(device.type()) ||
(Device.Type.OTN.equals(device.type())))) ?
new DefaultPortDescription(port.number(), false,
port.type(), port.portSpeed()) :
OpticalPortOperator.descriptionOf(port, false)
......@@ -439,7 +440,8 @@ public class DeviceManager
return;
}
Device device = nullIsNotFound(getDevice(deviceId), "Device not found");
if ((Device.Type.ROADM.equals(device.type()))) {
if ((Device.Type.ROADM.equals(device.type())) ||
(Device.Type.OTN.equals(device.type()))) {
Port port = getPort(deviceId, portDescription.portNumber());
portDescription = OpticalPortOperator.descriptionOf(port, portDescription.isEnabled());
}
......
......@@ -23,6 +23,7 @@ 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.OtuPort;
import org.onosproject.net.OduCltPort;
import org.onosproject.net.OmsPort;
import org.onosproject.net.Port;
......@@ -32,6 +33,7 @@ import org.onosproject.net.device.DefaultPortDescription;
import org.onosproject.net.device.OchPortDescription;
import org.onosproject.net.device.OduCltPortDescription;
import org.onosproject.net.device.OmsPortDescription;
import org.onosproject.net.device.OtuPortDescription;
import org.onosproject.net.device.PortDescription;
import org.slf4j.Logger;
......@@ -115,6 +117,9 @@ public final class OpticalPortOperator implements ConfigOperator {
case COPPER:
return new DefaultPortDescription(port, descr.isEnabled(), descr.type(),
descr.portSpeed(), sa);
case OTU:
OtuPortDescription otu = (OtuPortDescription) descr;
return new OtuPortDescription(port, otu.isEnabled(), otu.signalType(), sa);
default:
log.warn("Unsupported optical port type {} - can't update", descr.type());
return descr;
......@@ -183,6 +188,9 @@ public final class OpticalPortOperator implements ConfigOperator {
case ODUCLT:
OduCltPort odu = (OduCltPort) port;
return new OduCltPortDescription(ptn, isup, odu.signalType(), an);
case OTU:
OtuPort otu = (OtuPort) port;
return new OtuPortDescription(ptn, isup, otu.signalType(), an);
default:
return new DefaultPortDescription(ptn, isup, port.type(), port.portSpeed(), an);
}
......
......@@ -34,11 +34,13 @@ import java.net.URI;
import static org.junit.Assert.assertEquals;
import static org.onosproject.net.Device.Type.ROADM;
import static org.onosproject.net.Device.Type.SWITCH;
import static org.onosproject.net.Device.Type.OTN;
public class BasicDeviceOperatorTest {
private static final String NAME1 = "of:foo";
private static final String NAME2 = "of:bar";
private static final String NAME3 = "of:otn";
private static final String OWNER = "somebody";
private static final URI DURI = URI.create(NAME1);
private static final String MFR = "whitebox";
......@@ -64,6 +66,7 @@ public class BasicDeviceOperatorTest {
private static final BasicDeviceConfig SW_BDC = new BasicDeviceConfig();
private static final BasicDeviceConfig RD_BDC = new BasicDeviceConfig();
private static final BasicDeviceConfig OT_BDC = new BasicDeviceConfig();
@Before
public void setUp() {
......@@ -72,6 +75,8 @@ public class BasicDeviceOperatorTest {
RD_BDC.init(DeviceId.deviceId(NAME2), NAME2, JsonNodeFactory.instance.objectNode(), mapper, delegate);
RD_BDC.type(ROADM).manufacturer(MANUFACTURER).hwVersion(HW_VERSION)
.swVersion(SW_VERSION).serial(SERIAL).managementAddress(MANAGEMENT_ADDRESS).driver(DRIVER).owner(OWNER);
OT_BDC.init(DeviceId.deviceId(NAME3), NAME3, JsonNodeFactory.instance.objectNode(), mapper, delegate);
OT_BDC.type(OTN);
}
@Test
......@@ -92,5 +97,9 @@ public class BasicDeviceOperatorTest {
assertEquals("Wrong serial", SERIAL, desc.serialNumber());
assertEquals("Wrong management Address", MANAGEMENT_ADDRESS,
desc.annotations().value(AnnotationKeys.MANAGEMENT_ADDRESS));
// override Device type
desc = BasicDeviceOperator.combine(OT_BDC, DEV1);
assertEquals(OTN, desc.type());
}
}
......
......@@ -31,6 +31,7 @@ import org.onosproject.net.device.DeviceDescription;
import org.onosproject.net.device.OchPortDescription;
import org.onosproject.net.device.OduCltPortDescription;
import org.onosproject.net.device.OmsPortDescription;
import org.onosproject.net.device.OtuPortDescription;
import org.onosproject.net.device.PortDescription;
import org.onosproject.store.Timestamp;
import org.onosproject.store.impl.Timestamped;
......@@ -123,6 +124,13 @@ class DeviceDescriptions {
ocDesc, ocDesc.signalType(), merged),
newDesc.timestamp());
break;
case OTU:
OtuPortDescription otuDesc = (OtuPortDescription) (newDesc.value());
newOne = new Timestamped<>(
new OtuPortDescription(
otuDesc, otuDesc.signalType(), merged),
newDesc.timestamp());
break;
default:
newOne = new Timestamped<>(
new DefaultPortDescription(newDesc.value(), merged),
......
......@@ -48,6 +48,7 @@ import org.onosproject.net.MastershipRole;
import org.onosproject.net.OchPort;
import org.onosproject.net.OduCltPort;
import org.onosproject.net.OmsPort;
import org.onosproject.net.OtuPort;
import org.onosproject.net.Port;
import org.onosproject.net.PortNumber;
import org.onosproject.net.device.DefaultPortStatistics;
......@@ -59,6 +60,7 @@ import org.onosproject.net.device.DeviceStoreDelegate;
import org.onosproject.net.device.OchPortDescription;
import org.onosproject.net.device.OduCltPortDescription;
import org.onosproject.net.device.OmsPortDescription;
import org.onosproject.net.device.OtuPortDescription;
import org.onosproject.net.device.PortDescription;
import org.onosproject.net.device.PortStatistics;
import org.onosproject.net.provider.ProviderId;
......@@ -1095,6 +1097,9 @@ public class GossipDeviceStore
case ODUCLT:
OduCltPortDescription oduDesc = (OduCltPortDescription) description;
return new OduCltPort(device, number, isEnabled, oduDesc.signalType(), annotations);
case OTU:
OtuPortDescription otuDesc = (OtuPortDescription) description;
return new OtuPort(device, number, isEnabled, otuDesc.signalType(), annotations);
default:
return new DefaultPort(device, number, isEnabled, description.type(),
description.portSpeed(), annotations);
......
......@@ -77,6 +77,8 @@ import org.onosproject.net.OduCltPort;
import org.onosproject.net.OduSignalId;
import org.onosproject.net.OduSignalType;
import org.onosproject.net.OmsPort;
import org.onosproject.net.OtuPort;
import org.onosproject.net.OtuSignalType;
import org.onosproject.net.Port;
import org.onosproject.net.PortNumber;
import org.onosproject.net.TributarySlot;
......@@ -85,6 +87,7 @@ import org.onosproject.net.device.DefaultPortDescription;
import org.onosproject.net.device.DefaultPortStatistics;
import org.onosproject.net.device.OchPortDescription;
import org.onosproject.net.device.OduCltPortDescription;
import org.onosproject.net.device.OtuPortDescription;
import org.onosproject.net.device.OmsPortDescription;
import org.onosproject.net.device.PortStatistics;
import org.onosproject.net.flow.CompletedBatchOperation;
......@@ -511,6 +514,9 @@ public final class KryoNamespaces {
.register(OchPortDescription.class)
.register(OmsPortDescription.class)
.register(TributarySlot.class)
.register(OtuPort.class)
.register(OtuSignalType.class)
.register(OtuPortDescription.class)
.register(
MplsIntent.class,
MplsPathIntent.class,
......
......@@ -52,6 +52,8 @@ import org.onosproject.net.OchPort;
import org.onosproject.net.OchSignal;
import org.onosproject.net.OduCltPort;
import org.onosproject.net.OmsPort;
import org.onosproject.net.OtuPort;
import org.onosproject.net.OtuSignalType;
import org.onosproject.net.PortNumber;
import org.onosproject.net.OduSignalType;
import org.onosproject.net.SparseAnnotations;
......@@ -225,6 +227,11 @@ public class KryoSerializerTest {
}
@Test
public void testOtuPort() {
testSerializedEquals(new OtuPort(DEV1, P1, true, OtuSignalType.OTU2));
testSerializedEquals(new OtuPort(DEV1, P1, true, OtuSignalType.OTU2, A1_2));
}
@Test
public void testDeviceId() {
testSerializedEquals(DID1);
}
......
......@@ -186,7 +186,7 @@ public class LldpLinkProvider extends AbstractProvider implements LinkProvider {
private ApplicationId appId;
static final SuppressionRules DEFAULT_RULES
= new SuppressionRules(EnumSet.of(Device.Type.ROADM, Device.Type.FIBER_SWITCH),
= new SuppressionRules(EnumSet.of(Device.Type.ROADM, Device.Type.FIBER_SWITCH, Device.Type.OTN),
ImmutableMap.of(NO_LLDP, SuppressionRules.ANY_VALUE));
private SuppressionRules rules = LldpLinkProvider.DEFAULT_RULES;
......
......@@ -51,7 +51,7 @@ public class SuppressionRulesTest {
@Before
public void setUp() throws Exception {
rules = new SuppressionRules(ImmutableSet.of(Device.Type.ROADM),
rules = new SuppressionRules(ImmutableSet.of(Device.Type.ROADM, Device.Type.OTN),
ImmutableMap.of("no-lldp", SuppressionRules.ANY_VALUE,
"sendLLDP", "false"));
}
......
......@@ -54,6 +54,7 @@ import org.onosproject.net.GridType;
import org.onosproject.net.MastershipRole;
import org.onosproject.net.OchSignal;
import org.onosproject.net.OduSignalType;
import org.onosproject.net.OtuSignalType;
import org.onosproject.net.Port;
import org.onosproject.net.PortNumber;
import org.onosproject.net.SparseAnnotations;
......@@ -67,6 +68,7 @@ import org.onosproject.net.device.DeviceProviderService;
import org.onosproject.net.device.OchPortDescription;
import org.onosproject.net.device.OduCltPortDescription;
import org.onosproject.net.device.OmsPortDescription;
import org.onosproject.net.device.OtuPortDescription;
import org.onosproject.net.device.PortDescription;
import org.onosproject.net.device.PortStatistics;
import org.onosproject.net.provider.AbstractProvider;
......@@ -492,13 +494,15 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr
*/
private List<PortDescription> buildPortDescriptions(OpenFlowSwitch sw) {
final List<PortDescription> portDescs = new ArrayList<>(sw.getPorts().size());
if (!(Device.Type.ROADM.equals(sw.deviceType()))) {
if (!((Device.Type.ROADM.equals(sw.deviceType())) ||
(Device.Type.OTN.equals(sw.deviceType())))) {
sw.getPorts().forEach(port -> portDescs.add(buildPortDescription(port)));
}
OpenFlowOpticalSwitch opsw;
switch (sw.deviceType()) {
case ROADM:
case OTN:
opsw = (OpenFlowOpticalSwitch) sw;
List<OFPortDesc> ports = opsw.getPorts();
LOG.debug("SW ID {} , ETH- ODU CLT Ports {}", opsw.getId(), ports);
......@@ -578,6 +582,24 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr
return buildPortDescription(ptype, (OFExpPort) port);
}
private boolean matchingOtuPortSignalTypes(OFPortOpticalTransportSignalType sigType,
OduSignalType oduSignalType) {
switch (sigType) {
case OTU2:
if (oduSignalType == OduSignalType.ODU2) {
return true;
}
break;
case OTU4:
if (oduSignalType == OduSignalType.ODU4) {
return true;
}
break;
default:
break;
}
return false;
}
/**
* Build a portDescription from a given a port description describing some
* Optical port.
......@@ -622,8 +644,25 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr
break;
case OTU2:
case OTU4:
LOG.error("Signal tpye OTU2/4 not supported yet ", port.toString());
break;
entry = firstProp.getFeatures().get(0).getValue().get(0);
layerClass = entry.getLayerClass();
if (!OFPortOpticalTransportLayerClass.ODU.equals(layerClass)) {
LOG.error("Unsupported layer Class {} ", layerClass);
return null;
}
// convert to ONOS OduSignalType
OduSignalType oduSignalTypeOtuPort = OpenFlowDeviceValueMapper.
lookupOduSignalType((byte) entry.getSignalType());
if (!matchingOtuPortSignalTypes(sigType, oduSignalTypeOtuPort)) {
LOG.error("Wrong oduSignalType {} for OTU Port sigType {} ", oduSignalTypeOtuPort, sigType);
return null;
}
OtuSignalType otuSignalType =
((sigType == OFPortOpticalTransportSignalType.OTU2) ? OtuSignalType.OTU2 :
OtuSignalType.OTU4);
portDes = new OtuPortDescription(portNo, enabled, otuSignalType, annotations);
break;
default:
break;
}
......
......@@ -611,12 +611,14 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase {
private void sendAllDevices() {
// Send optical first, others later for layered rendering
for (Device device : deviceService.getDevices()) {
if (device.type() == Device.Type.ROADM) {
if ((device.type() == Device.Type.ROADM) ||
(device.type() == Device.Type.OTN)) {
sendMessage(deviceMessage(new DeviceEvent(DEVICE_ADDED, device)));
}
}
for (Device device : deviceService.getDevices()) {
if (device.type() != Device.Type.ROADM) {
if ((device.type() != Device.Type.ROADM) &&
(device.type() != Device.Type.OTN)) {
sendMessage(deviceMessage(new DeviceEvent(DEVICE_ADDED, device)));
}
}
......
......@@ -131,6 +131,7 @@
icon(grp, 'router', [250, 0]);
icon(grp, 'bgpSpeaker', [300, 0]);
icon(grp, 'uiAttached', [350, 0]);
icon(grp, 'otn', [400, 0]);
icon(grp, 'chain', [ 0, 60]);
icon(grp, 'crown', [ 50, 60]);
......
......@@ -88,6 +88,11 @@
"M52,40l-12,0,0-8-18,13,18,13,0-8,12,0zM52,74l-12,0,0-8-18,13," +
"18,13,0-8,12,0z",
otn: "M10,35l25-25h40l25,25v40l-25,25h-40l-25-25zM58,26l12,0,0" +
"-8,18,13-18,13,0-8-12,0zM58,60l12,0,0-8,18,13-18,13,0-8-12,0z" +
"M52,40l-12,0,0-8-18,13,18,13,0-8,12,0zM52,74l-12,0,0-8-18,13," +
"18,13,0-8,12,0z",
endstation: "M10,15a5,5,0,0,1,5-5h65a5,5,0,0,1,5,5v80a5,5,0,0,1" +
"-5,5h-65a5,5,0,0,1-5-5zM87.5,14l11,11a3,10,0,0,1,2,10v40a3,10," +
"0,0,1,-2,10l-11,11zM17,19a2,2,0,0,1,2-2h56a2,2,0,0,1,2,2v26a2," +
......
......@@ -49,6 +49,7 @@
devIcon_SWITCH: 'switch',
devIcon_ROADM: 'roadm',
devIcon_OTN: 'otn',
deviceTable: 'switch',
flowTable: 'flowTable',
portTable: 'portTable',
......
......@@ -44,7 +44,8 @@
},
device: {
switch: 'pkt',
roadm: 'opt'
roadm: 'opt',
otn: 'opt'
},
link: {
hostLink: 'pkt',
......
......@@ -223,7 +223,8 @@
var isDevice = {
switch: 1,
roadm: 1
roadm: 1,
otn:1
};
function displaySingle(data) {
......