Yafit Hadar
Committed by Gerrit Code Review

[Emu] Open Flow Optical Port Description

Change-Id: I8da4d7a1e1dea18d56cba9673f70b1ec69a5adcf
1 /* 1 /*
2 - * Copyright 2014 Open Networking Laboratory 2 + * Copyright 2015 Open Networking Laboratory
3 * 3 *
4 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License. 5 * you may not use this file except in compliance with the License.
...@@ -22,8 +22,12 @@ import com.fasterxml.jackson.databind.node.ObjectNode; ...@@ -22,8 +22,12 @@ import com.fasterxml.jackson.databind.node.ObjectNode;
22 import org.apache.karaf.shell.commands.Argument; 22 import org.apache.karaf.shell.commands.Argument;
23 import org.apache.karaf.shell.commands.Command; 23 import org.apache.karaf.shell.commands.Command;
24 import org.apache.karaf.shell.commands.Option; 24 import org.apache.karaf.shell.commands.Option;
25 +import org.onlab.util.Frequency;
25 import org.onosproject.cli.Comparators; 26 import org.onosproject.cli.Comparators;
26 import org.onosproject.net.Device; 27 import org.onosproject.net.Device;
28 +import org.onosproject.net.OchPort;
29 +import org.onosproject.net.OduCltPort;
30 +import org.onosproject.net.OmsPort;
27 import org.onosproject.net.Port; 31 import org.onosproject.net.Port;
28 import org.onosproject.net.PortNumber; 32 import org.onosproject.net.PortNumber;
29 import org.onosproject.net.device.DeviceService; 33 import org.onosproject.net.device.DeviceService;
...@@ -41,7 +45,10 @@ import static org.onosproject.net.DeviceId.deviceId; ...@@ -41,7 +45,10 @@ import static org.onosproject.net.DeviceId.deviceId;
41 description = "Lists all ports or all ports of a device") 45 description = "Lists all ports or all ports of a device")
42 public class DevicePortsListCommand extends DevicesListCommand { 46 public class DevicePortsListCommand extends DevicesListCommand {
43 47
44 - private static final String FMT = " port=%s, state=%s, type=%s, speed=%s%s"; 48 + private static final String FMT = " port=%s, state=%s, type=%s, speed=%s %s";
49 + private static final String FMT_OCH = " port=%s, state=%s, type=%s, signalType=%s, isTunable=%s %s";
50 + private static final String FMT_ODUCLT = " port=%s, state=%s, type=%s, signalType=%s %s";
51 + private static final String FMT_OMS = " port=%s, state=%s, type=%s, Freqs= %s / %s / %s GHz, totalChannels=%s %s";
45 52
46 @Option(name = "-e", aliases = "--enabled", description = "Show only enabled ports", 53 @Option(name = "-e", aliases = "--enabled", description = "Show only enabled ports",
47 required = false, multiValued = false) 54 required = false, multiValued = false)
...@@ -137,13 +144,34 @@ public class DevicePortsListCommand extends DevicesListCommand { ...@@ -137,13 +144,34 @@ public class DevicePortsListCommand extends DevicesListCommand {
137 List<Port> ports = new ArrayList<>(service.getPorts(device.id())); 144 List<Port> ports = new ArrayList<>(service.getPorts(device.id()));
138 Collections.sort(ports, Comparators.PORT_COMPARATOR); 145 Collections.sort(ports, Comparators.PORT_COMPARATOR);
139 for (Port port : ports) { 146 for (Port port : ports) {
140 - if (isIncluded(port)) { 147 + if (!isIncluded(port)) {
141 - print(FMT, portName(port.number()), 148 + continue;
142 - port.isEnabled() ? "enabled" : "disabled", 149 + }
143 - port.type().toString().toLowerCase(), port.portSpeed(), 150 + String portName = portName(port.number());
144 - annotations(port.annotations())); 151 + Object portIsEnabled = port.isEnabled() ? "enabled" : "disabled";
152 + String portType = port.type().toString().toLowerCase();
153 + String annotations = annotations(port.annotations());
154 + switch (port.type()) {
155 + case OCH:
156 + print(FMT_OCH, portName, portIsEnabled, portType,
157 + ((OchPort) port).signalType().toString(),
158 + ((OchPort) port).isTunable() ? "yes" : "no", annotations);
159 + break;
160 + case ODUCLT:
161 + print(FMT_ODUCLT, portName, portIsEnabled, portType,
162 + ((OduCltPort) port).signalType().toString(), annotations);
163 + break;
164 + case OMS:
165 + print(FMT_OMS, portName, portIsEnabled, portType,
166 + ((OmsPort) port).minFrequency().asHz() / Frequency.ofGHz(1).asHz(),
167 + ((OmsPort) port).maxFrequency().asHz() / Frequency.ofGHz(1).asHz(),
168 + ((OmsPort) port).grid().asHz() / Frequency.ofGHz(1).asHz(),
169 + ((OmsPort) port).totalChannels(), annotations);
170 + break;
171 + default:
172 + print(FMT, portName, portIsEnabled, portType, port.portSpeed(), annotations);
173 + break;
145 } 174 }
146 } 175 }
147 } 176 }
148 -
149 } 177 }
......
...@@ -15,8 +15,26 @@ ...@@ -15,8 +15,26 @@
15 */ 15 */
16 package org.onosproject.net.device.impl; 16 package org.onosproject.net.device.impl;
17 17
18 -import com.google.common.collect.Lists; 18 +import static com.google.common.base.Preconditions.checkNotNull;
19 -import com.google.common.util.concurrent.Futures; 19 +import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor;
20 +import static org.onlab.util.Tools.groupedThreads;
21 +import static org.onosproject.net.MastershipRole.MASTER;
22 +import static org.onosproject.net.MastershipRole.NONE;
23 +import static org.onosproject.net.MastershipRole.STANDBY;
24 +import static org.onosproject.security.AppGuard.checkPermission;
25 +import static org.onosproject.security.AppPermission.Type.DEVICE_READ;
26 +import static org.slf4j.LoggerFactory.getLogger;
27 +
28 +import java.util.Collection;
29 +import java.util.HashSet;
30 +import java.util.List;
31 +import java.util.Objects;
32 +import java.util.Set;
33 +import java.util.concurrent.CompletableFuture;
34 +import java.util.concurrent.ExecutionException;
35 +import java.util.concurrent.ScheduledExecutorService;
36 +import java.util.concurrent.TimeUnit;
37 +import java.util.stream.Collectors;
20 38
21 import org.apache.felix.scr.annotations.Activate; 39 import org.apache.felix.scr.annotations.Activate;
22 import org.apache.felix.scr.annotations.Component; 40 import org.apache.felix.scr.annotations.Component;
...@@ -26,12 +44,6 @@ import org.apache.felix.scr.annotations.ReferenceCardinality; ...@@ -26,12 +44,6 @@ import org.apache.felix.scr.annotations.ReferenceCardinality;
26 import org.apache.felix.scr.annotations.Service; 44 import org.apache.felix.scr.annotations.Service;
27 import org.onosproject.cluster.ClusterService; 45 import org.onosproject.cluster.ClusterService;
28 import org.onosproject.cluster.NodeId; 46 import org.onosproject.cluster.NodeId;
29 -import org.onosproject.net.provider.AbstractListenerProviderRegistry;
30 -import org.onosproject.net.config.NetworkConfigEvent;
31 -import org.onosproject.net.config.NetworkConfigListener;
32 -import org.onosproject.net.config.NetworkConfigService;
33 -import org.onosproject.net.config.basics.BasicDeviceConfig;
34 -import org.onosproject.net.config.basics.OpticalPortConfig;
35 import org.onosproject.mastership.MastershipEvent; 47 import org.onosproject.mastership.MastershipEvent;
36 import org.onosproject.mastership.MastershipListener; 48 import org.onosproject.mastership.MastershipListener;
37 import org.onosproject.mastership.MastershipService; 49 import org.onosproject.mastership.MastershipService;
...@@ -44,6 +56,11 @@ import org.onosproject.net.DeviceId; ...@@ -44,6 +56,11 @@ import org.onosproject.net.DeviceId;
44 import org.onosproject.net.MastershipRole; 56 import org.onosproject.net.MastershipRole;
45 import org.onosproject.net.Port; 57 import org.onosproject.net.Port;
46 import org.onosproject.net.PortNumber; 58 import org.onosproject.net.PortNumber;
59 +import org.onosproject.net.config.NetworkConfigEvent;
60 +import org.onosproject.net.config.NetworkConfigListener;
61 +import org.onosproject.net.config.NetworkConfigService;
62 +import org.onosproject.net.config.basics.BasicDeviceConfig;
63 +import org.onosproject.net.config.basics.OpticalPortConfig;
47 import org.onosproject.net.device.DefaultDeviceDescription; 64 import org.onosproject.net.device.DefaultDeviceDescription;
48 import org.onosproject.net.device.DefaultPortDescription; 65 import org.onosproject.net.device.DefaultPortDescription;
49 import org.onosproject.net.device.DeviceAdminService; 66 import org.onosproject.net.device.DeviceAdminService;
...@@ -58,27 +75,11 @@ import org.onosproject.net.device.DeviceStore; ...@@ -58,27 +75,11 @@ import org.onosproject.net.device.DeviceStore;
58 import org.onosproject.net.device.DeviceStoreDelegate; 75 import org.onosproject.net.device.DeviceStoreDelegate;
59 import org.onosproject.net.device.PortDescription; 76 import org.onosproject.net.device.PortDescription;
60 import org.onosproject.net.device.PortStatistics; 77 import org.onosproject.net.device.PortStatistics;
78 +import org.onosproject.net.provider.AbstractListenerProviderRegistry;
61 import org.onosproject.net.provider.AbstractProviderService; 79 import org.onosproject.net.provider.AbstractProviderService;
62 import org.slf4j.Logger; 80 import org.slf4j.Logger;
63 81
64 -import java.util.Collection; 82 +import com.google.common.util.concurrent.Futures;
65 -import java.util.HashSet;
66 -import java.util.List;
67 -import java.util.Objects;
68 -import java.util.Set;
69 -import java.util.stream.Collectors;
70 -import java.util.concurrent.CompletableFuture;
71 -import java.util.concurrent.ExecutionException;
72 -import java.util.concurrent.ScheduledExecutorService;
73 -import java.util.concurrent.TimeUnit;
74 -
75 -import static com.google.common.base.Preconditions.checkNotNull;
76 -import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor;
77 -import static org.onlab.util.Tools.groupedThreads;
78 -import static org.onosproject.net.MastershipRole.*;
79 -import static org.onosproject.security.AppGuard.checkPermission;
80 -import static org.slf4j.LoggerFactory.getLogger;
81 -import static org.onosproject.security.AppPermission.Type.*;
82 83
83 /** 84 /**
84 * Provides implementation of the device SB &amp; NB APIs. 85 * Provides implementation of the device SB &amp; NB APIs.
...@@ -347,11 +348,15 @@ public class DeviceManager ...@@ -347,11 +348,15 @@ public class DeviceManager
347 log.info("Device {} disconnected from this node", deviceId); 348 log.info("Device {} disconnected from this node", deviceId);
348 349
349 List<Port> ports = store.getPorts(deviceId); 350 List<Port> ports = store.getPorts(deviceId);
350 - List<PortDescription> descs = Lists.newArrayList(); 351 + final Device device = getDevice(deviceId);
351 - ports.forEach(port -> 352 +
352 - descs.add(new DefaultPortDescription(port.number(), 353 + List<PortDescription> descs = ports.stream().map(
353 - false, port.type(), 354 + port -> (!(Device.Type.ROADM.equals(device.type()))) ?
354 - port.portSpeed()))); 355 + new DefaultPortDescription(port.number(), false,
356 + port.type(), port.portSpeed()) :
357 + OpticalPortOperator.descriptionOf(port, false)
358 + ).collect(Collectors.toList());
359 +
355 store.updatePorts(this.provider().id(), deviceId, descs); 360 store.updatePorts(this.provider().id(), deviceId, descs);
356 try { 361 try {
357 if (mastershipService.isLocalMaster(deviceId)) { 362 if (mastershipService.isLocalMaster(deviceId)) {
...@@ -430,6 +435,12 @@ public class DeviceManager ...@@ -430,6 +435,12 @@ public class DeviceManager
430 portDescription); 435 portDescription);
431 return; 436 return;
432 } 437 }
438 + final Device device = getDevice(deviceId);
439 + if ((Device.Type.ROADM.equals(device.type()))) {
440 + Port port = getPort(deviceId, portDescription.portNumber());
441 + portDescription = OpticalPortOperator.descriptionOf(port, portDescription.isEnabled());
442 + }
443 +
433 portDescription = consolidate(deviceId, portDescription); 444 portDescription = consolidate(deviceId, portDescription);
434 final DeviceEvent event = store.updatePortStatus(this.provider().id(), 445 final DeviceEvent event = store.updatePortStatus(this.provider().id(),
435 deviceId, portDescription); 446 deviceId, portDescription);
......
...@@ -151,8 +151,25 @@ public final class OpticalPortOperator implements ConfigOperator { ...@@ -151,8 +151,25 @@ public final class OpticalPortOperator implements ConfigOperator {
151 */ 151 */
152 public static PortDescription descriptionOf(Port port) { 152 public static PortDescription descriptionOf(Port port) {
153 checkNotNull(port, "Must supply non-null Port"); 153 checkNotNull(port, "Must supply non-null Port");
154 + final boolean isUp = port.isEnabled();
155 + return descriptionOfPort(port, isUp);
156 + }
157 +
158 + /**
159 + * Returns a description built from an existing port and reported status.
160 + *
161 + * @param port
162 + * @param isEnabled
163 + * @return a PortDescription based on the port
164 + */
165 + static PortDescription descriptionOf(Port port, boolean isEnabled) {
166 + checkNotNull(port, "Must supply non-null Port");
167 + final boolean isup = isEnabled;
168 + return descriptionOfPort(port, isup);
169 + }
170 +
171 + private static PortDescription descriptionOfPort(Port port, final boolean isup) {
154 final PortNumber ptn = port.number(); 172 final PortNumber ptn = port.number();
155 - final boolean isup = port.isEnabled();
156 final SparseAnnotations an = (SparseAnnotations) port.annotations(); 173 final SparseAnnotations an = (SparseAnnotations) port.annotations();
157 switch (port.type()) { 174 switch (port.type()) {
158 case OMS: 175 case OMS:
......
1 +/*
2 + * Copyright 2015 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +package org.onosproject.driver.handshaker;
17 +
18 +import org.projectfloodlight.openflow.protocol.OFExpPort;
19 +import org.projectfloodlight.openflow.protocol.OFExpPortDescReply;
20 +import org.projectfloodlight.openflow.protocol.OFExpPortDescRequest;
21 +import org.projectfloodlight.openflow.protocol.OFMessage;
22 +import org.projectfloodlight.openflow.protocol.OFPortDesc;
23 +import org.projectfloodlight.openflow.protocol.OFStatsReply;
24 +import org.projectfloodlight.openflow.protocol.OFStatsReplyFlags;
25 +import org.projectfloodlight.openflow.protocol.OFStatsType;
26 +
27 +import java.io.IOException;
28 +import java.util.ArrayList;
29 +import java.util.List;
30 +import java.util.Set;
31 +import java.util.concurrent.atomic.AtomicBoolean;
32 +import java.util.stream.Collectors;
33 +
34 +import org.onosproject.net.Device;
35 +import org.onosproject.openflow.controller.OpenFlowOpticalSwitch;
36 +import org.onosproject.openflow.controller.PortDescPropertyType;
37 +import org.onosproject.openflow.controller.driver.AbstractOpenFlowSwitch;
38 +import org.onosproject.openflow.controller.driver.SwitchDriverSubHandshakeAlreadyStarted;
39 +import org.onosproject.openflow.controller.driver.SwitchDriverSubHandshakeCompleted;
40 +import org.onosproject.openflow.controller.driver.SwitchDriverSubHandshakeNotStarted;
41 +import org.projectfloodlight.openflow.protocol.OFObject;
42 +
43 +import com.google.common.collect.ImmutableList;
44 +import com.google.common.collect.ImmutableSet;
45 +
46 +
47 +/**
48 + * Open Flow Optical Switch handshaker - for Open Flow 13.
49 + */
50 +public class OFOpticalSwitch13 extends AbstractOpenFlowSwitch implements OpenFlowOpticalSwitch {
51 +
52 + private final AtomicBoolean driverHandshakeComplete = new AtomicBoolean(false);
53 + private List<OFExpPort> expPortDes = new ArrayList<>();
54 +
55 + @Override
56 + public Boolean supportNxRole() {
57 + return false;
58 + }
59 +
60 + @Override
61 + public void startDriverHandshake() {
62 + log.info("Starting driver handshake for sw {}", getStringId());
63 + if (startDriverHandshakeCalled) {
64 + throw new SwitchDriverSubHandshakeAlreadyStarted();
65 + }
66 + startDriverHandshakeCalled = true;
67 +
68 + log.debug("sendHandshakeOFExperimenterPortDescRequest for sw {}", getStringId());
69 +
70 + try {
71 + sendHandshakeOFExperimenterPortDescRequest();
72 + } catch (IOException e) {
73 + log.error("Failed to send handshaker message OFExperimenterPortDescRequestfor sw {}, {}",
74 + getStringId(), e.getMessage());
75 + e.printStackTrace();
76 + }
77 + }
78 +
79 + @Override
80 + public void processDriverHandshakeMessage(OFMessage m) {
81 + if (!startDriverHandshakeCalled) {
82 + throw new SwitchDriverSubHandshakeNotStarted();
83 + }
84 + if (driverHandshakeComplete.get()) {
85 + throw new SwitchDriverSubHandshakeCompleted(m);
86 + }
87 +
88 + log.debug("processDriverHandshakeMessage for sw {}", getStringId());
89 +
90 + switch (m.getType()) {
91 + case STATS_REPLY: // multipart message is reported as STAT
92 + processOFMultipartReply((OFStatsReply) m);
93 + break;
94 + default:
95 + log.warn("Received message {} during switch-driver " +
96 + "subhandshake " + "from switch {} ... " +
97 + "Ignoring message", m,
98 + getStringId());
99 + }
100 + }
101 +
102 + private void processOFMultipartReply(OFStatsReply stats) {
103 + log.debug("Received message {} during switch-driver " +
104 + "subhandshake " + "from switch {} ... " +
105 + stats,
106 + getStringId());
107 +
108 + if (stats.getStatsType() == OFStatsType.EXPERIMENTER) {
109 + try {
110 + OFExpPortDescReply expPortDescReply = (OFExpPortDescReply) stats;
111 + expPortDes.addAll(expPortDescReply.getEntries());
112 + if (!expPortDescReply.getFlags().contains(OFStatsReplyFlags.REPLY_MORE)) {
113 + driverHandshakeComplete.set(true);
114 + return;
115 + }
116 + } catch (ClassCastException e) {
117 + log.error("Unexspected Experimenter Multipart message type {} "
118 + , stats.getClass().getName());
119 + }
120 + }
121 + }
122 +
123 +
124 + @Override
125 + public boolean isDriverHandshakeComplete() {
126 + return driverHandshakeComplete.get();
127 + }
128 +
129 + private void sendHandshakeOFExperimenterPortDescRequest() throws
130 + IOException {
131 +
132 + OFExpPortDescRequest preq = factory()
133 + .buildExpPortDescRequest()
134 + .setXid(getNextTransactionId())
135 + .build();
136 +
137 + log.debug("Sending experimented port description " +
138 + "message " +
139 + "{}",
140 + preq.toString());
141 +
142 + this.sendHandshakeMessage(preq);
143 + }
144 +
145 + @Override
146 + public Device.Type deviceType() {
147 + return Device.Type.ROADM;
148 + }
149 +
150 + /*
151 + * OduClt ports are reported as regular ETH ports.
152 + */
153 + @Override
154 + public List<OFPortDesc> getPorts() {
155 + return ImmutableList.copyOf(
156 + ports.stream().flatMap(p -> p.getEntries().stream())
157 + .collect(Collectors.toList()));
158 + }
159 +
160 + @Override
161 + public List<? extends OFObject> getPortsOf(PortDescPropertyType type) {
162 + return ImmutableList.copyOf(expPortDes);
163 + }
164 +
165 + @Override
166 + public Set<PortDescPropertyType> getPortTypes() {
167 + return ImmutableSet.of(PortDescPropertyType.OPTICAL_TRANSPORT);
168 + }
169 +
170 +}
...@@ -120,5 +120,10 @@ ...@@ -120,5 +120,10 @@
120 <behaviour api="org.onosproject.net.behaviour.Pipeliner" 120 <behaviour api="org.onosproject.net.behaviour.Pipeliner"
121 impl="org.onosproject.driver.pipeline.OpenVSwitchPipeline"/> 121 impl="org.onosproject.driver.pipeline.OpenVSwitchPipeline"/>
122 </driver> 122 </driver>
123 + <driver name="eci" extends="default"
124 + manufacturer="ECI Telecom" hwVersion="optical" swVersion="V_1_0">
125 + <behaviour api="org.onosproject.openflow.controller.driver.OpenFlowSwitchDriver"
126 + impl="org.onosproject.driver.handshaker.OFOpticalSwitch13"/>
127 + </driver>
123 </drivers> 128 </drivers>
124 129
......
1 +/*
2 + * Copyright 2015 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +package org.onosproject.provider.of.device.impl;
17 +
18 +import org.onosproject.net.OduSignalType;
19 +
20 +import com.google.common.collect.BiMap;
21 +import com.google.common.collect.EnumHashBiMap;
22 +
23 +/**
24 + * Collection of helper methods to convert protocol agnostic models to values used in OpenFlow spec.
25 + */
26 +final class OpenFlowDeviceValueMapper {
27 +
28 + // prohibit instantiation
29 + private OpenFlowDeviceValueMapper() {}
30 +
31 + private static final BiMap<OduSignalType, Byte> ODU_SIGNAL_TYPES = EnumHashBiMap.create(OduSignalType.class);
32 + static {
33 + // See ONF "Optical Transport Protocol Extensions Version 1.0" for the following values
34 + ODU_SIGNAL_TYPES.put(OduSignalType.ODU1, (byte) 1); // OFPODUT_ODU1 of enum ofp_odu_signal_type
35 + ODU_SIGNAL_TYPES.put(OduSignalType.ODU2, (byte) 2); // OFPODUT_ODU2 of enum ofp_odu_signal_type
36 + ODU_SIGNAL_TYPES.put(OduSignalType.ODU3, (byte) 3); // OFPODUT_ODU3 of enum ofp_odu_signal_type
37 + ODU_SIGNAL_TYPES.put(OduSignalType.ODU4, (byte) 4); // OFPODUT_ODU4 of enum ofp_odu_signal_type
38 + ODU_SIGNAL_TYPES.put(OduSignalType.ODU0, (byte) 10); // OFPODUT_ODU0 of enum ofp_odu_signal_type
39 + ODU_SIGNAL_TYPES.put(OduSignalType.ODU2e, (byte) 11); // OFPODUT_ODU2E of enum ofp_odu_signal_type
40 + }
41 +
42 + /**
43 + * Looks up the specified input value to the corresponding value with the specified map.
44 + *
45 + * @param map bidirectional mapping
46 + * @param input input value
47 + * @param cls class of output value
48 + * @param <I> type of input value
49 + * @param <O> type of output value
50 + * @return the corresponding value stored in the specified map
51 + */
52 + private static <I, O> O lookup(BiMap<I, O> map, I input, Class<O> cls) {
53 + if (!map.containsKey(input)) {
54 + throw new RuntimeException(
55 + String.format("No mapping found for %s when converting to %s", input, cls.getName()));
56 + }
57 +
58 + return map.get(input);
59 + }
60 +
61 + /**
62 + * Looks up the the corresponding {@link OduSignalType} instance
63 + * from the specified byte value for ODU signal type defined in
64 + * ONF "Optical Transport Protocol Extensions Version 1.0".
65 + *
66 + * @param signalType byte value as ODU (Optical channel Data Unit) signal type defined the spec
67 + * @return the corresponding OchSignalType instance
68 + */
69 + static OduSignalType lookupOduSignalType(byte signalType) {
70 + return lookup(ODU_SIGNAL_TYPES.inverse(), signalType, OduSignalType.class);
71 + }
72 +
73 +}