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