2 * Copyright © 2021 Nokia. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.transportpce.tapi;
10 import java.nio.charset.Charset;
11 import java.util.ArrayList;
12 import java.util.Collection;
13 import java.util.HashMap;
14 import java.util.List;
16 import java.util.Optional;
17 import java.util.UUID;
18 import java.util.concurrent.ExecutionException;
19 import java.util.stream.Collectors;
20 import java.util.stream.Stream;
21 import org.eclipse.jdt.annotation.Nullable;
22 import org.opendaylight.mdsal.binding.api.DataBroker;
23 import org.opendaylight.mdsal.binding.api.MountPoint;
24 import org.opendaylight.mdsal.binding.api.ReadTransaction;
25 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
26 import org.opendaylight.transportpce.common.Timeouts;
27 import org.opendaylight.transportpce.common.device.DeviceTransactionManager;
28 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev210425.Network;
29 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev210425.cp.to.degree.CpToDegree;
30 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev210425.mapping.Mapping;
31 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev210425.network.Nodes;
32 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev210425.network.NodesKey;
33 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.types.rev170929.Direction;
34 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.org.openroadm.device.container.OrgOpenroadmDevice;
35 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.org.openroadm.device.container.org.openroadm.device.Protocols;
36 import org.opendaylight.yang.gen.v1.http.org.openroadm.lldp.rev161014.Protocols1;
37 import org.opendaylight.yang.gen.v1.http.org.openroadm.lldp.rev161014.lldp.container.lldp.NbrList;
38 import org.opendaylight.yang.gen.v1.http.org.openroadm.lldp.rev161014.lldp.container.lldp.nbr.list.IfName;
39 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.NodeId;
40 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.AdministrativeState;
41 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.CapacityUnit;
42 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.ForwardingDirection;
43 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.LayerProtocolName;
44 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.LifecycleState;
45 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.OperationalState;
46 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.Uuid;
47 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.capacity.TotalSizeBuilder;
48 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.capacity.pac.AvailableCapacityBuilder;
49 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.capacity.pac.TotalPotentialCapacityBuilder;
50 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.global._class.Name;
51 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.global._class.NameBuilder;
52 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.ProtectionType;
53 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.RestorationPolicy;
54 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.link.NodeEdgePoint;
55 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.link.NodeEdgePointBuilder;
56 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.link.NodeEdgePointKey;
57 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.link.ResilienceTypeBuilder;
58 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.risk.parameter.pac.RiskCharacteristic;
59 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.risk.parameter.pac.RiskCharacteristicBuilder;
60 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.Link;
61 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.LinkBuilder;
62 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.LinkKey;
63 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.transfer.cost.pac.CostCharacteristic;
64 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.transfer.cost.pac.CostCharacteristicBuilder;
65 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.transfer.timing.pac.LatencyCharacteristic;
66 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.transfer.timing.pac.LatencyCharacteristicBuilder;
67 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.validation.pac.ValidationMechanism;
68 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.validation.pac.ValidationMechanismBuilder;
69 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
70 import org.opendaylight.yangtools.yang.common.Uint64;
71 import org.slf4j.Logger;
72 import org.slf4j.LoggerFactory;
74 public class R2RTapiLinkDiscovery {
76 private static final Logger LOG = LoggerFactory.getLogger(R2RTapiLinkDiscovery.class);
78 private final DataBroker dataBroker;
79 private final DeviceTransactionManager deviceTransactionManager;
80 private static final String PHTNC_MEDIA = "PHOTONIC_MEDIA";
82 public R2RTapiLinkDiscovery(final DataBroker dataBroker, DeviceTransactionManager deviceTransactionManager) {
83 this.dataBroker = dataBroker;
84 this.deviceTransactionManager = deviceTransactionManager;
87 public Map<LinkKey, Link> readLLDP(NodeId nodeId, int nodeVersion, Uuid tapiTopoUuid) {
88 LOG.info("Tapi R2R Link Node version = {}", nodeVersion);
89 // TODO -> waiting for device 7.1 in network model to change this to a switch statement and include
90 // support for 7.1 devices
91 switch (nodeVersion) {
94 InstanceIdentifier<Protocols> protocols121IID = InstanceIdentifier.create(OrgOpenroadmDevice.class)
95 .child(Protocols.class);
96 Optional<Protocols> protocol121Object = this.deviceTransactionManager.getDataFromDevice(
97 nodeId.getValue(), LogicalDatastoreType.OPERATIONAL, protocols121IID, Timeouts.DEVICE_READ_TIMEOUT,
98 Timeouts.DEVICE_READ_TIMEOUT_UNIT);
99 if (!protocol121Object.isPresent()
100 || (protocol121Object.get().augmentation(Protocols1.class) == null)) {
101 LOG.warn("LLDP subtree is missing : isolated openroadm device");
102 return new HashMap<>();
105 NbrList nbr121List = protocol121Object.get().augmentation(Protocols1.class).getLldp().getNbrList();
106 LOG.info("LLDP subtree is present. Device has {} neighbours", nbr121List.getIfName().size());
107 // try to create rdm2rdm link
108 return rdm2rdmLinkCreatev121(nodeId, tapiTopoUuid, nbr121List);
111 InstanceIdentifier<org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.org.openroadm.device
112 .container.org.openroadm.device.Protocols> protocols221IID =
113 InstanceIdentifier.create(org.opendaylight.yang.gen.v1.http
114 .org.openroadm.device.rev181019.org.openroadm.device.container.OrgOpenroadmDevice.class)
115 .child(org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019
116 .org.openroadm.device.container.org.openroadm.device.Protocols.class);
117 Optional<org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.org.openroadm.device
118 .container.org.openroadm.device.Protocols> protocol221Object = this.deviceTransactionManager
119 .getDataFromDevice(nodeId.getValue(), LogicalDatastoreType.OPERATIONAL, protocols221IID,
120 Timeouts.DEVICE_READ_TIMEOUT, Timeouts.DEVICE_READ_TIMEOUT_UNIT);
121 if (!protocol221Object.isPresent() || (protocol221Object.get().augmentation(
122 org.opendaylight.yang.gen.v1.http.org.openroadm.lldp.rev181019.Protocols1.class) == null)) {
123 LOG.warn("LLDP subtree is missing : isolated openroadm device");
124 return new HashMap<>();
126 org.opendaylight.yang.gen.v1.http.org.openroadm.lldp.rev181019.lldp.container.lldp.@Nullable NbrList
127 nbr221List = protocol221Object.get().augmentation(org.opendaylight.yang.gen.v1.http
128 .org.openroadm.lldp.rev181019.Protocols1.class).getLldp().getNbrList();
129 LOG.info("LLDP subtree is present. Device has {} neighbours", nbr221List.getIfName().size());
130 return rdm2rdmLinkCreatev221(nodeId, tapiTopoUuid, nbr221List);
133 LOG.info("Not yet supported?");
134 return new HashMap<>();
136 LOG.error("Unable to read LLDP data for unmanaged openroadm device version");
137 return new HashMap<>();
141 private Map<LinkKey, Link> rdm2rdmLinkCreatev221(NodeId nodeId, Uuid tapiTopoUuid,
142 org.opendaylight.yang.gen.v1.http.org.openroadm.lldp.rev181019.lldp.container.lldp.NbrList nbrList) {
143 Map<LinkKey, Link> linkMap = new HashMap<>();
144 for (org.opendaylight.yang.gen.v1.http.org.openroadm.lldp.rev181019.lldp.container.lldp.nbr.list.IfName
145 ifName : nbrList.nonnullIfName().values()) {
146 if (ifName.getRemoteSysName() == null) {
147 LOG.warn("Tapi R2R Link LLDP subtree neighbour is empty for nodeId: {}, ifName: {}",
148 nodeId.getValue(),ifName.getIfName());
151 Optional<MountPoint> mps = this.deviceTransactionManager.getDeviceMountPoint(ifName.getRemoteSysName());
152 if (!mps.isPresent()) {
153 LOG.warn("Tapi R2R Link Neighbouring nodeId: {} is not mounted yet", ifName.getRemoteSysName());
154 // The controller raises a warning rather than an error because the first node to
155 // mount cannot see its neighbors yet. The link will be detected when processing
156 // the neighbor node.
159 Link omsLink = createR2RTapiLink(nodeId, ifName.getIfName(), ifName.getRemoteSysName(),
160 ifName.getRemotePortId(), tapiTopoUuid);
161 if (omsLink != null) {
162 linkMap.put(omsLink.key(), omsLink);
168 private Map<LinkKey, Link> rdm2rdmLinkCreatev121(NodeId nodeId, Uuid tapiTopoUuid, NbrList nbrList) {
169 Map<LinkKey, Link> linkMap = new HashMap<>();
170 for (IfName ifName : nbrList.nonnullIfName().values()) {
171 if (ifName.getRemoteSysName() == null) {
172 LOG.warn("Tapi R2R Link LLDP subtree neighbour is empty for nodeId: {}, ifName: {}",
173 nodeId.getValue(),ifName.getIfName());
176 Optional<MountPoint> mps = this.deviceTransactionManager.getDeviceMountPoint(ifName
177 .getRemoteSysName());
178 if (!mps.isPresent()) {
179 LOG.warn("Tapi R2R Link Neighbouring nodeId: {} is not mounted yet", ifName.getRemoteSysName());
180 // The controller raises a warning rather than an error because the first node to
181 // mount cannot see its neighbors yet. The link will be detected when processing
182 // the neighbor node.
185 Link omsLink = createR2RTapiLink(nodeId, ifName.getIfName(), ifName.getRemoteSysName(),
186 ifName.getRemotePortId(), tapiTopoUuid);
187 if (omsLink != null) {
188 linkMap.put(omsLink.key(), omsLink);
194 public Link createR2RTapiLink(NodeId nodeId, String interfaceName, String remoteSystemName,
195 String remoteInterfaceName, Uuid tapiTopoUuid) {
196 String srcTpTx = null;
197 String srcTpRx = null;
198 String destTpTx = null;
199 String destTpRx = null;
200 // Find which degree is associated with ethernet interface
201 Integer srcDegId = getDegFromInterface(nodeId, interfaceName);
202 if (srcDegId == null) {
203 LOG.error("Tapi R2R Link Couldnt find degree connected to Ethernet interface for nodeId: {}", nodeId);
206 // Check whether degree is Unidirectional or Bidirectional by counting
208 // circuit-packs under degree subtree
209 Direction sourceDirection = getDegreeDirection(srcDegId, nodeId);
210 if (Direction.NotApplicable == sourceDirection) {
211 LOG.error("Tapi R2R Link Couldnt find degree direction for nodeId: {} and degree: {}", nodeId, srcDegId);
213 } else if (Direction.Bidirectional == sourceDirection) {
214 srcTpTx = "DEG" + srcDegId + "-TTP-TXRX";
215 srcTpRx = "DEG" + srcDegId + "-TTP-TXRX";
217 srcTpTx = "DEG" + srcDegId + "-TTP-TX";
218 srcTpRx = "DEG" + srcDegId + "-TTP-RX";
220 LOG.debug("Tapi R2R Link SrcTPTx {}, SrcTPRx {}", srcTpTx, srcTpRx);
221 // Find degree for which Ethernet interface is created on other end
222 NodeId destNodeId = new NodeId(remoteSystemName);
223 Integer destDegId = getDegFromInterface(destNodeId, remoteInterfaceName);
224 if (destDegId == null) {
225 LOG.error("Tapi R2R Link Couldnt find degree connected to Ethernet interface for nodeId: {}", nodeId);
228 // Check whether degree is Unidirectional or Bidirectional by counting
230 // circuit-packs under degree subtree
231 Direction destinationDirection = getDegreeDirection(destDegId, destNodeId);
232 if (Direction.NotApplicable == destinationDirection) {
233 LOG.error("Tapi R2R Link Couldnt find degree direction for nodeId: {} and degree: {}",
234 destNodeId, destDegId);
236 } else if (Direction.Bidirectional == destinationDirection) {
237 destTpTx = "DEG" + destDegId + "-TTP-TXRX";
238 destTpRx = "DEG" + destDegId + "-TTP-TXRX";
240 destTpTx = "DEG" + destDegId + "-TTP-TX";
241 destTpRx = "DEG" + destDegId + "-TTP-RX";
243 // Todo -> only handling for the bidirectional case. I assume all tps are of the type bidirectional
244 LOG.debug("Tapi R2R Link DstTPTx {}, DstTPRx {}", destTpTx, srcTpRx);
245 // Create OMS Tapi Link
246 LOG.info("Tapi R2R Link Found a neighbor SrcNodeId: {} , SrcDegId: {} , SrcTPId: {}, DestNodeId:{} , "
247 + "DestDegId: {}, DestTPId: {}", nodeId.getValue(), srcDegId, srcTpTx, destNodeId, destDegId, destTpRx);
248 Link omsLink = createTapiLink(nodeId.getValue(), srcTpTx, destNodeId.getValue(), destTpRx, tapiTopoUuid);
249 LOG.info("Tapi R2R Link OMS link created = {}", omsLink);
253 private Link createTapiLink(String sourceNode, String sourceTp, String destNode, String destTp, Uuid tapiTopoUuid) {
254 Map<NodeEdgePointKey, NodeEdgePoint> nepList = new HashMap<>();
255 Uuid sourceUuidNode = new Uuid(UUID.nameUUIDFromBytes((String.join("+", sourceNode,
256 PHTNC_MEDIA)).getBytes(Charset.forName("UTF-8"))).toString());
257 Uuid sourceUuidTp = new Uuid(UUID.nameUUIDFromBytes((String.join("+", sourceNode, PHTNC_MEDIA, sourceTp))
258 .getBytes(Charset.forName("UTF-8"))).toString());
259 Uuid destUuidNode = new Uuid(UUID.nameUUIDFromBytes((String.join("+", destNode,
260 PHTNC_MEDIA)).getBytes(Charset.forName("UTF-8"))).toString());
261 Uuid destUuidTp = new Uuid(UUID.nameUUIDFromBytes((String.join("+", destNode, PHTNC_MEDIA, destTp))
262 .getBytes(Charset.forName("UTF-8"))).toString());
263 NodeEdgePoint sourceNep = new NodeEdgePointBuilder()
264 .setTopologyUuid(tapiTopoUuid)
265 .setNodeUuid(sourceUuidNode)
266 .setNodeEdgePointUuid(sourceUuidTp)
268 nepList.put(sourceNep.key(), sourceNep);
269 NodeEdgePoint destNep = new NodeEdgePointBuilder()
270 .setTopologyUuid(tapiTopoUuid)
271 .setNodeUuid(destUuidNode)
272 .setNodeEdgePointUuid(destUuidTp)
274 nepList.put(destNep.key(), destNep);
275 String linkNameValue = String.join("-", sourceNode, sourceTp.split("-")[0], sourceTp)
276 + "to" + String.join("-", destNode, destTp.split("-")[0], destTp);
277 Name linkName = new NameBuilder().setValueName("OMS link name")
278 .setValue(linkNameValue)
280 CostCharacteristic costCharacteristic = new CostCharacteristicBuilder()
281 .setCostAlgorithm("Restricted Shortest Path - RSP")
282 .setCostName("HOP_COUNT")
283 .setCostValue("12345678")
285 LatencyCharacteristic latencyCharacteristic = new LatencyCharacteristicBuilder()
286 .setFixedLatencyCharacteristic("12345678")
287 .setQueingLatencyCharacteristic("12345678")
288 .setJitterCharacteristic("12345678")
289 .setWanderCharacteristic("12345678")
290 .setTrafficPropertyName("FIXED_LATENCY")
292 RiskCharacteristic riskCharacteristic = new RiskCharacteristicBuilder()
293 .setRiskCharacteristicName("risk characteristic")
294 .setRiskIdentifierList(List.of("risk identifier1", "risk identifier2"))
296 ValidationMechanism validationMechanism = new ValidationMechanismBuilder()
297 .setValidationMechanism("validation mechanism")
298 .setValidationRobustness("validation robustness")
299 .setLayerProtocolAdjacencyValidated("layer protocol adjacency")
301 return new LinkBuilder()
303 UUID.nameUUIDFromBytes(linkNameValue.getBytes(Charset.forName("UTF-8")))
305 .setName(Map.of(linkName.key(), linkName))
306 .setLayerProtocolName(List.of(LayerProtocolName.PHOTONICMEDIA))
307 .setTransitionedLayerProtocolName(new ArrayList<>())
308 .setNodeEdgePoint(nepList)
309 .setDirection(ForwardingDirection.BIDIRECTIONAL)
310 .setResilienceType(new ResilienceTypeBuilder().setProtectionType(ProtectionType.NOPROTECTON)
311 .setRestorationPolicy(RestorationPolicy.NA)
313 .setAdministrativeState(AdministrativeState.UNLOCKED)
314 .setOperationalState(OperationalState.ENABLED)
315 .setLifecycleState(LifecycleState.INSTALLED)
316 .setTotalPotentialCapacity(new TotalPotentialCapacityBuilder().setTotalSize(
317 new TotalSizeBuilder().setUnit(CapacityUnit.GBPS)
318 .setValue(Uint64.valueOf(100)).build()).build())
319 .setAvailableCapacity(new AvailableCapacityBuilder().setTotalSize(
320 new TotalSizeBuilder().setUnit(CapacityUnit.MBPS)
321 .setValue(Uint64.valueOf(100)).build())
323 .setCostCharacteristic(Map.of(costCharacteristic.key(), costCharacteristic))
324 .setLatencyCharacteristic(Map.of(latencyCharacteristic.key(), latencyCharacteristic))
325 .setRiskCharacteristic(Map.of(riskCharacteristic.key(), riskCharacteristic))
326 .setErrorCharacteristic("error")
327 .setLossCharacteristic("loss")
328 .setRepeatDeliveryCharacteristic("repeat delivery")
329 .setDeliveryOrderCharacteristic("delivery order")
330 .setUnavailableTimeCharacteristic("unavailable time")
331 .setServerIntegrityProcessCharacteristic("server integrity process")
332 .setValidationMechanism(Map.of(validationMechanism.key(), validationMechanism))
336 private Integer getDegFromInterface(NodeId nodeId, String interfaceName) {
337 InstanceIdentifier<Nodes> nodesIID = InstanceIdentifier.builder(Network.class)
338 .child(Nodes.class, new NodesKey(nodeId.getValue())).build();
339 try (ReadTransaction readTx = this.dataBroker.newReadOnlyTransaction()) {
340 Optional<Nodes> nodesObject = readTx.read(LogicalDatastoreType.CONFIGURATION, nodesIID).get();
341 if (nodesObject.isEmpty() || (nodesObject.get().getCpToDegree() == null)) {
342 LOG.warn("Could not find mapping for Interface {} for nodeId {}", interfaceName,
346 Collection<CpToDegree> cpToDeg = nodesObject.get().nonnullCpToDegree().values();
347 Stream<CpToDegree> cpToDegStream = cpToDeg.stream().filter(cp -> cp.getInterfaceName() != null)
348 .filter(cp -> cp.getInterfaceName().equals(interfaceName));
349 if (cpToDegStream != null) {
350 @SuppressWarnings("unchecked") Optional<CpToDegree> firstCpToDegree = cpToDegStream.findFirst();
351 if (firstCpToDegree.isEmpty() || (firstCpToDegree == null)) {
352 LOG.debug("Not found so returning nothing");
355 LOG.debug("Found and returning {}",firstCpToDegree.get().getDegreeNumber().intValue());
356 return firstCpToDegree.get().getDegreeNumber().intValue();
358 LOG.warn("CircuitPack stream couldnt find anything for nodeId: {} and interfaceName: {}",
359 nodeId.getValue(),interfaceName);
361 } catch (InterruptedException | ExecutionException ex) {
362 LOG.error("Unable to read mapping for Interface : {} for nodeId {}", interfaceName, nodeId, ex);
367 public Direction getDegreeDirection(Integer degreeCounter, NodeId nodeId) {
368 InstanceIdentifier<Nodes> nodesIID = InstanceIdentifier.builder(Network.class)
369 .child(Nodes.class, new NodesKey(nodeId.getValue())).build();
370 try (ReadTransaction readTx = this.dataBroker.newReadOnlyTransaction()) {
371 Optional<Nodes> nodesObject = readTx.read(LogicalDatastoreType.CONFIGURATION, nodesIID).get();
372 if (nodesObject.isPresent() && (nodesObject.get().getMapping() != null)) {
373 Collection<Mapping> mappingList = nodesObject.get().nonnullMapping().values();
374 mappingList = mappingList.stream().filter(mp -> mp.getLogicalConnectionPoint().contains("DEG"
375 + degreeCounter)).collect(Collectors.toList());
376 if (mappingList.size() == 1) {
377 return Direction.Bidirectional;
378 } else if (mappingList.size() > 1) {
382 } catch (InterruptedException | ExecutionException e) {
383 LOG.error("Failed getting Mapping data from portMapping",e);
385 return Direction.NotApplicable;