Renderer and OLM update
[transportpce.git] / olm / src / main / java / org / opendaylight / transportpce / olm / service / OlmPowerServiceImpl.java
1 /*
2  * Copyright © 2017 AT&T and others.  All rights reserved.
3  *
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
7  */
8
9 package org.opendaylight.transportpce.olm.service;
10
11 import com.google.common.base.Strings;
12 import com.google.common.util.concurrent.ListenableFuture;
13
14 import java.math.BigDecimal;
15 import java.math.RoundingMode;
16 import java.util.ArrayList;
17 import java.util.Collections;
18 import java.util.List;
19 import java.util.Optional;
20 import java.util.concurrent.ExecutionException;
21 import java.util.concurrent.Future;
22 import java.util.concurrent.TimeUnit;
23 import java.util.concurrent.TimeoutException;
24 import java.util.stream.Collectors;
25
26 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
27 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
28 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
29 import org.opendaylight.transportpce.common.InstanceIdentifiers;
30 import org.opendaylight.transportpce.common.NetworkUtils;
31 import org.opendaylight.transportpce.common.Timeouts;
32 import org.opendaylight.transportpce.common.device.DeviceTransaction;
33 import org.opendaylight.transportpce.common.device.DeviceTransactionManager;
34 import org.opendaylight.transportpce.common.mapping.PortMapping;
35 import org.opendaylight.transportpce.olm.power.PowerMgmt;
36 import org.opendaylight.transportpce.olm.util.OlmUtils;
37 import org.opendaylight.transportpce.olm.util.OtsPmHolder;
38 import org.opendaylight.transportpce.olm.util.RoadmLinks;
39 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.types.rev161014.RatioDB;
40 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.interfaces.grp.Interface;
41 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.interfaces.grp.InterfaceBuilder;
42 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.interfaces.grp.InterfaceKey;
43 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.org.openroadm.device.container.OrgOpenroadmDevice;
44 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev170929.Link1;
45 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.types.rev170929.OpenroadmLinkType;
46 import org.opendaylight.yang.gen.v1.http.org.openroadm.optical.transport.interfaces.rev161014.Interface1;
47 import org.opendaylight.yang.gen.v1.http.org.openroadm.optical.transport.interfaces.rev161014.Interface1Builder;
48 import org.opendaylight.yang.gen.v1.http.org.openroadm.optical.transport.interfaces.rev161014.ots.container.Ots;
49 import org.opendaylight.yang.gen.v1.http.org.openroadm.optical.transport.interfaces.rev161014.ots.container.OtsBuilder;
50 import org.opendaylight.yang.gen.v1.http.org.openroadm.pm.types.rev161014.PmGranularity;
51 import org.opendaylight.yang.gen.v1.http.org.openroadm.resource.types.rev161014.ResourceTypeEnum;
52 import org.opendaylight.yang.gen.v1.http.org.transportpce.common.types.rev170907.olm.get.pm.input.ResourceIdentifierBuilder;
53 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev150608.Network;
54 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev150608.NetworkId;
55 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev150608.NetworkKey;
56 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev150608.NodeId;
57 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev150608.network.Node;
58 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev150608.network.NodeKey;
59 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev150608.network.node.SupportingNode;
60 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev150608.Network1;
61 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev150608.network.Link;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.CalculateSpanlossBaseInput;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.CalculateSpanlossBaseOutput;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.CalculateSpanlossBaseOutputBuilder;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.CalculateSpanlossCurrentInput;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.CalculateSpanlossCurrentOutput;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.CalculateSpanlossCurrentOutputBuilder;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.GetPmInput;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.GetPmInputBuilder;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.GetPmOutput;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.GetPmOutputBuilder;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.ServicePowerResetInput;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.ServicePowerResetOutput;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.ServicePowerSetupInput;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.ServicePowerSetupOutput;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.ServicePowerSetupOutputBuilder;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.ServicePowerTurndownInput;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.ServicePowerTurndownOutput;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.ServicePowerTurndownOutputBuilder;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.get.pm.output.Measurements;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.portmapping.rev170228.network.nodes.Mapping;
82 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
83 import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
84 import org.slf4j.Logger;
85 import org.slf4j.LoggerFactory;
86
87 public class OlmPowerServiceImpl implements OlmPowerService {
88     private static final Logger LOG = LoggerFactory.getLogger(OlmPowerServiceImpl.class);
89     private static final String SUCCESS = "Success";
90     private static final String FAILED = "Failed";
91     private final DataBroker dataBroker;
92     private final PowerMgmt powerMgmt;
93     private final DeviceTransactionManager deviceTransactionManager;
94     private final PortMapping portMapping;
95
96     public OlmPowerServiceImpl(DataBroker dataBroker, PowerMgmt powerMgmt,
97             DeviceTransactionManager deviceTransactionManager, PortMapping portMapping) {
98         this.dataBroker = dataBroker;
99         this.powerMgmt = powerMgmt;
100         this.portMapping = portMapping;
101         this.deviceTransactionManager = deviceTransactionManager;
102     }
103
104     public void init() {
105         LOG.info("init ...");
106     }
107
108     public void close() {
109         LOG.info("close ...");
110     }
111
112
113     @Override
114     public GetPmOutput getPm(GetPmInput pmInput) {
115         GetPmOutputBuilder pmOutputBuilder = OlmUtils.pmFetch(pmInput, deviceTransactionManager);
116         return pmOutputBuilder.build();
117     }
118
119     @Override
120     public ServicePowerSetupOutput servicePowerSetup(ServicePowerSetupInput powerSetupInput) {
121         ServicePowerSetupOutputBuilder powerSetupOutput = new ServicePowerSetupOutputBuilder();
122         boolean successValPowerCalculation = powerMgmt.setPower(powerSetupInput);
123
124         if (successValPowerCalculation) {
125             powerSetupOutput.setResult(SUCCESS);
126         } else {
127             powerSetupOutput.setResult(FAILED);
128         }
129         return powerSetupOutput.build();
130     }
131
132     @Override
133     public ServicePowerTurndownOutput servicePowerTurndown(
134             ServicePowerTurndownInput powerTurndownInput) {
135
136         ServicePowerTurndownOutputBuilder powerTurnDownOutput = new ServicePowerTurndownOutputBuilder();
137         // TODO add flag or return failure instead of string
138         if (powerMgmt.powerTurnDown(powerTurndownInput)) {
139             powerTurnDownOutput.setResult(SUCCESS);
140         } else {
141             powerTurnDownOutput.setResult(FAILED);
142         }
143         return powerTurnDownOutput.build();
144     }
145
146     @Override
147     public CalculateSpanlossBaseOutput calculateSpanlossBase(CalculateSpanlossBaseInput spanlossBaseInput) {
148
149         LOG.info("CalculateSpanlossBase Request received for source type {}", spanlossBaseInput.getSrcType());
150
151         List<Link> networkLinks = getNetworkLinks();
152         if (networkLinks.isEmpty()) {
153             LOG.warn("Failed to get links form {} topology.", NetworkUtils.OVERLAY_NETWORK_ID);
154             return new CalculateSpanlossBaseOutputBuilder().setResult(FAILED).build();
155         }
156
157         if (! CalculateSpanlossBaseInput.SrcType.All.equals(spanlossBaseInput.getSrcType())) {
158             networkLinks = networkLinks.stream()
159                     .filter(link -> link.getLinkId().equals(spanlossBaseInput.getLinkId()))
160                     .collect(Collectors.toList());
161         }
162
163         List<RoadmLinks> roadmLinks = new ArrayList<>();
164         for (Link link : networkLinks) {
165             Link1 roadmLinkAugmentation = link.getAugmentation(Link1.class);
166             if (roadmLinkAugmentation == null) {
167                 LOG.debug("Missing OpenRoadm link augmentation in link {} from {} topology.",
168                         link.getLinkId().getValue(), NetworkUtils.OVERLAY_NETWORK_ID);
169                 continue;
170             }
171             if (OpenroadmLinkType.ROADMTOROADM.equals(roadmLinkAugmentation.getLinkType())) {
172                 // Only calculate spanloss for Roadm-to-Roadm links
173                 RoadmLinks roadmLink = new RoadmLinks();
174                 roadmLink.setSrcNodeId(link.getSource().getSourceNode().getValue());
175                 roadmLink.setSrcTpId(link.getSource().getSourceTp().toString());
176                 roadmLink.setDestNodeId(link.getDestination().getDestNode().getValue());
177                 roadmLink.setDestTpid(link.getDestination().getDestTp().toString());
178                 roadmLinks.add(roadmLink);
179             }
180         }
181
182         if (roadmLinks.isEmpty()) {
183             LOG.warn("Topology {} does not have any Roadm-to-Roadm links.", NetworkUtils.OVERLAY_NETWORK_ID);
184             return new CalculateSpanlossBaseOutputBuilder().setResult(FAILED).build();
185         }
186
187         boolean spanLossResult = getLinkSpanloss(roadmLinks);
188         CalculateSpanlossBaseOutputBuilder spanLossBaseBuilder = new CalculateSpanlossBaseOutputBuilder();
189         if (spanLossResult) {
190             spanLossBaseBuilder.setResult(SUCCESS);
191             return spanLossBaseBuilder.build();
192         } else {
193             LOG.warn("Spanloss calculation failed");
194             spanLossBaseBuilder.setResult(FAILED);
195             return spanLossBaseBuilder.build();
196         }
197
198     }
199
200     @Override
201     public CalculateSpanlossCurrentOutput calculateSpanlossCurrent(CalculateSpanlossCurrentInput input) {
202         LOG.info("calculateSpanlossCurrent Request received for all links in network model.");
203         List<Link> networkLinks = getNetworkLinks();
204         if (networkLinks.isEmpty()) {
205             LOG.warn("Failed to get links form {} topology.", NetworkUtils.OVERLAY_NETWORK_ID);
206             return null;
207         }
208         List<RoadmLinks> roadmLinks = new ArrayList<>();
209         for (Link link : networkLinks) {
210             Link1 roadmLinkAugmentation = link.getAugmentation(Link1.class);
211             if (roadmLinkAugmentation == null) {
212                 LOG.debug("Missing OpenRoadm link augmentation in link {} from {} topology.",
213                         link.getLinkId().getValue(), NetworkUtils.OVERLAY_NETWORK_ID);
214                 continue;
215             }
216             if (OpenroadmLinkType.ROADMTOROADM.equals(roadmLinkAugmentation.getLinkType())) {
217                 // Only calculate spanloss for Roadm-to-Roadm links
218                 RoadmLinks roadmLink = new RoadmLinks();
219                 roadmLink.setSrcNodeId(link.getSource().getSourceNode().toString());
220                 roadmLink.setSrcTpId(link.getSource().getSourceTp().toString());
221                 roadmLink.setDestNodeId(link.getDestination().getDestNode().toString());
222                 roadmLink.setDestTpid(link.getDestination().getDestTp().toString());
223                 roadmLinks.add(roadmLink);
224             }
225         }
226
227         if (roadmLinks.isEmpty()) {
228             LOG.warn("Topology {} does not have any Roadm-to-Roadm links.", NetworkUtils.OVERLAY_NETWORK_ID);
229             return null;
230         }
231
232         boolean spanLossResult = getLinkSpanloss(roadmLinks);
233         CalculateSpanlossCurrentOutputBuilder spanLossCurrentBuilder = new CalculateSpanlossCurrentOutputBuilder();
234         if (spanLossResult) {
235             spanLossCurrentBuilder.setResult(SUCCESS);
236             return spanLossCurrentBuilder.build();
237         } else {
238             LOG.error("Spanloss Current calculation failed");
239             spanLossCurrentBuilder.setResult(FAILED);
240             return spanLossCurrentBuilder.build();
241         }
242     }
243
244     @Override
245     public ServicePowerResetOutput servicePowerReset(ServicePowerResetInput input) {
246         // TODO
247         return null;
248     }
249
250     private List<Link> getNetworkLinks() {
251         NetworkKey overlayTopologyKey = new NetworkKey(new NetworkId(NetworkUtils.OVERLAY_NETWORK_ID));
252
253         InstanceIdentifier<Network1> networkIID = InstanceIdentifier.builder(Network.class, overlayTopologyKey)
254                 .augmentation(Network1.class)
255                 .build();
256         Optional<Network1> networkOptional;
257         try (ReadOnlyTransaction rtx = dataBroker.newReadOnlyTransaction()) {
258             //TODO change to constant from Timeouts class when it will be merged.
259             networkOptional = rtx.read(LogicalDatastoreType.CONFIGURATION, networkIID).get(Timeouts.DATASTORE_READ,
260                     TimeUnit.MILLISECONDS).toJavaUtil();
261         } catch (InterruptedException | ExecutionException | TimeoutException e) {
262             LOG.warn("Read of {} topology failed", NetworkUtils.OVERLAY_NETWORK_ID);
263             return Collections.emptyList();
264         }
265
266         if (! networkOptional.isPresent()) {
267             LOG.warn("Network augmentation with links data is not present in {} topology.",
268                     NetworkUtils.OVERLAY_NETWORK_ID);
269             return Collections.emptyList();
270         }
271
272         List<Link> networkLinks = networkOptional.get().getLink();
273         if (networkLinks == null || networkLinks.isEmpty()) {
274             LOG.warn("Links are not present in {} topology.", NetworkUtils.OVERLAY_NETWORK_ID);
275             return Collections.emptyList();
276         }
277         return networkLinks;
278     }
279
280     /**
281      * This method retrieves OTS PM from current PM list by nodeId and TPId: Steps:
282      *
283      * <p>
284      * 1. Get OTS interface name from port mapping by TPId 2. Call getPm RPC to get OTS PM
285      *
286      * <p>
287      *
288      * @param nodeId Node-id of the NE.
289      * @param tpID Termination point Name.
290      * @param pmName PM name which need to be retrieved
291      * @return reference to OtsPmHolder
292      */
293     private OtsPmHolder getPmMeasurements(String nodeId, String tpID, String pmName) {
294         String realNodeId = getRealNodeId(nodeId);
295         Mapping mapping = portMapping.getMapping(realNodeId, tpID);
296         if (mapping == null) {
297             return null;
298         }
299         GetPmInput getPmInput = new GetPmInputBuilder().setNodeId(realNodeId)
300                 .setResourceType(ResourceTypeEnum.Interface).setGranularity(PmGranularity._15min)
301                 .setResourceIdentifier(
302                         new ResourceIdentifierBuilder().setResourceName(mapping.getSupportingOts()).build())
303                 .build();
304         GetPmOutput otsPmOutput = getPm(getPmInput);
305
306         if (otsPmOutput == null) {
307             LOG.info("OTS PM not found for NodeId: {} TP Id:{} PMName:{}", realNodeId, tpID, pmName);
308             return null;
309         }
310         try {
311             for (Measurements measurement : otsPmOutput.getMeasurements()) {
312                 if (pmName.equals(measurement.getPmparameterName())) {
313                     return new OtsPmHolder(pmName, Double.parseDouble(measurement.getPmparameterValue()),
314                             mapping.getSupportingOts());
315                 }
316             }
317         } catch (NumberFormatException e) {
318             LOG.warn("Unable to get PM for NodeId: {} TP Id:{} PMName:{}", realNodeId, tpID, pmName, e);
319         }
320         return null;
321     }
322
323     /**
324      * This method Sets Spanloss on A-End and Z-End OTS interface: Steps:
325      *
326      * <p>
327      * 1. Read existing interface details
328      *
329      * <p>
330      * 2. Set spanloss
331      *
332      * @param nodeId nodeId of NE on which spanloss need to be updated
333      * @param interfaceName OTS interface for NE on which spanloss is cacluated
334      * @param spanLoss calculated spanloss value
335      * @param direction for which spanloss is calculated.It can be either Tx or Rx
336      * @return true/false
337      */
338     private boolean setSpanLoss(String nodeId, String interfaceName, BigDecimal spanLoss, String direction) {
339         String realNodeId = getRealNodeId(nodeId);
340         LOG.info("Setting Spanloss in device for {}, InterfaceName: {}", realNodeId, interfaceName);
341         InstanceIdentifier<Interface> interfacesIID = InstanceIdentifier.create(OrgOpenroadmDevice.class)
342                 .child(Interface.class, new InterfaceKey(interfaceName));
343         com.google.common.base.Optional<Interface> interfaceObject;
344         try {
345             Future<Optional<DeviceTransaction>> deviceTxFuture =
346                     deviceTransactionManager.getDeviceTransaction(realNodeId);
347             java.util.Optional<DeviceTransaction> deviceTxOpt = deviceTxFuture.get();
348             DeviceTransaction deviceTx;
349             if (deviceTxOpt.isPresent()) {
350                 deviceTx = deviceTxOpt.get();
351             } else {
352                 LOG.error("Device transaction for device {} was not found!", nodeId);
353                 return false;
354             }
355             interfaceObject = deviceTx.read(LogicalDatastoreType.CONFIGURATION, interfacesIID).get();
356             BigDecimal initialSpanloss = new BigDecimal(0);
357             RatioDB spanLossRx = new RatioDB(initialSpanloss);
358             RatioDB spanLossTx = new RatioDB(initialSpanloss);
359             if (interfaceObject.isPresent()) {
360                 Interface intf = interfaceObject.get();
361                 InterfaceBuilder interfaceBuilder = new InterfaceBuilder(intf);
362                 OtsBuilder otsBuilder = new OtsBuilder();
363                 if (intf.getAugmentation(Interface1.class) != null
364                     && intf.getAugmentation(Interface1.class).getOts() != null) {
365                     Ots ots = intf.getAugmentation(Interface1.class).getOts();
366                     otsBuilder.setFiberType(ots.getFiberType());
367                     spanLossRx = ots.getSpanLossReceive();
368                     spanLossTx = ots.getSpanLossTransmit();
369                 } else {
370                     spanLossRx = new RatioDB(spanLoss);
371                     spanLossTx = new RatioDB(spanLoss);
372                 }
373                 Interface1Builder intf1Builder = new Interface1Builder();
374                 if (direction.equals("TX")) {
375                     otsBuilder.setSpanLossTransmit(new RatioDB(spanLoss));
376                     otsBuilder.setSpanLossReceive(spanLossRx);
377                 } else {
378                     otsBuilder.setSpanLossTransmit(spanLossTx).setSpanLossReceive(new RatioDB(spanLoss));
379                 }
380                 interfaceBuilder.addAugmentation(Interface1.class, intf1Builder.setOts(otsBuilder.build()).build());
381                 deviceTx.put(LogicalDatastoreType.CONFIGURATION, interfacesIID, interfaceBuilder.build());
382                 ListenableFuture<Void> submit =
383                         deviceTx.submit(Timeouts.DEVICE_WRITE_TIMEOUT, Timeouts.DEVICE_WRITE_TIMEOUT_UNIT);
384                 submit.get();
385                 LOG.info("Spanloss Value update completed successfully");
386                 return true;
387             }
388         } catch (InterruptedException | ExecutionException e) {
389             LOG.warn("Unable to set spanloss", e);
390         }
391         return false;
392     }
393
394     /**
395      * This method calculates Spanloss by TranmistPower - Receive Power Steps:
396      *
397      * <p>
398      * 1. Read PM measurement
399      *
400      * <p>
401      * 2. Set Spanloss value for interface
402      *
403      * @param roadmLinks reference to list of RoadmLinks
404      * @return true/false
405      */
406     private boolean getLinkSpanloss(List<RoadmLinks> roadmLinks) {
407         LOG.info("Executing GetLinkSpanLoss");
408         BigDecimal spanLoss = new BigDecimal(0);
409         for (int i = 0; i < roadmLinks.size(); i++) {
410
411             OtsPmHolder srcOtsPmHoler = getPmMeasurements(roadmLinks.get(i).getSrcNodeId(),
412                     roadmLinks.get(i).getSrcTpId(), "OpticalPowerOutput");
413             OtsPmHolder destOtsPmHoler = getPmMeasurements(roadmLinks.get(i).getDestNodeId(),
414                     roadmLinks.get(i).getDestTpid(), "OpticalPowerInput");
415             spanLoss = new BigDecimal(srcOtsPmHoler.getOtsParameterVal() - destOtsPmHoler.getOtsParameterVal())
416                     .setScale(0, RoundingMode.HALF_UP);
417             LOG.info("Spanloss Calculated as :" + spanLoss + "=" + srcOtsPmHoler.getOtsParameterVal() + "-"
418                     + destOtsPmHoler.getOtsParameterVal());
419             if (spanLoss.doubleValue() < 28 && spanLoss.doubleValue() > 0) {
420                 if (!setSpanLoss(roadmLinks.get(i).getSrcNodeId(), srcOtsPmHoler.getOtsInterfaceName(), spanLoss,
421                         "TX")) {
422                     LOG.info("Setting spanLoss failed for " + roadmLinks.get(i).getSrcNodeId());
423                     return false;
424                 }
425                 if (!setSpanLoss(roadmLinks.get(i).getDestNodeId(), destOtsPmHoler.getOtsInterfaceName(), spanLoss,
426                         "RX")) {
427                     LOG.info("Setting spanLoss failed for " + roadmLinks.get(i).getDestNodeId());
428                     return false;
429                 }
430             }
431         }
432         return true;
433     }
434
435     private String getRealNodeId(String mappedNodeId) {
436         KeyedInstanceIdentifier<Node, NodeKey> mappedNodeII =
437                 InstanceIdentifiers.OVERLAY_NETWORK_II.child(Node.class, new NodeKey(new NodeId(mappedNodeId)));
438         com.google.common.base.Optional<Node> realNode;
439         try (ReadOnlyTransaction readOnlyTransaction = dataBroker.newReadOnlyTransaction()) {
440             realNode = readOnlyTransaction.read(LogicalDatastoreType.CONFIGURATION, mappedNodeII).get();
441         } catch (InterruptedException | ExecutionException e) {
442             LOG.error(e.getMessage(), e);
443             throw new IllegalStateException(e);
444         }
445         if (!realNode.isPresent() || realNode.get().getSupportingNode() == null) {
446             throw new IllegalArgumentException(
447                     String.format("Could not find node %s, or supporting node is not present", mappedNodeId));
448         }
449         List<SupportingNode> collect = realNode.get().getSupportingNode().stream()
450                 .filter(node -> node.getNetworkRef() != null
451                         && NetworkUtils.UNDERLAY_NETWORK_ID.equals(node.getNetworkRef().getValue())
452                         && node.getNodeRef() != null && !Strings.isNullOrEmpty(node.getNodeRef().getValue()))
453                 .collect(Collectors.toList());
454         if (collect.isEmpty() || collect.size() > 1) {
455             throw new IllegalArgumentException(String.format("Invalid support node count [%d] was found for node %s",
456                     collect.size(), mappedNodeId));
457         }
458         return collect.iterator().next().getNodeRef().getValue();
459     }
460
461 }