switch to DeviceTransaction.commit()
[transportpce.git] / common / src / main / java / org / opendaylight / transportpce / common / crossconnect / CrossConnectImpl221.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 package org.opendaylight.transportpce.common.crossconnect;
9
10 import com.google.common.util.concurrent.FluentFuture;
11 import java.math.BigDecimal;
12 import java.util.ArrayList;
13 import java.util.Collections;
14 import java.util.List;
15 import java.util.Optional;
16 import java.util.concurrent.ExecutionException;
17 import java.util.concurrent.Future;
18
19 import org.eclipse.jdt.annotation.NonNull;
20 import org.opendaylight.controller.md.sal.binding.api.MountPoint;
21 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
22 import org.opendaylight.controller.sal.binding.api.RpcConsumerRegistry;
23 import org.opendaylight.mdsal.common.api.CommitInfo;
24 import org.opendaylight.transportpce.common.Timeouts;
25 import org.opendaylight.transportpce.common.device.DeviceTransaction;
26 import org.opendaylight.transportpce.common.device.DeviceTransactionManager;
27 import org.opendaylight.transportpce.common.openroadminterfaces.OpenRoadmInterfaceException;
28 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.types.rev181019.OpticalControlMode;
29 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.types.rev181019.PowerDBm;
30 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.GetConnectionPortTrailInputBuilder;
31 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.GetConnectionPortTrailOutput;
32 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.OrgOpenroadmDeviceService;
33 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.connection.DestinationBuilder;
34 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.connection.SourceBuilder;
35 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.get.connection.port.trail.output.Ports;
36 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.org.openroadm.device.container.OrgOpenroadmDevice;
37 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.org.openroadm.device.container.org.openroadm.device.RoadmConnections;
38 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.org.openroadm.device.container.org.openroadm.device.RoadmConnectionsBuilder;
39 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.org.openroadm.device.container.org.openroadm.device.RoadmConnectionsKey;
40 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
41 import org.opendaylight.yangtools.yang.common.RpcResult;
42 import org.slf4j.Logger;
43 import org.slf4j.LoggerFactory;
44
45 public class CrossConnectImpl221 {
46
47     private static final Logger LOG = LoggerFactory.getLogger(CrossConnectImpl221.class);
48     private final DeviceTransactionManager deviceTransactionManager;
49
50     public CrossConnectImpl221(DeviceTransactionManager deviceTransactionManager) {
51         this.deviceTransactionManager = deviceTransactionManager;
52     }
53
54     public Optional<RoadmConnections> getCrossConnect(String deviceId, String connectionNumber) {
55         //TODO Change it to Operational later for real device
56         return deviceTransactionManager.getDataFromDevice(deviceId, LogicalDatastoreType.CONFIGURATION,
57                 generateRdmConnectionIID(connectionNumber), Timeouts.DEVICE_READ_TIMEOUT,
58                 Timeouts.DEVICE_READ_TIMEOUT_UNIT);
59     }
60
61
62     public Optional<String> postCrossConnect(String deviceId, Long waveNumber, String srcTp, String destTp) {
63         RoadmConnectionsBuilder rdmConnBldr = new RoadmConnectionsBuilder();
64         String connectionNumber = generateConnectionName(srcTp, destTp, waveNumber);
65         rdmConnBldr.setConnectionName(connectionNumber);
66
67         rdmConnBldr.setOpticalControlMode(OpticalControlMode.Off);
68
69         rdmConnBldr.setSource(new SourceBuilder().setSrcIf(srcTp + "-nmc-" + waveNumber).build());
70
71         rdmConnBldr.setDestination(new DestinationBuilder().setDstIf(destTp + "-nmc-" + waveNumber).build());
72
73
74         InstanceIdentifier<RoadmConnections> rdmConnectionIID = InstanceIdentifier.create(OrgOpenroadmDevice.class)
75                 .child(RoadmConnections.class, new RoadmConnectionsKey(rdmConnBldr.getConnectionName()));
76
77         Future<Optional<DeviceTransaction>> deviceTxFuture = deviceTransactionManager.getDeviceTransaction(deviceId);
78         DeviceTransaction deviceTx;
79         try {
80             Optional<DeviceTransaction> deviceTxOpt = deviceTxFuture.get();
81             if (deviceTxOpt.isPresent()) {
82                 deviceTx = deviceTxOpt.get();
83             } else {
84                 LOG.error("Device transaction for device {} was not found!", deviceId);
85                 return Optional.empty();
86             }
87         } catch (InterruptedException | ExecutionException e) {
88             LOG.error("Unable to obtain device transaction for device {}!", deviceId, e);
89             return Optional.empty();
90         }
91
92         // post the cross connect on the device
93         deviceTx.put(LogicalDatastoreType.CONFIGURATION, rdmConnectionIID, rdmConnBldr.build());
94         FluentFuture<? extends @NonNull CommitInfo> commit =
95                 deviceTx.commit(Timeouts.DEVICE_WRITE_TIMEOUT, Timeouts.DEVICE_WRITE_TIMEOUT_UNIT);
96         try {
97             commit.get();
98             LOG.info("Roadm-connection successfully created: {}-{}-{}", srcTp, destTp, waveNumber);
99             return Optional.of(connectionNumber);
100         } catch (InterruptedException | ExecutionException e) {
101             LOG.warn("Failed to post {}. Exception: {}", rdmConnBldr.build(), e);
102         }
103         return Optional.empty();
104     }
105
106
107     public List<String> deleteCrossConnect(String deviceId, String connectionName) {
108         List<String> interfList = new ArrayList<>();
109         Optional<RoadmConnections> xc = getCrossConnect(deviceId, connectionName);
110         //Check if cross connect exists before delete
111         if (xc.isPresent()) {
112             String name = xc.get().getSource().getSrcIf();
113             name.replace("nmc", "mc");
114             interfList.add(xc.get().getSource().getSrcIf());
115             interfList.add(xc.get().getDestination().getDstIf());
116             interfList.add(xc.get().getSource().getSrcIf().replace("nmc", "mc"));
117             interfList.add(xc.get().getDestination().getDstIf().replace("nmc", "mc"));
118         } else {
119             LOG.warn("Cross connect does not exist, halting delete");
120             return null;
121         }
122         Future<Optional<DeviceTransaction>> deviceTxFuture = deviceTransactionManager.getDeviceTransaction(deviceId);
123         DeviceTransaction deviceTx;
124         try {
125             Optional<DeviceTransaction> deviceTxOpt = deviceTxFuture.get();
126             if (deviceTxOpt.isPresent()) {
127                 deviceTx = deviceTxOpt.get();
128             } else {
129                 LOG.error("Device transaction for device {} was not found!", deviceId);
130                 return null;
131             }
132         } catch (InterruptedException | ExecutionException e) {
133             LOG.error("Unable to obtain device transaction for device {}!", deviceId, e);
134             return null;
135         }
136
137         // post the cross connect on the device
138         deviceTx.delete(LogicalDatastoreType.CONFIGURATION, generateRdmConnectionIID(connectionName));
139         FluentFuture<? extends @NonNull CommitInfo> commit =
140                 deviceTx.commit(Timeouts.DEVICE_WRITE_TIMEOUT, Timeouts.DEVICE_WRITE_TIMEOUT_UNIT);
141         try {
142             commit.get();
143             LOG.info("Roadm connection {} successfully deleted on {}", connectionName, deviceId);
144             return interfList;
145         } catch (InterruptedException | ExecutionException e) {
146             LOG.warn("Failed to delete {}", connectionName, e);
147         }
148         return null;
149     }
150
151
152     public List<Ports> getConnectionPortTrail(String nodeId, Long waveNumber, String srcTp, String destTp)
153             throws OpenRoadmInterfaceException {
154         String connectionName = generateConnectionName(srcTp, destTp, waveNumber);
155         Optional<MountPoint> mountPointOpt = deviceTransactionManager.getDeviceMountPoint(nodeId);
156         List<Ports> ports = null;
157         MountPoint mountPoint;
158         if (mountPointOpt.isPresent()) {
159             mountPoint = mountPointOpt.get();
160         } else {
161             LOG.error("Failed to obtain mount point for device {}!", nodeId);
162             return Collections.emptyList();
163         }
164         final Optional<RpcConsumerRegistry> service = mountPoint.getService(RpcConsumerRegistry.class).toJavaUtil();
165         if (!service.isPresent()) {
166             LOG.error("Failed to get RpcService for node {}", nodeId);
167         }
168         final OrgOpenroadmDeviceService rpcService = service.get().getRpcService(OrgOpenroadmDeviceService.class);
169         final GetConnectionPortTrailInputBuilder portTrainInputBuilder = new GetConnectionPortTrailInputBuilder();
170         portTrainInputBuilder.setConnectionName(connectionName);
171         final Future<RpcResult<GetConnectionPortTrailOutput>> portTrailOutput = rpcService.getConnectionPortTrail(
172                 portTrainInputBuilder.build());
173         if (portTrailOutput != null) {
174             try {
175                 RpcResult<GetConnectionPortTrailOutput> connectionPortTrailOutputRpcResult = portTrailOutput.get();
176                 GetConnectionPortTrailOutput connectionPortTrailOutput = connectionPortTrailOutputRpcResult.getResult();
177                 if (connectionPortTrailOutput == null) {
178                     throw new OpenRoadmInterfaceException(String.format("RPC get connection port trail called on"
179                             + " node %s returned null!", nodeId));
180                 }
181                 LOG.info("Getting port trail for node {}'s connection number {}", nodeId, connectionName);
182                 ports = connectionPortTrailOutput.getPorts();
183                 for (Ports port : ports) {
184                     LOG.info("{} - Circuit pack {} - Port {}", nodeId, port.getCircuitPackName(), port.getPortName());
185                 }
186             } catch (InterruptedException | ExecutionException e) {
187                 LOG.warn("Exception caught", e);
188             }
189         } else {
190             LOG.warn("Port trail is null in getConnectionPortTrail for nodeId {}", nodeId);
191         }
192         return ports != null ? ports : Collections.emptyList();
193     }
194
195
196     public boolean setPowerLevel(String deviceId, Enum mode, BigDecimal powerValue, String connectionName) {
197         Optional<RoadmConnections> rdmConnOpt = getCrossConnect(deviceId, connectionName);
198         if (rdmConnOpt.isPresent()) {
199             RoadmConnectionsBuilder rdmConnBldr = new RoadmConnectionsBuilder(rdmConnOpt.get());
200             rdmConnBldr.setOpticalControlMode(OpticalControlMode.values()[mode.ordinal()]);
201             if (powerValue != null) {
202                 rdmConnBldr.setTargetOutputPower(new PowerDBm(powerValue));
203             }
204             RoadmConnections newRdmConn = rdmConnBldr.build();
205
206             Future<Optional<DeviceTransaction>> deviceTxFuture =
207                     deviceTransactionManager.getDeviceTransaction(deviceId);
208             DeviceTransaction deviceTx;
209             try {
210                 Optional<DeviceTransaction> deviceTxOpt = deviceTxFuture.get();
211                 if (deviceTxOpt.isPresent()) {
212                     deviceTx = deviceTxOpt.get();
213                 } else {
214                     LOG.error("Transaction for device {} was not found!", deviceId);
215                     return false;
216                 }
217             } catch (InterruptedException | ExecutionException e) {
218                 LOG.error("Unable to get transaction for device {}!", deviceId, e);
219                 return false;
220             }
221
222             // post the cross connect on the device
223             InstanceIdentifier<RoadmConnections> roadmConnIID = InstanceIdentifier.create(OrgOpenroadmDevice.class)
224                     .child(RoadmConnections.class, new RoadmConnectionsKey(connectionName));
225             deviceTx.put(LogicalDatastoreType.CONFIGURATION, roadmConnIID, newRdmConn);
226             FluentFuture<? extends @NonNull CommitInfo> commit =
227                 deviceTx.commit(Timeouts.DEVICE_WRITE_TIMEOUT, Timeouts.DEVICE_WRITE_TIMEOUT_UNIT);
228             try {
229                 commit.get();
230                 LOG.info("Roadm connection power level successfully set ");
231                 return true;
232             } catch (InterruptedException | ExecutionException ex) {
233                 LOG.warn("Failed to post {}", newRdmConn, ex);
234             }
235
236         } else {
237             LOG.warn("Roadm-Connection is null in set power level ({})", connectionName);
238         }
239         return false;
240     }
241
242     private InstanceIdentifier<RoadmConnections> generateRdmConnectionIID(String connectionNumber) {
243         return InstanceIdentifier.create(OrgOpenroadmDevice.class)
244                 .child(RoadmConnections.class, new RoadmConnectionsKey(connectionNumber));
245     }
246
247     private String generateConnectionName(String srcTp, String destTp, Long waveNumber) {
248         return srcTp + "-" + destTp + "-" + waveNumber;
249     }
250 }