52abeced10d6d0937e19c49bbbf12aedd49ed612
[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 import org.eclipse.jdt.annotation.NonNull;
19 import org.opendaylight.mdsal.binding.api.MountPoint;
20 import org.opendaylight.mdsal.binding.api.RpcConsumerRegistry;
21 import org.opendaylight.mdsal.common.api.CommitInfo;
22 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
23 import org.opendaylight.transportpce.common.Timeouts;
24 import org.opendaylight.transportpce.common.device.DeviceTransaction;
25 import org.opendaylight.transportpce.common.device.DeviceTransactionManager;
26 import org.opendaylight.transportpce.common.openroadminterfaces.OpenRoadmInterfaceException;
27 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.types.rev181019.OpticalControlMode;
28 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.types.rev181019.PowerDBm;
29 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.GetConnectionPortTrailInputBuilder;
30 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.GetConnectionPortTrailOutput;
31 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.OduConnection.Direction;
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.OduConnectionBuilder;
38 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.org.openroadm.device.container.org.openroadm.device.OduConnectionKey;
39 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.org.openroadm.device.container.org.openroadm.device.RoadmConnections;
40 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.org.openroadm.device.container.org.openroadm.device.RoadmConnectionsBuilder;
41 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.org.openroadm.device.container.org.openroadm.device.RoadmConnectionsKey;
42 import org.opendaylight.yang.gen.v1.http.org.transportpce.common.types.rev200128.otn.renderer.input.Nodes;
43 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
44 import org.opendaylight.yangtools.yang.common.RpcResult;
45 import org.slf4j.Logger;
46 import org.slf4j.LoggerFactory;
47
48 public class CrossConnectImpl221 {
49
50     private static final Logger LOG = LoggerFactory.getLogger(CrossConnectImpl221.class);
51     private final DeviceTransactionManager deviceTransactionManager;
52
53     public CrossConnectImpl221(DeviceTransactionManager deviceTransactionManager) {
54         this.deviceTransactionManager = deviceTransactionManager;
55     }
56
57     public Optional<RoadmConnections> getCrossConnect(String deviceId, String connectionNumber) {
58         //TODO Change it to Operational later for real device
59         return deviceTransactionManager.getDataFromDevice(deviceId, LogicalDatastoreType.CONFIGURATION,
60                 generateRdmConnectionIID(connectionNumber), Timeouts.DEVICE_READ_TIMEOUT,
61                 Timeouts.DEVICE_READ_TIMEOUT_UNIT);
62     }
63
64     public Optional<org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.org.openroadm.device.container.org
65         .openroadm.device.OduConnection> getOtnCrossConnect(String deviceId, String connectionNumber) {
66         //TODO Change it to Operational later for real device
67         return deviceTransactionManager.getDataFromDevice(deviceId, LogicalDatastoreType.CONFIGURATION,
68                 generateOduConnectionIID(connectionNumber), Timeouts.DEVICE_READ_TIMEOUT,
69                 Timeouts.DEVICE_READ_TIMEOUT_UNIT);
70     }
71
72     public Optional<String> postCrossConnect(String deviceId, Long waveNumber, String srcTp, String destTp) {
73         String connectionNumber = generateConnectionName(srcTp, destTp, waveNumber);
74         RoadmConnectionsBuilder rdmConnBldr = new RoadmConnectionsBuilder()
75                 .setConnectionName(connectionNumber)
76                 .setOpticalControlMode(OpticalControlMode.Off)
77                 .setSource(new SourceBuilder().setSrcIf(srcTp + "-nmc-" + waveNumber).build())
78                 .setDestination(new DestinationBuilder().setDstIf(destTp + "-nmc-" + waveNumber)
79                 .build());
80
81         InstanceIdentifier<RoadmConnections> rdmConnectionIID =
82                 InstanceIdentifier.create(OrgOpenroadmDevice.class)
83                     .child(RoadmConnections.class, new RoadmConnectionsKey(rdmConnBldr.getConnectionName()));
84
85         Future<Optional<DeviceTransaction>> deviceTxFuture = deviceTransactionManager.getDeviceTransaction(deviceId);
86         DeviceTransaction deviceTx;
87         try {
88             Optional<DeviceTransaction> deviceTxOpt = deviceTxFuture.get();
89             if (deviceTxOpt.isPresent()) {
90                 deviceTx = deviceTxOpt.get();
91             } else {
92                 LOG.error("Device transaction for device {} was not found!", deviceId);
93                 return Optional.empty();
94             }
95         } catch (InterruptedException | ExecutionException e) {
96             LOG.error("Unable to obtain device transaction for device {}!", deviceId, e);
97             return Optional.empty();
98         }
99
100         // post the cross connect on the device
101         deviceTx.put(LogicalDatastoreType.CONFIGURATION, rdmConnectionIID, rdmConnBldr.build());
102         FluentFuture<? extends @NonNull CommitInfo> commit =
103                 deviceTx.commit(Timeouts.DEVICE_WRITE_TIMEOUT, Timeouts.DEVICE_WRITE_TIMEOUT_UNIT);
104         try {
105             commit.get();
106             LOG.info("Roadm-connection successfully created: {}-{}-{}", srcTp, destTp, waveNumber);
107             return Optional.of(connectionNumber);
108         } catch (InterruptedException | ExecutionException e) {
109             LOG.warn("Failed to post {}. Exception: ", rdmConnBldr.build(), e);
110         }
111         return Optional.empty();
112     }
113
114
115     public List<String> deleteCrossConnect(String deviceId, String connectionName, boolean isOtn) {
116         List<String> interfList = new ArrayList<>();
117         Optional<RoadmConnections> xc = getCrossConnect(deviceId, connectionName);
118         Optional<org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.org.openroadm.device.container.org
119             .openroadm.device.OduConnection> otnXc = getOtnCrossConnect(deviceId, connectionName);
120         //Check if cross connect exists before delete
121         if (xc.isPresent()) {
122             interfList.add(xc.get().getSource().getSrcIf());
123             interfList.add(xc.get().getDestination().getDstIf());
124             interfList.add(xc.get().getSource().getSrcIf().replace("nmc", "mc"));
125             interfList.add(xc.get().getDestination().getDstIf().replace("nmc", "mc"));
126         } else if (otnXc.isPresent()) {
127             interfList.add(otnXc.get().getSource().getSrcIf());
128             interfList.add(otnXc.get().getDestination().getDstIf());
129         } else {
130             LOG.warn("Cross connect {} does not exist, halting delete", connectionName);
131             return null;
132         }
133         Future<Optional<DeviceTransaction>> deviceTxFuture = deviceTransactionManager.getDeviceTransaction(deviceId);
134         DeviceTransaction deviceTx;
135         try {
136             Optional<DeviceTransaction> deviceTxOpt = deviceTxFuture.get();
137             if (deviceTxOpt.isPresent()) {
138                 deviceTx = deviceTxOpt.get();
139             } else {
140                 LOG.error("Device transaction for device {} was not found!", deviceId);
141                 return null;
142             }
143         } catch (InterruptedException | ExecutionException e) {
144             LOG.error("Unable to obtain device transaction for device {}!", deviceId, e);
145             return null;
146         }
147
148         // post the cross connect on the device
149         if (isOtn) {
150             deviceTx.delete(LogicalDatastoreType.CONFIGURATION, generateOduConnectionIID(connectionName));
151         } else {
152             deviceTx.delete(LogicalDatastoreType.CONFIGURATION, generateRdmConnectionIID(connectionName));
153         }
154         FluentFuture<? extends @NonNull CommitInfo> commit =
155                 deviceTx.commit(Timeouts.DEVICE_WRITE_TIMEOUT, Timeouts.DEVICE_WRITE_TIMEOUT_UNIT);
156         try {
157             commit.get();
158             LOG.info("Connection {} successfully deleted on {}", connectionName, deviceId);
159             return interfList;
160         } catch (InterruptedException | ExecutionException e) {
161             LOG.warn("Failed to delete {}", connectionName, e);
162         }
163         return null;
164     }
165
166
167     public List<Ports> getConnectionPortTrail(String nodeId, Long waveNumber, String srcTp, String destTp)
168             throws OpenRoadmInterfaceException {
169         String connectionName = generateConnectionName(srcTp, destTp, waveNumber);
170         Optional<MountPoint> mountPointOpt = deviceTransactionManager.getDeviceMountPoint(nodeId);
171         List<Ports> ports = null;
172         MountPoint mountPoint;
173         if (mountPointOpt.isPresent()) {
174             mountPoint = mountPointOpt.get();
175         } else {
176             LOG.error("Failed to obtain mount point for device {}!", nodeId);
177             return Collections.emptyList();
178         }
179         final Optional<RpcConsumerRegistry> service = mountPoint.getService(RpcConsumerRegistry.class);
180         if (!service.isPresent()) {
181             LOG.error("Failed to get RpcService for node {}", nodeId);
182         }
183         final OrgOpenroadmDeviceService rpcService = service.get().getRpcService(OrgOpenroadmDeviceService.class);
184         final GetConnectionPortTrailInputBuilder portTrainInputBuilder = new GetConnectionPortTrailInputBuilder();
185         portTrainInputBuilder.setConnectionName(connectionName);
186         final Future<RpcResult<GetConnectionPortTrailOutput>> portTrailOutput = rpcService.getConnectionPortTrail(
187                 portTrainInputBuilder.build());
188         if (portTrailOutput != null) {
189             try {
190                 RpcResult<GetConnectionPortTrailOutput> connectionPortTrailOutputRpcResult = portTrailOutput.get();
191                 GetConnectionPortTrailOutput connectionPortTrailOutput = connectionPortTrailOutputRpcResult.getResult();
192                 if (connectionPortTrailOutput == null) {
193                     throw new OpenRoadmInterfaceException(String.format("RPC get connection port trail called on"
194                             + " node %s returned null!", nodeId));
195                 }
196                 LOG.info("Getting port trail for node {}'s connection number {}", nodeId, connectionName);
197                 ports = connectionPortTrailOutput.getPorts();
198                 for (Ports port : ports) {
199                     LOG.info("{} - Circuit pack {} - Port {}", nodeId, port.getCircuitPackName(), port.getPortName());
200                 }
201             } catch (InterruptedException | ExecutionException e) {
202                 LOG.warn("Exception caught", e);
203             }
204         } else {
205             LOG.warn("Port trail is null in getConnectionPortTrail for nodeId {}", nodeId);
206         }
207         return ports != null ? ports : Collections.emptyList();
208     }
209
210
211     public boolean setPowerLevel(String deviceId, OpticalControlMode mode, BigDecimal powerValue, String ctName) {
212         Optional<RoadmConnections> rdmConnOpt = getCrossConnect(deviceId, ctName);
213         if (rdmConnOpt.isPresent()) {
214             RoadmConnectionsBuilder rdmConnBldr = new RoadmConnectionsBuilder(rdmConnOpt.get());
215             rdmConnBldr.setOpticalControlMode(mode);
216             if (powerValue != null) {
217                 rdmConnBldr.setTargetOutputPower(new PowerDBm(powerValue));
218             }
219             RoadmConnections newRdmConn = rdmConnBldr.build();
220
221             Future<Optional<DeviceTransaction>> deviceTxFuture =
222                     deviceTransactionManager.getDeviceTransaction(deviceId);
223             DeviceTransaction deviceTx;
224             try {
225                 Optional<DeviceTransaction> deviceTxOpt = deviceTxFuture.get();
226                 if (deviceTxOpt.isPresent()) {
227                     deviceTx = deviceTxOpt.get();
228                 } else {
229                     LOG.error("Transaction for device {} was not found!", deviceId);
230                     return false;
231                 }
232             } catch (InterruptedException | ExecutionException e) {
233                 LOG.error("Unable to get transaction for device {}!", deviceId, e);
234                 return false;
235             }
236
237             // post the cross connect on the device
238             InstanceIdentifier<RoadmConnections> roadmConnIID = InstanceIdentifier.create(OrgOpenroadmDevice.class)
239                     .child(RoadmConnections.class, new RoadmConnectionsKey(ctName));
240             deviceTx.put(LogicalDatastoreType.CONFIGURATION, roadmConnIID, newRdmConn);
241             FluentFuture<? extends @NonNull CommitInfo> commit =
242                 deviceTx.commit(Timeouts.DEVICE_WRITE_TIMEOUT, Timeouts.DEVICE_WRITE_TIMEOUT_UNIT);
243             try {
244                 commit.get();
245                 LOG.info("Roadm connection power level successfully set ");
246                 return true;
247             } catch (InterruptedException | ExecutionException ex) {
248                 LOG.warn("Failed to post {}", newRdmConn, ex);
249             }
250
251         } else {
252             LOG.warn("Roadm-Connection is null in set power level ({})", ctName);
253         }
254         return false;
255     }
256
257     private InstanceIdentifier<RoadmConnections> generateRdmConnectionIID(String connectionNumber) {
258         return InstanceIdentifier.create(OrgOpenroadmDevice.class)
259                 .child(RoadmConnections.class, new RoadmConnectionsKey(connectionNumber));
260     }
261
262     private InstanceIdentifier<org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.org.openroadm.device
263         .container.org.openroadm.device.OduConnection> generateOduConnectionIID(String connectionNumber) {
264         return InstanceIdentifier.create(OrgOpenroadmDevice.class).child(org.opendaylight.yang.gen.v1.http.org
265             .openroadm.device.rev181019.org.openroadm.device.container.org.openroadm.device.OduConnection.class,
266             new OduConnectionKey(connectionNumber));
267     }
268
269     private String generateConnectionName(String srcTp, String destTp, Long waveNumber) {
270         return srcTp + "-" + destTp + "-" + waveNumber;
271     }
272
273     public Optional<String> postOtnCrossConnect(List<String> createdOduInterfaces, Nodes node) {
274         String deviceId = node.getNodeId();
275         String srcTp = createdOduInterfaces.get(0);
276         String dstTp = createdOduInterfaces.get(1);
277         OduConnectionBuilder oduConnectionBuilder = new OduConnectionBuilder()
278             .setConnectionName(srcTp + "-x-" + dstTp)
279             .setDestination(new org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.odu.connection
280                 .DestinationBuilder().setDstIf(dstTp).build())
281             .setSource(new org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.odu.connection
282                 .SourceBuilder().setSrcIf(srcTp).build())
283             .setDirection(Direction.Bidirectional);
284
285         InstanceIdentifier<org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.org.openroadm.device
286                 .container.org.openroadm.device.OduConnection> oduConnectionIID =
287             InstanceIdentifier.create(OrgOpenroadmDevice.class)
288                 .child(org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.org.openroadm.device
289                         .container.org.openroadm.device.OduConnection.class,
290                     new OduConnectionKey(oduConnectionBuilder.getConnectionName())
291                 );
292
293         Future<Optional<DeviceTransaction>> deviceTxFuture = deviceTransactionManager.getDeviceTransaction(deviceId);
294         DeviceTransaction deviceTx;
295         try {
296             Optional<DeviceTransaction> deviceTxOpt = deviceTxFuture.get();
297             if (deviceTxOpt.isPresent()) {
298                 deviceTx = deviceTxOpt.get();
299             } else {
300                 LOG.error("Device transaction for device {} was not found!", deviceId);
301                 return Optional.empty();
302             }
303         } catch (InterruptedException | ExecutionException e) {
304             LOG.error("Unable to obtain device transaction for device {}!", deviceId, e);
305             return Optional.empty();
306         }
307
308         // post the cross connect on the device
309         deviceTx.merge(LogicalDatastoreType.CONFIGURATION, oduConnectionIID, oduConnectionBuilder.build());
310         FluentFuture<? extends @NonNull CommitInfo> commit =
311                 deviceTx.commit(Timeouts.DEVICE_WRITE_TIMEOUT, Timeouts.DEVICE_WRITE_TIMEOUT_UNIT);
312         try {
313             commit.get();
314             LOG.info("Otn-connection successfully created: {}-{}", srcTp, dstTp);
315             return Optional.of(srcTp + "-x-" + dstTp);
316         } catch (InterruptedException | ExecutionException e) {
317             LOG.warn("Failed to post {}.", oduConnectionBuilder.build(), e);
318         }
319         return Optional.empty();
320     }
321 }