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