Increase OLM timer to turn-up xc power in RDM node
[transportpce.git] / olm / src / main / java / org / opendaylight / transportpce / olm / power / PowerMgmt.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 com.google.common.util.concurrent.ListenableFuture;
12
13 import java.math.BigDecimal;
14 import java.util.HashMap;
15 import java.util.Map;
16 import java.util.Optional;
17 import java.util.concurrent.ExecutionException;
18 import java.util.concurrent.Future;
19
20 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
21 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
22 import org.opendaylight.transportpce.common.Timeouts;
23 import org.opendaylight.transportpce.common.crossconnect.CrossConnect;
24 import org.opendaylight.transportpce.common.device.DeviceTransaction;
25 import org.opendaylight.transportpce.common.device.DeviceTransactionManager;
26 import org.opendaylight.transportpce.common.openroadminterfaces.OpenRoadmInterfaceException;
27 import org.opendaylight.transportpce.common.openroadminterfaces.OpenRoadmInterfaces;
28 import org.opendaylight.transportpce.olm.util.OlmUtils;
29 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.types.rev161014.NodeTypes;
30 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.types.rev161014.OpticalControlMode;
31 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.types.rev161014.PowerDBm;
32 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.circuit.pack.Ports;
33 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.circuit.pack.PortsKey;
34 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.circuit.packs.CircuitPacks;
35 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.circuit.packs.CircuitPacksKey;
36 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.interfaces.grp.Interface;
37 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.interfaces.grp.InterfaceBuilder;
38 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.interfaces.grp.InterfaceKey;
39 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.org.openroadm.device.container.OrgOpenroadmDevice;
40 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.org.openroadm.device.container.org.openroadm.device.RoadmConnections;
41 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.org.openroadm.device.container.org.openroadm.device.RoadmConnectionsBuilder;
42 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.org.openroadm.device.container.org.openroadm.device.RoadmConnectionsKey;
43 import org.opendaylight.yang.gen.v1.http.org.openroadm.equipment.states.types.rev161014.AdminStates;
44 import org.opendaylight.yang.gen.v1.http.org.openroadm.optical.channel.interfaces.rev161014.Interface1Builder;
45 import org.opendaylight.yang.gen.v1.http.org.openroadm.optical.channel.interfaces.rev161014.och.container.OchBuilder;
46 import org.opendaylight.yang.gen.v1.http.org.openroadm.optical.transport.interfaces.rev161014.Interface1;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.ServicePowerSetupInput;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.olm.rev170418.ServicePowerTurndownInput;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.portmapping.rev170228.network.Nodes;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.portmapping.rev170228.network.nodes.Mapping;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.portmapping.rev170228.network.nodes.MappingKey;
52 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
53 import org.slf4j.Logger;
54 import org.slf4j.LoggerFactory;
55
56 public class PowerMgmt {
57     private static final Logger LOG = LoggerFactory.getLogger(PowerMgmt.class);
58     private static final long DATA_STORE_READ_TIMEOUT = 120;
59     private final DataBroker db;
60     private final OpenRoadmInterfaces openRoadmInterfaces;
61     private final CrossConnect crossConnect;
62     private final DeviceTransactionManager deviceTransactionManager;
63
64     public PowerMgmt(DataBroker db, OpenRoadmInterfaces openRoadmInterfaces,
65             CrossConnect crossConnect, DeviceTransactionManager deviceTransactionManager) {
66         this.db = db;
67         this.openRoadmInterfaces = openRoadmInterfaces;
68         this.crossConnect = crossConnect;
69         this.deviceTransactionManager = deviceTransactionManager;
70     }
71
72     /**
73      * This methods measures power requirement for turning up a WL
74      * from the Spanloss at OTS transmit direction and update
75      * roadm-connection target-output-power.
76      *
77      * @param input
78      *            Input parameter from the olm servicePowerSetup rpc
79      *
80      * @return true/false based on status of operation.
81      */
82     public Boolean setPower(ServicePowerSetupInput input) {
83         LOG.info("Olm-setPower initiated");
84         for (int i = 0; i < input.getNodes().size(); i++) {
85             String nodeId = input.getNodes().get(i).getNodeId();
86             String srcTpId =  input.getNodes().get(i).getSrcTp();
87             String destTpId = input.getNodes().get(i).getDestTp();
88             Optional<Nodes> inputNodeOptional = OlmUtils.getNode(nodeId, db);
89             // If node type is transponder
90             if (inputNodeOptional.isPresent()
91                     && inputNodeOptional.get().getNodeType() != null
92                     && inputNodeOptional.get().getNodeType().equals(NodeTypes.Xpdr)) {
93
94                 Nodes inputNode = inputNodeOptional.get();
95                 LOG.info("Getting data from input node {}", inputNode.getNodeType());
96                 LOG.info("Getting mapping data for node is {}", inputNode.getMapping().stream().filter(o -> o.getKey()
97                         .equals(new MappingKey(destTpId))).findFirst().toString());
98                 // If its A-End transponder
99                 if (destTpId.toLowerCase().contains("network")) {
100                     java.util.Optional<Mapping> mappingObject = inputNode.getMapping().stream().filter(o -> o.getKey()
101                             .equals(new MappingKey(destTpId))).findFirst();
102                     if (mappingObject.isPresent()) {
103                         Map<String, Double> txPowerRangeMap = getXponderPowerRange(mappingObject.get()
104                                 .getSupportingCircuitPackName(), mappingObject.get().getSupportingPort(), nodeId);
105                         if (!txPowerRangeMap.isEmpty()) {
106                             LOG.info("Transponder range exists for nodeId: {}", nodeId);
107                             String srgId =  input.getNodes().get(i + 1).getSrcTp();
108                             String nextNodeId = input.getNodes().get(i + 1).getNodeId();
109
110                             Map<String, Double> rxSRGPowerRangeMap = getSRGRxPowerRange(nextNodeId, srgId);
111                             double powerValue = 0;
112                             if (!rxSRGPowerRangeMap.isEmpty()) {
113                                 LOG.info("SRG Rx Power range exists for nodeId: {}", nodeId);
114                                 if (txPowerRangeMap.get("MaxTx")
115                                         <= rxSRGPowerRangeMap.get("MaxRx")) {
116                                     powerValue = txPowerRangeMap.get("MaxTx");
117                                 } else if (rxSRGPowerRangeMap.get("MaxRx")
118                                         < txPowerRangeMap.get("MaxTx")) {
119                                     powerValue = rxSRGPowerRangeMap.get("MaxRx");
120                                 }
121                                 LOG.info("Calculated Transponder Power value is {}" , powerValue);
122                                 String interfaceName = destTpId + "-" + input.getWaveNumber();
123                                 if (setTransponderPower(nodeId, interfaceName, new BigDecimal(powerValue))) {
124                                     LOG.info("Transponder OCH connection: {} power updated ", interfaceName);
125                                     try {
126                                         LOG.info("Now going in sleep mode");
127                                         Thread.sleep(120000);
128                                     } catch (InterruptedException e) {
129                                         LOG.info("Transponder warmup failed for OCH connection: {}", interfaceName, e);
130                                     }
131                                 } else {
132                                     LOG.info("Transponder OCH connection: {} power update failed ", interfaceName);
133                                 }
134                             } else {
135                                 LOG.info("SRG Power Range not found");
136                             }
137                         } else {
138                             LOG.info("Tranponder range not available seting to default "
139                                     + "power for nodeId: {}", nodeId);
140                             String interfaceName = destTpId + "-" + input.getWaveNumber();
141                             if (setTransponderPower(nodeId, interfaceName, new BigDecimal(-5))) {
142                                 LOG.info("Transponder OCH connection: {} power updated ", interfaceName);
143                                 try {
144                                     Thread.sleep(120000);
145                                 } catch (InterruptedException e) {
146                                     // TODO Auto-generated catch block
147                                     LOG.info("Transponder warmup failed for OCH connection: {}", interfaceName, e);
148                                 }
149                             } else {
150                                 LOG.info("Transponder OCH connection: {} power update failed ", interfaceName);
151                             }
152                         }
153                     } else {
154                         LOG.info("Mapping object not found for nodeId: {}", nodeId);
155                         return false;
156                     }
157                 } else {
158                     LOG.info("{} is a drop node. Net power settings needed", nodeId);
159                 }
160             } else if (inputNodeOptional.isPresent()
161                     && inputNodeOptional.get().getNodeType() != null
162                     && inputNodeOptional.get().getNodeType().equals(NodeTypes.Rdm)) {
163                 // If Degree is transmitting end then set power
164                 Nodes inputNode = inputNodeOptional.get();
165                 LOG.info("This is a roadm device ");
166                 String connectionNumber = srcTpId + "-" + destTpId + "-" + input.getWaveNumber();
167                 LOG.info("Connection number is {}", connectionNumber);
168                 if (destTpId.toLowerCase().contains("deg")) {
169                     Optional<Mapping> mappingObjectOptional = inputNode.getMapping().stream().filter(o -> o.getKey()
170                             .equals(new MappingKey(destTpId))).findFirst();
171                     if (mappingObjectOptional.isPresent()) {
172                         LOG.info("Dest point is Degree {}", mappingObjectOptional.get());
173                         Mapping portMapping = mappingObjectOptional.get();
174                         Optional<Interface> interfaceOpt;
175                         try {
176                             interfaceOpt = openRoadmInterfaces.getInterface(nodeId, portMapping.getSupportingOts());
177                         } catch (OpenRoadmInterfaceException ex) {
178                             LOG.error("Failed to get interface {} from node {}!", portMapping.getSupportingOts(),
179                                     nodeId, ex);
180                             return false;
181                         }
182                         if (interfaceOpt.isPresent()) {
183                             BigDecimal spanLossTx = interfaceOpt.get().getAugmentation(Interface1.class).getOts()
184                                     .getSpanLossTransmit().getValue();
185                             LOG.info("Spanloss TX is {}", spanLossTx);
186                             BigDecimal powerValue = BigDecimal.valueOf(Math.min(spanLossTx.doubleValue() - 9, 2));
187                             LOG.info("Power Value is {}", powerValue);
188                             try {
189                                 Boolean setXconnPowerSuccessVal = setPowerLevel(nodeId,
190                                         OpticalControlMode.Power, powerValue, connectionNumber);
191                                 LOG.info("Success Value is {}", setXconnPowerSuccessVal);
192                                 if (setXconnPowerSuccessVal) {
193                                     LOG.info("Roadm-connection: {} updated ");
194                                     //The value recommended by the white paper is 20 seconds and not 60.
195                                     //TODO - commented code because one vendor is not supporting
196                                     //GainLoss with target-output-power
197                                     Thread.sleep(60000);
198                                     setPowerLevel(nodeId, OpticalControlMode.GainLoss, powerValue,
199                                             connectionNumber);
200                                 } else {
201                                     LOG.info("Set Power failed for Roadm-connection: {} on Node: {}", connectionNumber,
202                                             nodeId);
203                                     return false;
204                                 }
205                             } catch (InterruptedException e) {
206                                 LOG.error("Olm-setPower wait failed {}", e);
207                                 return false;
208                             }
209                         } else {
210                             LOG.error("Interface {} on node {} is not present!", portMapping.getSupportingOts(),
211                                     nodeId);
212                             return false;
213                         }
214                     }
215                   // If Drop node leave node is power mode
216                 } else if (destTpId.toLowerCase().contains("srg")) {
217                     LOG.info("Setting power at drop node");
218                     setPowerLevel(nodeId, OpticalControlMode.Power, null, connectionNumber);
219                 }
220             }
221         }
222         return true;
223     }
224
225     /**
226      * This methods turns down power a WL by performing
227      * following steps:
228      *
229      * <p>
230      * 1. Pull interfaces used in service and change
231      * status to outOfService
232      *
233      * <p>
234      * 2. For each of the ROADM node set target-output-power
235      * to -60dbm, wait for 20 seconds, turn power mode to off
236      *
237      * <p>
238      * 3. Turn down power in Z to A direction and A to Z
239      *
240      * @param input
241      *            Input parameter from the olm servicePowerTurndown rpc
242      *
243      * @return true/false based on status of operation
244      */
245     public Boolean powerTurnDown(ServicePowerTurndownInput input) {
246         LOG.info("Olm-powerTurnDown initiated");
247         /*Starting with last element into the list Z -> A for
248           turning down A -> Z */
249         for (int i = input.getNodes().size() - 1; i >= 0; i--) {
250             String nodeId = input.getNodes().get(i).getNodeId();
251             String srcTpId =  input.getNodes().get(i).getSrcTp();
252             String destTpId = input.getNodes().get(i).getDestTp();
253             Long wlNumber = input.getWaveNumber();
254             String srcInterfaceName = srcTpId + "-" + wlNumber;
255             //if (!setInterfaceOutOfService(nodeId, srcTpId, srcInterfaceName, deviceDb)) {
256             //    LOG.warn("Out of service status update failed for interface {} ", srcInterfaceName);
257             //    return false;
258             //}
259             String destInterfaceName = destTpId + "-" + wlNumber;
260             //if (!setInterfaceOutOfService(nodeId, destTpId, destInterfaceName, deviceDb)) {
261             //    LOG.warn("Out of service status update failed for interface {} ", destInterfaceName);
262             //    return false;
263             //}
264             String connectionNumber =  srcTpId + "-" + destTpId + "-" + wlNumber;
265             if (destTpId.toLowerCase().contains("srg")) {
266                 setPowerLevel(nodeId, OpticalControlMode.Off, null, connectionNumber);
267             } else if (destTpId.toLowerCase().contains("deg")) {
268                 try {
269                     if (!setPowerLevel(nodeId, OpticalControlMode.Power, new BigDecimal(-60),
270                             connectionNumber)) {
271                         LOG.warn("Power down failed for Roadm-connection: {}", connectionNumber);
272                         return false;
273                     }
274                     Thread.sleep(20000);
275                     if (!setPowerLevel(nodeId, OpticalControlMode.Off, null, connectionNumber)) {
276                         LOG.warn("Setting power-control mode off failed for Roadm-connection: {}", connectionNumber);
277                         return false;
278                     }
279                 } catch (InterruptedException e) {
280                     // TODO Auto-generated catch block
281                     LOG.error("Olm-powerTurnDown wait failed {}",e);
282                     return false;
283                 }
284             }
285         }
286         return true;
287     }
288
289     /**
290      * This method updates interface administrative state to
291      * outOfService.
292      *
293      * @param nodeId
294      *            Unique identifier for the mounted netconf- node
295      * @param tpId
296      *            Termination point of mounted netconf - node
297      * @param interfaceName
298      *            Name of interface which needs status update
299      * @return true/false based on status of operation
300      */
301     private Boolean setInterfaceOutOfService(String nodeId, String tpId, String interfaceName) {
302         InstanceIdentifier<Interface> interfacesIID = InstanceIdentifier
303                 .create(OrgOpenroadmDevice.class)
304                 .child(Interface.class, new InterfaceKey(interfaceName));
305         Optional<Interface> nodeInterfaceOpt;
306         try {
307             nodeInterfaceOpt = openRoadmInterfaces.getInterface(nodeId, interfaceName);
308         } catch (OpenRoadmInterfaceException ex) {
309             LOG.error("Failed to get interface {} from node {}!", interfaceName, nodeId, ex);
310             return false;
311         }
312         if (nodeInterfaceOpt.isPresent()) {
313             InterfaceBuilder intfBuilder = new InterfaceBuilder(nodeInterfaceOpt.get());
314             intfBuilder.setAdministrativeState(AdminStates.OutOfService);
315             Future<Optional<DeviceTransaction>> deviceTxFuture = deviceTransactionManager.getDeviceTransaction(nodeId);
316             DeviceTransaction deviceTx;
317             try {
318                 Optional<DeviceTransaction> deviceTxOpt = deviceTxFuture.get();
319                 if (deviceTxOpt.isPresent()) {
320                     deviceTx = deviceTxOpt.get();
321                 } else {
322                     LOG.error("Transaction for device {} was not found!", nodeId);
323                     return false;
324                 }
325             } catch (InterruptedException | ExecutionException e) {
326                 LOG.error("Unable to get transaction for device {}!", nodeId, e);
327                 return false;
328             }
329             deviceTx.put(LogicalDatastoreType.CONFIGURATION, interfacesIID, intfBuilder.build());
330             ListenableFuture<Void> submit = deviceTx.submit(Timeouts.DEVICE_WRITE_TIMEOUT,
331                     Timeouts.DEVICE_WRITE_TIMEOUT_UNIT);
332             try {
333                 submit.get();
334                 LOG.info("Successfully posted interface {}", interfaceName);
335                 return true;
336             } catch (InterruptedException | ExecutionException ex) {
337                 LOG.warn("Failed to post {} ", interfaceName, ex);
338                 return false;
339             }
340         } else {
341             LOG.error("Interface {} on node {} is not present!", interfaceName, nodeId);
342             return false;
343         }
344     }
345
346     /**
347      * This method provides Transponder transmit power range.
348      *
349      * @param circuitPackName
350      *            Transponder circuitPack name
351      * @param portName
352      *            Transponder port name
353      * @param deviceId
354      *            Databroker for the given device
355      * @return HashMap holding Min and Max transmit power for given port
356      */
357     private Map<String, Double> getXponderPowerRange(String circuitPackName, String portName, String deviceId) {
358         InstanceIdentifier<Ports> portIID = InstanceIdentifier.create(OrgOpenroadmDevice.class)
359                 .child(CircuitPacks.class, new CircuitPacksKey(circuitPackName))
360                 .child(Ports.class, new PortsKey(portName));
361         Map<String, Double> powerRangeMap = new HashMap<>();
362         LOG.info("Fetching logical Connection Point value for port {} at circuit pack {}", portName, circuitPackName);
363         Optional<Ports> portObject =
364                 deviceTransactionManager.getDataFromDevice(deviceId, LogicalDatastoreType.OPERATIONAL, portIID,
365                         Timeouts.DEVICE_READ_TIMEOUT, Timeouts.DEVICE_READ_TIMEOUT_UNIT);
366         if (portObject.isPresent()) {
367             Ports port = portObject.get();
368             if (port.getTransponderPort().getPortPowerCapabilityMaxTx() != null) {
369                 powerRangeMap.put("MaxTx", port.getTransponderPort().getPortPowerCapabilityMaxTx().getValue()
370                         .doubleValue());
371                 powerRangeMap.put("MinTx", port.getTransponderPort().getPortPowerCapabilityMinTx().getValue()
372                         .doubleValue());
373             } else {
374                 LOG.warn("Logical Connection Point value missing for {} {}", circuitPackName, port.getPortName());
375             }
376         }
377         return powerRangeMap;
378     }
379
380     /**
381      * This method provides Transponder transmit power range.
382      *
383      * @param nodeId
384      *            Unique identifier for the mounted netconf- node
385      * @param srgId
386      *            SRG Id connected to transponder
387      * @return HashMap holding Min and Max transmit power for given port
388      */
389     private Map<String, Double> getSRGRxPowerRange(String nodeId, String srgId) {
390         Map<String, Double> powerRangeMap = new HashMap<>();
391         LOG.info("Coming inside Xpdr power range");
392         Optional<Mapping> mappingSRGOptional = OlmUtils.getNode(nodeId, db).flatMap(node -> node.getMapping()
393                 .stream().filter(o -> o.getKey()
394                         .equals(new MappingKey(srgId))).findFirst());
395         if (mappingSRGOptional.isPresent()) {
396             LOG.info("Mapping object exists.");
397             String circuitPackName = mappingSRGOptional.get().getSupportingCircuitPackName();
398             String portName = mappingSRGOptional.get().getSupportingPort();
399             InstanceIdentifier<Ports> portIID = InstanceIdentifier.create(OrgOpenroadmDevice.class)
400                     .child(CircuitPacks.class, new CircuitPacksKey(circuitPackName))
401                     .child(Ports.class, new PortsKey(portName));
402
403             LOG.info("Fetching logical Connection Point value for port {} at circuit pack {}{}", portName,
404                     circuitPackName, portIID);
405             Optional<Ports> portObject =
406                     deviceTransactionManager.getDataFromDevice(nodeId, LogicalDatastoreType.OPERATIONAL, portIID,
407                             Timeouts.DEVICE_READ_TIMEOUT, Timeouts.DEVICE_READ_TIMEOUT_UNIT);
408             if (portObject.isPresent()) {
409                 Ports port = portObject.get();
410                 if (port.getRoadmPort() != null) {
411                     LOG.info("Port found on the node ID");
412                     powerRangeMap.put("MinRx", port.getRoadmPort()
413                             .getPortPowerCapabilityMinRx().getValue().doubleValue());
414                     powerRangeMap.put("MaxRx", port.getRoadmPort()
415                             .getPortPowerCapabilityMaxRx().getValue().doubleValue());
416                     return powerRangeMap;
417                 } else {
418                     LOG.warn("Roadm ports power value is missing for {} {}", circuitPackName, port.getPortName());
419                 }
420             } else {
421                 LOG.info("Port not found");
422             }
423
424         } else {
425             LOG.info("Port mapping not found for nodeId: {} and srgId: {} ",
426                     nodeId, srgId);
427         }
428         return powerRangeMap;
429
430     }
431
432     /**
433      * This method retrieves transponder OCH interface and
434      * sets power.
435      *
436      * @param nodeId
437      *            Unique identifier for the mounted netconf- node
438      * @param interfaceName
439      *            OCH interface name carrying WL
440      * @param txPower
441      *            Calculated transmit power
442      * @return true/false based on status of operation
443      */
444     private boolean setTransponderPower(String nodeId, String interfaceName, BigDecimal txPower) {
445         LOG.info("Setting target-power for transponder nodeId: {} InterfaceName: {}",
446                 nodeId, interfaceName);
447         Optional<Interface> interfaceOptional;
448         try {
449             interfaceOptional = openRoadmInterfaces.getInterface(nodeId, interfaceName);
450         } catch (OpenRoadmInterfaceException ex) {
451             LOG.error("Failed to get interface {} from node {}!", interfaceName, nodeId, ex);
452             return false;
453         }
454         if (interfaceOptional.isPresent()) {
455             InterfaceBuilder ochInterfaceBuilder =
456                     new InterfaceBuilder(interfaceOptional.get());
457             OchBuilder ochBuilder = new OchBuilder(ochInterfaceBuilder.getAugmentation(
458                     org.opendaylight.yang.gen.v1.http.org.openroadm.optical.channel.interfaces.rev161014
459                             .Interface1.class).getOch());
460             ochBuilder.setTransmitPower(new PowerDBm(txPower));
461             ochInterfaceBuilder.addAugmentation(
462                     org.opendaylight.yang.gen.v1.http.org.openroadm.optical.channel.interfaces.rev161014
463                             .Interface1.class, new Interface1Builder().setOch(ochBuilder.build()).build());
464
465             Future<Optional<DeviceTransaction>> deviceTxFuture = deviceTransactionManager.getDeviceTransaction(nodeId);
466             DeviceTransaction deviceTx;
467             try {
468                 Optional<DeviceTransaction> deviceTxOpt = deviceTxFuture.get();
469                 if (deviceTxOpt.isPresent()) {
470                     deviceTx = deviceTxOpt.get();
471                 } else {
472                     LOG.error("Transaction for device {} was not found!", nodeId);
473                     return false;
474                 }
475             } catch (InterruptedException | ExecutionException e) {
476                 LOG.error("Unable to get transaction for device {}!", nodeId, e);
477                 return false;
478             }
479
480             InstanceIdentifier<Interface> interfacesIID = InstanceIdentifier.create(OrgOpenroadmDevice.class)
481                     .child(Interface.class, new InterfaceKey(interfaceName));
482             deviceTx.put(LogicalDatastoreType.CONFIGURATION, interfacesIID, ochInterfaceBuilder.build());
483             ListenableFuture<Void> submit = deviceTx.submit(Timeouts.DEVICE_WRITE_TIMEOUT,
484                     Timeouts.DEVICE_WRITE_TIMEOUT_UNIT);
485             try {
486                 submit.get();
487                 LOG.info("Power update is submitted");
488                 return true;
489             } catch (InterruptedException | ExecutionException e) {
490                 LOG.error("Setting transponder power failed {}", e);
491             }
492         } else {
493             LOG.error("Interface {} on node {} is not present!", interfaceName, nodeId);
494         }
495         return false;
496     }
497
498     /**
499      * This method does an edit-config on roadm connection subtree for a given
500      * connection number in order to set power level for use by the optical
501      * power control.
502      *
503      * @param deviceId
504      *            Device id.
505      * @param mode
506      *            Optical control modelcan be off, power or gainLoss.
507      * @param powerValue
508      *            Power value in DBm.
509      * @param connectionNumber
510      *            Name of the cross connect.
511      * @return true/false based on status of operation.
512      */
513     private boolean setPowerLevel(String deviceId, OpticalControlMode mode, BigDecimal powerValue,
514             String connectionNumber) {
515         Optional<RoadmConnections> rdmConnOpt = crossConnect.getCrossConnect(deviceId, connectionNumber);
516         if (rdmConnOpt.isPresent()) {
517             RoadmConnectionsBuilder rdmConnBldr = new RoadmConnectionsBuilder(rdmConnOpt.get());
518             rdmConnBldr.setOpticalControlMode(mode);
519             if (powerValue != null) {
520                 rdmConnBldr.setTargetOutputPower(new PowerDBm(powerValue));
521             }
522             RoadmConnections newRdmConn = rdmConnBldr.build();
523
524             Future<Optional<DeviceTransaction>> deviceTxFuture =
525                     deviceTransactionManager.getDeviceTransaction(deviceId);
526             DeviceTransaction deviceTx;
527             try {
528                 Optional<DeviceTransaction> deviceTxOpt = deviceTxFuture.get();
529                 if (deviceTxOpt.isPresent()) {
530                     deviceTx = deviceTxOpt.get();
531                 } else {
532                     LOG.error("Transaction for device {} was not found!", deviceId);
533                     return false;
534                 }
535             } catch (InterruptedException | ExecutionException e) {
536                 LOG.error("Unable to get transaction for device {}!", deviceId, e);
537                 return false;
538             }
539
540             // post the cross connect on the device
541             InstanceIdentifier<RoadmConnections> roadmConnIID = InstanceIdentifier.create(OrgOpenroadmDevice.class)
542                     .child(RoadmConnections.class, new RoadmConnectionsKey(connectionNumber));
543             deviceTx.put(LogicalDatastoreType.CONFIGURATION, roadmConnIID, newRdmConn);
544             ListenableFuture<Void> submit = deviceTx.submit(Timeouts.DEVICE_WRITE_TIMEOUT,
545                     Timeouts.DEVICE_WRITE_TIMEOUT_UNIT);
546             try {
547                 submit.get();
548                 LOG.info("Roadm connection power level successfully set ");
549                 return true;
550             } catch (InterruptedException | ExecutionException ex) {
551                 LOG.warn("Failed to post {}", newRdmConn, ex);
552             }
553
554         } else {
555             LOG.warn("Roadm-Connection is null in set power level ({})", connectionNumber);
556         }
557         return false;
558     }
559
560 }