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