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