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