Rewrite JUnit tests of PowerMgmt implementation
[transportpce.git] / olm / src / main / java / org / opendaylight / transportpce / olm / power / PowerMgmtImpl.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.power;
10
11 import java.math.BigDecimal;
12 import java.math.MathContext;
13 import java.math.RoundingMode;
14 import java.util.HashMap;
15 import java.util.Locale;
16 import java.util.Map;
17 import java.util.Optional;
18 import org.opendaylight.mdsal.binding.api.DataBroker;
19 import org.opendaylight.transportpce.common.crossconnect.CrossConnect;
20 import org.opendaylight.transportpce.common.device.DeviceTransactionManager;
21 import org.opendaylight.transportpce.common.fixedflex.GridConstant;
22 import org.opendaylight.transportpce.common.mapping.PortMapping;
23 import org.opendaylight.transportpce.common.openroadminterfaces.OpenRoadmInterfaceException;
24 import org.opendaylight.transportpce.common.openroadminterfaces.OpenRoadmInterfaces;
25 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.olm.rev210618.ServicePowerSetupInput;
26 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.olm.rev210618.ServicePowerTurndownInput;
27 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev220316.OpenroadmNodeVersion;
28 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev220316.mapping.Mapping;
29 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev220316.mapping.MappingKey;
30 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev220316.network.Nodes;
31 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.types.rev161014.OpticalControlMode;
32 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.interfaces.grp.Interface;
33 import org.opendaylight.yang.gen.v1.http.org.openroadm.optical.transport.interfaces.rev161014.Interface1;
34 import org.opendaylight.yangtools.yang.common.Decimal64;
35 import org.slf4j.Logger;
36 import org.slf4j.LoggerFactory;
37
38 public class PowerMgmtImpl implements PowerMgmt {
39     private static final Logger LOG = LoggerFactory.getLogger(PowerMgmtImpl.class);
40     private final DataBroker db;
41     private final OpenRoadmInterfaces openRoadmInterfaces;
42     private final CrossConnect crossConnect;
43     private final DeviceTransactionManager deviceTransactionManager;
44     private final PortMapping portMapping;
45     private static final BigDecimal DEFAULT_TPDR_PWR_100G = new BigDecimal(-5);
46     private static final BigDecimal DEFAULT_TPDR_PWR_400G = new BigDecimal(0);
47     private static final String INTERFACE_NOT_PRESENT = "Interface {} on node {} is not present!";
48     private static final double MC_WIDTH_GRAN = 2 * GridConstant.GRANULARITY;
49
50     private long timer1 = 120000;
51     // openroadm spec value is 120000, functest value is 3000
52     private long timer2 = 20000;
53     // openroadm spec value is 20000, functest value is 2000
54
55     public PowerMgmtImpl(DataBroker db, OpenRoadmInterfaces openRoadmInterfaces, CrossConnect crossConnect,
56             DeviceTransactionManager deviceTransactionManager, PortMapping portMapping) {
57         this.db = db;
58         this.openRoadmInterfaces = openRoadmInterfaces;
59         this.crossConnect = crossConnect;
60         this.deviceTransactionManager = deviceTransactionManager;
61         this.portMapping = portMapping;
62     }
63
64     public PowerMgmtImpl(DataBroker db, OpenRoadmInterfaces openRoadmInterfaces,
65                          CrossConnect crossConnect, DeviceTransactionManager deviceTransactionManager,
66             PortMapping portMapping, String timer1, String timer2) {
67         this.db = db;
68         this.openRoadmInterfaces = openRoadmInterfaces;
69         this.crossConnect = crossConnect;
70         this.deviceTransactionManager = deviceTransactionManager;
71         this.portMapping = portMapping;
72         try {
73             this.timer1 = Long.parseLong(timer1);
74         } catch (NumberFormatException e) {
75             this.timer1 = 120000;
76             LOG.warn("Failed to retrieve Olm timer1 value from configuration - using default value {}",
77                 this.timer1, e);
78         }
79         try {
80             this.timer2 = Long.parseLong(timer2);
81         } catch (NumberFormatException e) {
82             this.timer2 = 20000;
83             LOG.warn("Failed to retrieve Olm timer2 value from configuration - using default value {}",
84                 this.timer2, e);
85         }
86     }
87
88     /**
89      * This methods measures power requirement for turning up a WL
90      * from the Spanloss at OTS transmit direction and update
91      * roadm-connection target-output-power.
92      *
93      * @param input
94      *            Input parameter from the olm servicePowerSetup rpc
95      *
96      * @return true/false based on status of operation.
97      */
98     //TODO Need to Case Optical Power mode/NodeType in case of 2.2 devices
99     public Boolean setPower(ServicePowerSetupInput input) {
100         LOG.info("Olm-setPower initiated for input {}", input);
101         String spectralSlotName = String.join(GridConstant.SPECTRAL_SLOT_SEPARATOR,
102                 input.getLowerSpectralSlotNumber().toString(),
103                 input.getHigherSpectralSlotNumber().toString());
104         if (input.getNodes() == null) {
105             LOG.error("No Nodes to configure");
106             return false;
107         }
108         for (int i = 0; i < input.getNodes().size(); i++) {
109             String nodeId = input.getNodes().get(i).getNodeId();
110             String destTpId = input.getNodes().get(i).getDestTp();
111             Nodes inputNode = this.portMapping.getNode(nodeId);
112             if (inputNode == null || inputNode.getNodeInfo() == null) {
113                 LOG.error("OLM-PowerMgmtImpl : Error retrieving mapping node for {}", nodeId);
114                 continue;
115             }
116             OpenroadmNodeVersion openroadmVersion = inputNode.getNodeInfo().getOpenroadmVersion();
117
118             switch (inputNode.getNodeInfo().getNodeType()) {
119                 case Xpdr:
120                     if (destTpId == null) {
121                         continue;
122                     }
123                     LOG.info("Getting data from input node {}", inputNode.getNodeInfo().getNodeType());
124                     LOG.info("Getting mapping data for node is {}",
125                         inputNode.nonnullMapping().values().stream().filter(o -> o.key()
126                          .equals(new MappingKey(destTpId))).findFirst().toString());
127                     // If its not A-End transponder
128                     if (!destTpId.toUpperCase(Locale.getDefault()).contains("NETWORK")) {
129                         LOG.info("{} is a drop node. Net power settings needed", nodeId);
130                         continue;
131                     }
132
133                     BigDecimal powerVal = getXpdrPowerValue(
134                             inputNode, destTpId, nodeId, openroadmVersion.getIntValue(),
135                             input.getNodes().get(i + 1).getSrcTp(), input.getNodes().get(i + 1).getNodeId());
136                     if (powerVal == null) {
137                         return false;
138                     }
139
140                     String interfaceName = String.join(GridConstant.NAME_PARAMETERS_SEPARATOR,
141                         destTpId, spectralSlotName);
142                     if (!callSetTransponderPower(nodeId, interfaceName, powerVal, openroadmVersion)) {
143                         LOG.info("Transponder OCH connection: {} power update failed ", interfaceName);
144                         continue;
145                     }
146                     LOG.info("Transponder OCH connection: {} power updated ", interfaceName);
147                     try {
148                         LOG.info("Now going in sleep mode");
149                         Thread.sleep(timer1);
150                     } catch (InterruptedException e) {
151                         LOG.info("Transponder warmup failed for OCH connection: {}", interfaceName, e);
152                         // FIXME shouldn't it be LOG.warn  or LOG.error?
153                         // or maybe this try/catch block can simply be removed
154                     }
155                     break;
156                 case Rdm:
157                     LOG.info("This is a roadm {} device", openroadmVersion.getName());
158                     String connectionNumber = String.join(GridConstant.NAME_PARAMETERS_SEPARATOR,
159                             input.getNodes().get(i).getSrcTp(), destTpId, spectralSlotName);
160                     LOG.info("Connection number is {}", connectionNumber);
161
162                     // If Drop node leave node is power mode
163                     if (destTpId.toUpperCase(Locale.getDefault()).contains("SRG")) {
164                         LOG.info("Setting power at drop node");
165                         crossConnect.setPowerLevel(nodeId, OpticalControlMode.Power.getName(), null, connectionNumber);
166                         continue;
167                     }
168                     if (!destTpId.toUpperCase(Locale.getDefault()).contains("DEG")) {
169                         continue;
170                     }
171                     // If Degree is transmitting end then set power
172                     Optional<Mapping> mappingObjectOptional = inputNode.nonnullMapping()
173                             .values().stream().filter(o -> o.key()
174                             .equals(new MappingKey(destTpId))).findFirst();
175                     if (mappingObjectOptional.isEmpty()) {
176                         continue;
177                     }
178                     // TODO can it be return false rather than continue?
179                     // in that case, mappingObjectOptional could be moved inside method getSpanLossTx()
180                     LOG.info("Dest point is Degree {}", mappingObjectOptional.get());
181                     BigDecimal spanLossTx = getSpanLossTx(mappingObjectOptional.get().getSupportingOts(),
182                         destTpId, nodeId, openroadmVersion.getIntValue());
183
184                     LOG.info("Spanloss TX is {}", spanLossTx);
185                     // TODO: The span-loss limits should be obtained from optical specifications
186                     if (spanLossTx == null || spanLossTx.intValue() <= 0 || spanLossTx.intValue() > 27) {
187                         LOG.error("Power Value is null: spanLossTx null or out of openROADM range ]0,27] {}",
188                             spanLossTx);
189                         return false;
190                     }
191                     Decimal64 powerValue = Decimal64.valueOf(getRdmPowerValue(spanLossTx, input));
192                     try {
193                         if (!crossConnect.setPowerLevel(nodeId, OpticalControlMode.Power.getName(), powerValue,
194                                 connectionNumber)) {
195                             LOG.info("Set Power failed for Roadm-connection: {} on Node: {}",
196                                     connectionNumber, nodeId);
197                             // FIXME shouldn't it be LOG.error
198                             return false;
199                         }
200                         LOG.info("Roadm-connection: {} updated ", connectionNumber);
201                         Thread.sleep(timer2);
202                         // TODO make this timer value configurable via OSGi blueprint
203                         // although the value recommended by the white paper is 20 seconds.
204                         // At least one vendor product needs 60 seconds
205                         // because it is not supporting GainLoss with target-output-power.
206
207                         if (!crossConnect.setPowerLevel(nodeId, OpticalControlMode.GainLoss.getName(), powerValue,
208                                 connectionNumber)) {
209                             LOG.warn("Setting power-control mode off failed for Roadm-connection: {}",
210                                 connectionNumber);
211                             // FIXME no return false in that case?
212                         }
213                     } catch (InterruptedException e) {
214                         LOG.error("Olm-setPower wait failed :", e);
215                         return false;
216                     }
217                     break;
218                 default :
219                     LOG.error("OLM-PowerMgmtImpl : Error with node type for node {}", nodeId);
220                     break;
221             }
222         }
223         return true;
224     }
225
226     private Map<String, Double> getTxPowerRangeMap(Nodes inputNode, String destTpId, String nodeId,
227             Integer openroadmVersion) {
228
229         Optional<Mapping> mappingObject = inputNode.nonnullMapping().values().stream()
230                 .filter(o -> o.key().equals(new MappingKey(destTpId))).findFirst();
231         if (mappingObject.isEmpty()) {
232             LOG.info("Mapping object not found for nodeId: {}", nodeId);
233             // FIXME shouldn't it be LOG.error ?
234             return null;
235             // return null here means return false in setPower()
236             // TODO Align protections with getSRGRxPowerRangeMap
237         }
238
239         String circuitPackName = mappingObject.get().getSupportingCircuitPackName();
240         String portName = mappingObject.get().getSupportingPort();
241         switch (openroadmVersion) {
242             case 1:
243                 return PowerMgmtVersion121.getXponderPowerRange(circuitPackName, portName,
244                     nodeId, deviceTransactionManager);
245             case 2:
246                 return PowerMgmtVersion221.getXponderPowerRange(circuitPackName, portName,
247                     nodeId, deviceTransactionManager);
248             case 3:
249                 return PowerMgmtVersion710.getXponderPowerRange(circuitPackName, portName,
250                     nodeId, deviceTransactionManager);
251             default:
252                 LOG.error("Unrecognized OpenRoadm version");
253                 return new HashMap<>();
254                 // FIXME shouldn't it lead to a return false in setPower()?
255         }
256     }
257
258
259     private Map<String, Double> getSRGRxPowerRangeMap(String srgId, String nodeId, Integer openroadmVersion) {
260
261         Nodes inputNode = this.portMapping.getNode(nodeId);
262         int rdmOpenroadmVersion = inputNode.getNodeInfo().getOpenroadmVersion().getIntValue();
263         Optional<Mapping> mappingObject = inputNode.nonnullMapping().values().stream()
264                 .filter(o -> o.key().equals(new MappingKey(srgId)))
265                 .findFirst();
266
267         if (mappingObject.isEmpty()) {
268             return new HashMap<>();
269             // FIXME shouldn't it lead to a return false in setPower() ?
270         }
271
272         String circuitPackName = mappingObject.get().getSupportingCircuitPackName();
273         String portName = mappingObject.get().getSupportingPort();
274         switch (rdmOpenroadmVersion) {
275             case 1:
276                 return PowerMgmtVersion121.getSRGRxPowerRange(nodeId, srgId,
277                         deviceTransactionManager, circuitPackName, portName);
278             case 2:
279                 return PowerMgmtVersion221.getSRGRxPowerRange(nodeId, srgId,
280                         deviceTransactionManager, circuitPackName, portName);
281             case 3:
282                 return PowerMgmtVersion710.getSRGRxPowerRange(nodeId, srgId,
283                         deviceTransactionManager, circuitPackName, portName);
284             default:
285                 LOG.error("Unrecognized OpenRoadm version");
286                 return null;
287                 //return null here means return false in setPower()
288                 // TODO Align protections with getTxPowerRangeMap
289         }
290     }
291
292     private BigDecimal getSpanLossTx(String supportingOts, String destTpId, String nodeId, Integer openroadmVersion) {
293         try {
294             switch (openroadmVersion) {
295                 case 1:
296                     Optional<Interface> interfaceOpt =
297                         this.openRoadmInterfaces.getInterface(nodeId, supportingOts);
298                     if (interfaceOpt.isEmpty()) {
299                         LOG.error(INTERFACE_NOT_PRESENT, supportingOts, nodeId);
300                         return null;
301                     }
302                     if (interfaceOpt.get().augmentation(Interface1.class).getOts()
303                             .getSpanLossTransmit() == null) {
304                         LOG.error("interface {} has no spanloss value", interfaceOpt.get().getName());
305                         return null;
306                     }
307                     return interfaceOpt.get()
308                             .augmentation(Interface1.class)
309                             .getOts().getSpanLossTransmit().getValue().decimalValue();
310                 case 2:
311                     Optional<org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019
312                             .interfaces.grp.Interface> interfaceOpt1 =
313                         this.openRoadmInterfaces.getInterface(nodeId, supportingOts);
314                     if (interfaceOpt1.isEmpty()) {
315                         LOG.error(INTERFACE_NOT_PRESENT, supportingOts, nodeId);
316                         return null;
317                     }
318                     if (interfaceOpt1.get().augmentation(org.opendaylight.yang.gen.v1.http.org
319                             .openroadm.optical.transport.interfaces.rev181019.Interface1.class).getOts()
320                                 .getSpanLossTransmit() == null) {
321                         LOG.error("interface {} has no spanloss value", interfaceOpt1.get().getName());
322                         return null;
323                     }
324                     return interfaceOpt1.get()
325                             .augmentation(org.opendaylight.yang.gen.v1.http.org
326                                 .openroadm.optical.transport.interfaces.rev181019.Interface1.class)
327                             .getOts().getSpanLossTransmit().getValue().decimalValue();
328                 // TODO no case 3 ?
329                 default:
330                     return null;
331             }
332         } catch (OpenRoadmInterfaceException ex) {
333             LOG.error("Failed to get interface {} from node {}!",
334                 supportingOts, nodeId, ex);
335             return null;
336         } catch (IllegalArgumentException ex) {
337             LOG.error("Failed to get non existing interface {} from node {}!",
338                 supportingOts, nodeId);
339             return null;
340         }
341     }
342
343     private BigDecimal getXpdrPowerValue(Nodes inputNode, String destTpId, String nodeId, Integer openroadmVersion,
344             String srgId, String nextNodeId) {
345
346         Map<String, Double> txPowerRangeMap = getTxPowerRangeMap(inputNode, destTpId, nodeId, openroadmVersion);
347         if (txPowerRangeMap == null) {
348             return null;
349             // return null here means return false in setPower()
350         }
351         BigDecimal powerVal =
352             openroadmVersion == 3 ? DEFAULT_TPDR_PWR_400G : DEFAULT_TPDR_PWR_100G;
353         if (txPowerRangeMap.isEmpty()) {
354             LOG.info("Tranponder range not available setting to default power for nodeId: {}", nodeId);
355             return powerVal;
356         }
357
358         Map<String, Double> rxSRGPowerRangeMap = getSRGRxPowerRangeMap(srgId, nextNodeId, openroadmVersion);
359         if (rxSRGPowerRangeMap == null) {
360             return null;
361             // return null here means return false in setPower()
362             // TODO empty txPowerRangeMap + null rxSRGPowerRangeMap is allowed
363             // => confirm this behavior is OK
364         }
365         if (rxSRGPowerRangeMap.isEmpty()) {
366             LOG.info("SRG Power Range not found, setting the Transponder range to default");
367             return powerVal;
368         }
369
370         powerVal = new BigDecimal(txPowerRangeMap.get("MaxTx"))
371             .min(new BigDecimal(rxSRGPowerRangeMap.get("MaxRx")));
372         LOG.info("Calculated Transponder Power value is {}" , powerVal);
373         return powerVal;
374     }
375
376
377     private BigDecimal getRdmPowerValue(BigDecimal spanLossTx, ServicePowerSetupInput input) {
378         // TODO: These values will be obtained from the specifications
379         // power-value here refers to the Pin[50GHz]
380         BigDecimal powerValue;
381         if (spanLossTx.doubleValue()  >= 23.0) {
382             powerValue = BigDecimal.valueOf(2.0);
383         } else if (spanLossTx.doubleValue()  >= 8.0) {
384             powerValue = BigDecimal.valueOf(- (8.0 - spanLossTx.doubleValue()) / 3.0 - 3.0);
385         } else if (spanLossTx.doubleValue() >= 6.0) {
386             powerValue = BigDecimal.valueOf(-3.0);
387         } else {
388             powerValue = spanLossTx.subtract(BigDecimal.valueOf(9));
389         }
390         BigDecimal mcWidth = new BigDecimal(50);
391         // we work at constant power spectral density (50 GHz channel width @-20dBm=37.5GHz)
392         // 87.5 GHz channel width @-20dBm=75GHz
393         if (input.getMcWidth() != null) {
394             // Units of MC-width are in GHz, meaning it should be 40/50/87.5GHz
395             // TODO: Should we validate this units before proceeding?
396             LOG.debug("Input Grid size is {}", input.getMcWidth().getValue());
397
398             // We round-off the mc-width to the nearest grid-value based on the granularity of 12.5 GHz
399             double nbrMcSlots = Math.ceil(input.getMcWidth().getValue().doubleValue() / MC_WIDTH_GRAN);
400             LOG.debug("Nearest (ceil) number of slots {}", nbrMcSlots);
401             mcWidth = new BigDecimal(MC_WIDTH_GRAN * nbrMcSlots);
402             LOG.debug("Given mc-width={}, Rounded mc-width={}", input.getMcWidth().getValue(), mcWidth);
403
404             BigDecimal logVal = mcWidth.divide(new BigDecimal(50));
405             double pdsVal = 10 * Math.log10(logVal.doubleValue());
406             // Addition of PSD value will give Pin[87.5 GHz]
407             powerValue = powerValue.add(new BigDecimal(pdsVal, new MathContext(3, RoundingMode.HALF_EVEN)));
408         }
409         // FIXME compliancy with OpenROADM MSA and approximations used -- should be addressed with powermask update
410         // cf JIRA ticket https://jira.opendaylight.org/browse/TRNSPRTPCE-494
411         powerValue = powerValue.setScale(2, RoundingMode.CEILING);
412         // target-output-power yang precision is 2, so we limit here to 2
413         LOG.info("The power value is P1[{}GHz]={} dB for spanloss {}", mcWidth, powerValue, spanLossTx);
414         return powerValue;
415     }
416
417     /**
418      * This methods turns down power a WL by performing
419      * following steps:
420      *
421      * <p>
422      * 1. Pull interfaces used in service and change
423      * status to outOfService
424      *
425      * <p>
426      * 2. For each of the ROADM node set target-output-power
427      * to -60dbm, wait for 20 seconds, turn power mode to off
428      *
429      * <p>
430      * 3. Turn down power in Z to A direction and A to Z
431      *
432      * @param input
433      *            Input parameter from the olm servicePowerTurndown rpc
434      *
435      * @return true/false based on status of operation
436      */
437     public Boolean powerTurnDown(ServicePowerTurndownInput input) {
438         LOG.info("Olm-powerTurnDown initiated for input {}", input);
439         /*Starting with last element into the list Z -> A for
440           turning down A -> Z */
441         String spectralSlotName = String.join(GridConstant.SPECTRAL_SLOT_SEPARATOR,
442                 input.getLowerSpectralSlotNumber().toString(),
443                 input.getHigherSpectralSlotNumber().toString());
444         for (int i = input.getNodes().size() - 1; i >= 0; i--) {
445             String nodeId = input.getNodes().get(i).getNodeId();
446             String destTpId = input.getNodes().get(i).getDestTp();
447             String connectionNumber =  String.join(GridConstant.NAME_PARAMETERS_SEPARATOR,
448                     input.getNodes().get(i).getSrcTp(), destTpId, spectralSlotName);
449             try {
450                 if (destTpId.toUpperCase(Locale.getDefault()).contains("DEG")) {
451                     if (!crossConnect.setPowerLevel(nodeId, OpticalControlMode.Power.getName(),
452                             Decimal64.valueOf("-60"), connectionNumber)) {
453                         LOG.warn("Power down failed for Roadm-connection: {}", connectionNumber);
454                         return false;
455                     }
456                     Thread.sleep(timer2);
457                     if (!crossConnect.setPowerLevel(nodeId, OpticalControlMode.Off.getName(), null, connectionNumber)) {
458                         LOG.warn("Setting power-control mode off failed for Roadm-connection: {}", connectionNumber);
459                         return false;
460                     }
461                 } else if (destTpId.toUpperCase(Locale.getDefault()).contains("SRG")) {
462                     if (!crossConnect.setPowerLevel(nodeId, OpticalControlMode.Off.getName(), null, connectionNumber)) {
463                         LOG.warn("Setting power-control mode off failed for Roadm-connection: {}", connectionNumber);
464                         // FIXME a return false would allow sync with DEG case but makes current Unit tests fail
465                     }
466                 }
467             } catch (InterruptedException e) {
468                 // TODO Auto-generated catch block
469                 LOG.error("Olm-powerTurnDown wait failed: ",e);
470                 return false;
471             }
472         }
473         return true;
474     }
475
476     /**
477      * This method retrieves transponder OCH interface and
478      * sets power.
479      *
480      * @param nodeId
481      *            Unique identifier for the mounted netconf- node
482      * @param interfaceName
483      *            OCH interface name carrying WL
484      * @param txPower
485      *            Calculated transmit power
486      * @param openroadmVersion
487      *            Version of openRoadm device software
488      * @return true/false based on status of operation
489      */
490     private boolean callSetTransponderPower(String nodeId, String interfaceName, BigDecimal txPower,
491                                             OpenroadmNodeVersion openroadmVersion) {
492
493         boolean powerSetupResult = false;
494         try {
495             switch (openroadmVersion.getIntValue()) {
496                 case 1:
497                     Optional<Interface> interfaceOptional121 =
498                         openRoadmInterfaces.getInterface(nodeId, interfaceName);
499                     if (interfaceOptional121.isEmpty()) {
500                         LOG.error(INTERFACE_NOT_PRESENT, interfaceName, nodeId);
501                         return false;
502                     }
503                     powerSetupResult = PowerMgmtVersion121.setTransponderPower(nodeId, interfaceName,
504                             txPower, deviceTransactionManager, interfaceOptional121.get());
505                     break;
506                 case 2:
507                     Optional<org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.interfaces.grp
508                             .Interface> interfaceOptional221 =
509                         openRoadmInterfaces.getInterface(nodeId, interfaceName);
510                     if (interfaceOptional221.isEmpty()) {
511                         LOG.error(INTERFACE_NOT_PRESENT, interfaceName, nodeId);
512                         return false;
513                     }
514                     powerSetupResult = PowerMgmtVersion221.setTransponderPower(nodeId, interfaceName,
515                             txPower, deviceTransactionManager, interfaceOptional221.get());
516                     break;
517                 case 3:
518                     Optional<org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev200529.interfaces.grp
519                             .Interface> interfaceOptional710 =
520                         openRoadmInterfaces.getInterface(nodeId, interfaceName);
521                     if (interfaceOptional710.isEmpty()) {
522                         LOG.error(INTERFACE_NOT_PRESENT, interfaceName, nodeId);
523                         return false;
524                     }
525                     powerSetupResult = PowerMgmtVersion710.setTransponderPower(nodeId, interfaceName,
526                             txPower, deviceTransactionManager, interfaceOptional710.get());
527                     break;
528                 default:
529                     LOG.error("Unrecognized OpenRoadm version");
530                     return false;
531             }
532         } catch (OpenRoadmInterfaceException ex) {
533             LOG.error("Failed to get interface {} from node {}!", interfaceName, nodeId, ex);
534             return false;
535         }
536         if (!powerSetupResult) {
537             LOG.debug("Transponder power setup failed for nodeId {} on interface {}",
538                     nodeId, interfaceName);
539             return false;
540         }
541         LOG.debug("Transponder power set up completed successfully for nodeId {} and interface {}",
542                 nodeId,interfaceName);
543         return true;
544     }
545
546 }