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