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