adbba537f2ca023e62d2bc741dc74cae8f8fbb23
[transportpce.git] / olm / src / main / java / org / opendaylight / transportpce / olm / power / PowerMgmtVersion710.java
1 /*
2  * Copyright © 2020 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.FluentFuture;
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.eclipse.jdt.annotation.NonNull;
19 import org.opendaylight.mdsal.common.api.CommitInfo;
20 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
21 import org.opendaylight.transportpce.common.Timeouts;
22 import org.opendaylight.transportpce.common.crossconnect.CrossConnect;
23 import org.opendaylight.transportpce.common.device.DeviceTransaction;
24 import org.opendaylight.transportpce.common.device.DeviceTransactionManager;
25 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.link.types.rev191129.OpticalControlMode;
26 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.link.types.rev191129.PowerDBm;
27 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev200529.OrgOpenroadmDeviceData;
28 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev200529.circuit.pack.Ports;
29 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev200529.circuit.pack.PortsKey;
30 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev200529.circuit.packs.CircuitPacks;
31 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev200529.circuit.packs.CircuitPacksKey;
32 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev200529.interfaces.grp.Interface;
33 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev200529.interfaces.grp.InterfaceBuilder;
34 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev200529.interfaces.grp.InterfaceKey;
35 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev200529.org.openroadm.device.container.OrgOpenroadmDevice;
36 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev200529.org.openroadm.device.container.org.openroadm.device.RoadmConnections;
37 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev200529.org.openroadm.device.container.org.openroadm.device.RoadmConnectionsBuilder;
38 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev200529.org.openroadm.device.container.org.openroadm.device.RoadmConnectionsKey;
39 import org.opendaylight.yang.gen.v1.http.org.openroadm.optical.channel.tributary.signal.interfaces.rev200529.Interface1;
40 import org.opendaylight.yang.gen.v1.http.org.openroadm.optical.channel.tributary.signal.interfaces.rev200529.Interface1Builder;
41 import org.opendaylight.yang.gen.v1.http.org.openroadm.optical.channel.tributary.signal.interfaces.rev200529.otsi.container.OtsiBuilder;
42 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
43 import org.opendaylight.yangtools.yang.common.Decimal64;
44 import org.slf4j.Logger;
45 import org.slf4j.LoggerFactory;
46
47
48
49 public final class PowerMgmtVersion710 {
50     private static final Logger LOG = LoggerFactory.getLogger(PowerMgmtVersion710.class);
51
52     private PowerMgmtVersion710() {
53     }
54
55     /**
56      * This method provides Transponder transmit power range.
57      *
58      * @param circuitPackName
59      *            Transponder circuitPack name
60      * @param portName
61      *            Transponder port name
62      * @param deviceId
63      *            Node Id of a device
64      * @param deviceTransactionManager
65      *            Device transaction manager to read device data
66      * @return HashMap holding Min and Max transmit power for given port
67      */
68     public static Map<String, Double> getXponderPowerRange(String circuitPackName, String portName, String deviceId,
69             DeviceTransactionManager deviceTransactionManager) {
70         InstanceIdentifier<Ports> portIID = InstanceIdentifier
71             .builderOfInherited(OrgOpenroadmDeviceData.class, OrgOpenroadmDevice.class)
72             .child(CircuitPacks.class, new CircuitPacksKey(circuitPackName))
73             .child(Ports.class, new PortsKey(portName))
74             .build();
75         LOG.debug("Fetching logical Connection Point value for port {} at circuit pack {}", portName, circuitPackName);
76         Optional<Ports> portObject =
77                 deviceTransactionManager.getDataFromDevice(deviceId, LogicalDatastoreType.OPERATIONAL, portIID,
78                         Timeouts.DEVICE_READ_TIMEOUT, Timeouts.DEVICE_READ_TIMEOUT_UNIT);
79         if (!portObject.isPresent()) {
80             return new HashMap<>();
81         }
82         Ports port = portObject.get();
83         if (port.getTransponderPort() == null || port.getTransponderPort().getPortPowerCapabilityMaxTx() == null) {
84             LOG.warn("Logical Connection Point value missing for {} {}", circuitPackName, port.getPortName());
85             return new HashMap<>();
86         }
87         Map<String, Double> powerRangeMap = new HashMap<>();
88         powerRangeMap.put("MaxTx", port.getTransponderPort().getPortPowerCapabilityMaxTx().getValue().doubleValue());
89         powerRangeMap.put("MinTx", port.getTransponderPort().getPortPowerCapabilityMinTx().getValue().doubleValue());
90         return powerRangeMap;
91     }
92
93     /**
94      * This method provides Transponder transmit power range.
95      *
96      * @param nodeId
97      *            Unique identifier for the mounted netconf- node
98      * @param srgId
99      *            SRG Id connected to transponder
100      * @param deviceTransactionManager
101      *            Device transaction manager to read device data
102      * @param circuitPackName
103      *            SRG circuitpack name
104      * @param portName
105      *            SRG port name
106      * @return HashMap holding Min and Max transmit power for given port
107      */
108     public static Map<String, Double> getSRGRxPowerRange(String nodeId, String srgId,
109             DeviceTransactionManager deviceTransactionManager,
110             String circuitPackName, String portName) {
111         LOG.debug("Coming inside SRG power range");
112         LOG.debug("Mapping object exists.");
113         InstanceIdentifier<Ports> portIID = InstanceIdentifier
114             .builderOfInherited(OrgOpenroadmDeviceData.class, OrgOpenroadmDevice.class)
115             .child(CircuitPacks.class, new CircuitPacksKey(circuitPackName))
116             .child(Ports.class, new PortsKey(portName))
117             .build();
118         LOG.debug("Fetching logical Connection Point value for port {} at circuit pack {}{}", portName,
119                 circuitPackName, portIID);
120         Optional<Ports> portObject =
121                 deviceTransactionManager.getDataFromDevice(nodeId, LogicalDatastoreType.OPERATIONAL, portIID,
122                         Timeouts.DEVICE_READ_TIMEOUT, Timeouts.DEVICE_READ_TIMEOUT_UNIT);
123         if (!portObject.isPresent()) {
124             LOG.info("Port not found");
125             return new HashMap<>();
126         }
127         Ports port = portObject.get();
128         if (port.getRoadmPort() == null) {
129             LOG.warn("Roadm ports power value is missing for {} {}", circuitPackName, port.getPortName());
130             return new HashMap<>();
131         }
132         LOG.debug("Port found on the node ID");
133         Map<String, Double> powerRangeMap = new HashMap<>();
134         powerRangeMap.put("MinRx", port.getRoadmPort().getPortPowerCapabilityMinRx().getValue().doubleValue());
135         powerRangeMap.put("MaxRx", port.getRoadmPort().getPortPowerCapabilityMaxRx().getValue().doubleValue());
136         return powerRangeMap;
137     }
138
139     /**
140      * This method retrieves transponder OCH interface and
141      * sets power.
142      *
143      * @param nodeId
144      *            Unique identifier for the mounted netconf- node
145      * @param interfaceName
146      *            OCH interface name carrying WL
147      * @param txPower
148      *            Calculated transmit power
149      * @param deviceTransactionManager
150      *            Device Transaction Manager
151      * @param interfaceObj
152      *            Interface object
153      *
154      * @return true/false based on status of operation
155      */
156     public static boolean setTransponderPower(String nodeId, String interfaceName, BigDecimal txPower,
157             DeviceTransactionManager deviceTransactionManager,
158             Interface interfaceObj) {
159         LOG.debug("Setting target-power for transponder nodeId: {} InterfaceName: {}",
160                 nodeId, interfaceName);
161         InterfaceBuilder otsiInterfaceBuilder = new InterfaceBuilder(interfaceObj);
162         OtsiBuilder otsiBuilder = new OtsiBuilder(otsiInterfaceBuilder.augmentation(Interface1.class).getOtsi());
163         otsiBuilder.setTransmitPower(new PowerDBm(Decimal64.valueOf(txPower)));
164         otsiInterfaceBuilder.addAugmentation(new Interface1Builder().setOtsi(otsiBuilder.build()).build());
165         Future<Optional<DeviceTransaction>> deviceTxFuture = deviceTransactionManager.getDeviceTransaction(nodeId);
166         DeviceTransaction deviceTx;
167         try {
168             Optional<DeviceTransaction> deviceTxOpt = deviceTxFuture.get();
169             if (deviceTxOpt.isPresent()) {
170                 deviceTx = deviceTxOpt.get();
171             } else {
172                 LOG.error("Transaction for device {} was not found during transponder power setup for Node:", nodeId);
173                 return false;
174             }
175         } catch (InterruptedException | ExecutionException e) {
176             LOG.error("Unable to get transaction for device {} during transponder power setup!", nodeId, e);
177             return false;
178         }
179         InstanceIdentifier<Interface> interfacesIID = InstanceIdentifier
180             .builderOfInherited(OrgOpenroadmDeviceData.class, OrgOpenroadmDevice.class)
181             .child(Interface.class, new InterfaceKey(interfaceName))
182             .build();
183         deviceTx.merge(LogicalDatastoreType.CONFIGURATION, interfacesIID, otsiInterfaceBuilder.build());
184         FluentFuture<? extends @NonNull CommitInfo> commit =
185             deviceTx.commit(Timeouts.DEVICE_WRITE_TIMEOUT, Timeouts.DEVICE_WRITE_TIMEOUT_UNIT);
186         try {
187             commit.get();
188             LOG.info("Transponder Power update is committed");
189             return true;
190         } catch (InterruptedException | ExecutionException e) {
191             LOG.error("Setting transponder power failed: ", e);
192         }
193         return false;
194     }
195
196     /**
197      * This method does an edit-config on roadm connection subtree for a given
198      * connection number in order to set power level for use by the optical
199      * power control.
200      *
201      * @param deviceId
202      *            Device id.
203      * @param mode
204      *            Optical control modelcan be off, power or gainLoss.
205      * @param powerValue
206      *            Power value in DBm.
207      * @param connectionNumber
208      *            Name of the cross connect.
209      * @param crossConnect
210      *            cross connect.
211      * @param deviceTransactionManager
212      *            Device Transaction Manager.
213      *
214      * @return true/false based on status of operation.
215      */
216     public static boolean setPowerLevel(String deviceId, OpticalControlMode mode, BigDecimal powerValue,
217             String connectionNumber, CrossConnect crossConnect,
218             DeviceTransactionManager deviceTransactionManager) {
219         @SuppressWarnings("unchecked") Optional<RoadmConnections> rdmConnOpt =
220             (Optional<RoadmConnections>) crossConnect.getCrossConnect(deviceId, connectionNumber);
221         if (!rdmConnOpt.isPresent()) {
222             LOG.warn("Roadm-Connection is null in set power level ({})", connectionNumber);
223             return false;
224         }
225         RoadmConnectionsBuilder rdmConnBldr = new RoadmConnectionsBuilder(rdmConnOpt.get());
226         rdmConnBldr.setOpticalControlMode(mode);
227         if (powerValue != null) {
228             rdmConnBldr.setTargetOutputPower(new PowerDBm(Decimal64.valueOf(powerValue)));
229         }
230         RoadmConnections newRdmConn = rdmConnBldr.build();
231         Future<Optional<DeviceTransaction>> deviceTxFuture = deviceTransactionManager.getDeviceTransaction(deviceId);
232         DeviceTransaction deviceTx;
233         try {
234             Optional<DeviceTransaction> deviceTxOpt = deviceTxFuture.get();
235             if (!deviceTxOpt.isPresent()) {
236                 LOG.error("Transaction for device {} was not found!", deviceId);
237                 return false;
238             }
239             deviceTx = deviceTxOpt.get();
240         } catch (InterruptedException | ExecutionException e) {
241             LOG.error("Unable to get transaction for device {}!", deviceId, e);
242             return false;
243         }
244         // post the cross connect on the device
245         InstanceIdentifier<RoadmConnections> roadmConnIID = InstanceIdentifier
246             .builderOfInherited(OrgOpenroadmDeviceData.class, OrgOpenroadmDevice.class)
247             .child(RoadmConnections.class, new RoadmConnectionsKey(connectionNumber))
248             .build();
249         deviceTx.merge(LogicalDatastoreType.CONFIGURATION, roadmConnIID, newRdmConn);
250         FluentFuture<? extends @NonNull CommitInfo> commit =
251             deviceTx.commit(Timeouts.DEVICE_WRITE_TIMEOUT, Timeouts.DEVICE_WRITE_TIMEOUT_UNIT);
252         try {
253             commit.get();
254             LOG.info("Roadm connection power level successfully set ");
255             return true;
256         } catch (InterruptedException | ExecutionException ex) {
257             LOG.warn("Failed to post {}", newRdmConn, ex);
258         }
259         return false;
260     }
261
262 }