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