2 * Copyright © 2017 AT&T and others. All rights reserved.
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
8 package org.opendaylight.transportpce.common.crossconnect;
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.RpcConsumerRegistry;
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.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.OduConnection.Direction;
33 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.OrgOpenroadmDeviceData;
34 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.OrgOpenroadmDeviceService;
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.rev210930.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;
52 public class CrossConnectImpl221 {
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;
59 public CrossConnectImpl221(DeviceTransactionManager deviceTransactionManager) {
60 this.deviceTransactionManager = deviceTransactionManager;
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);
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);
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"))
87 .setDestination(new DestinationBuilder()
88 .setDstIf(spectrumInformation.getIdentifierFromParams(destTp,"nmc"))
91 InstanceIdentifier<RoadmConnections> rdmConnectionIID = InstanceIdentifier
92 .builderOfInherited(OrgOpenroadmDeviceData.class, OrgOpenroadmDevice.class)
93 .child(RoadmConnections.class, new RoadmConnectionsKey(rdmConnBldr.getConnectionName()))
96 Future<Optional<DeviceTransaction>> deviceTxFuture = deviceTransactionManager.getDeviceTransaction(deviceId);
97 DeviceTransaction deviceTx;
99 Optional<DeviceTransaction> deviceTxOpt = deviceTxFuture.get();
100 if (deviceTxOpt.isPresent()) {
101 deviceTx = deviceTxOpt.get();
103 LOG.error(DEV_TRANSACTION_NOT_FOUND, deviceId);
104 return Optional.empty();
106 } catch (InterruptedException | ExecutionException e) {
107 LOG.error(UNABLE_DEV_TRANSACTION, deviceId, e);
108 return Optional.empty();
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);
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);
124 return Optional.empty();
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.get().getSource().getSrcIf());
136 interfList.add(xc.get().getDestination().getDstIf());
137 interfList.add(xc.get().getSource().getSrcIf().replace("nmc", "mc"));
138 interfList.add(xc.get().getDestination().getDstIf().replace("nmc", "mc"));
139 } else if (otnXc.isPresent()) {
140 interfList.add(otnXc.get().getSource().getSrcIf());
141 interfList.add(otnXc.get().getDestination().getDstIf());
143 LOG.warn("Cross connect {} does not exist, halting delete", connectionName);
146 Future<Optional<DeviceTransaction>> deviceTxFuture = deviceTransactionManager.getDeviceTransaction(deviceId);
147 DeviceTransaction deviceTx;
149 Optional<DeviceTransaction> deviceTxOpt = deviceTxFuture.get();
150 if (deviceTxOpt.isPresent()) {
151 deviceTx = deviceTxOpt.get();
153 LOG.error(DEV_TRANSACTION_NOT_FOUND, deviceId);
156 } catch (InterruptedException | ExecutionException e) {
157 LOG.error(UNABLE_DEV_TRANSACTION, deviceId, e);
161 // post the cross connect on the device
163 deviceTx.delete(LogicalDatastoreType.CONFIGURATION, generateOduConnectionIID(connectionName));
165 deviceTx.delete(LogicalDatastoreType.CONFIGURATION, generateRdmConnectionIID(connectionName));
167 FluentFuture<? extends @NonNull CommitInfo> commit =
168 deviceTx.commit(Timeouts.DEVICE_WRITE_TIMEOUT, Timeouts.DEVICE_WRITE_TIMEOUT_UNIT);
171 LOG.info("Connection {} successfully deleted on {}", connectionName, deviceId);
173 } catch (InterruptedException | ExecutionException e) {
174 LOG.warn("Failed to delete {}", connectionName, e);
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.get();
193 LOG.error("Failed to obtain mount point for device {}!", nodeId);
194 return Collections.emptyList();
196 final Optional<RpcConsumerRegistry> service = mountPoint.getService(RpcConsumerRegistry.class);
197 if (!service.isPresent()) {
198 LOG.error("Failed to get RpcService for node {}", nodeId);
200 final OrgOpenroadmDeviceService rpcService = service.get().getRpcService(OrgOpenroadmDeviceService.class);
201 final GetConnectionPortTrailInputBuilder portTrainInputBuilder = new GetConnectionPortTrailInputBuilder();
202 portTrainInputBuilder.setConnectionName(connectionName);
203 final Future<RpcResult<GetConnectionPortTrailOutput>> portTrailOutput = rpcService.getConnectionPortTrail(
204 portTrainInputBuilder.build());
205 if (portTrailOutput != null) {
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));
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());
218 } catch (InterruptedException | ExecutionException e) {
219 LOG.warn("Exception caught", e);
222 LOG.warn("Port trail is null in getConnectionPortTrail for nodeId {}", nodeId);
224 return ports != null ? ports : Collections.emptyList();
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.get());
232 rdmConnBldr.setOpticalControlMode(mode);
233 if (powerValue != null) {
234 rdmConnBldr.setTargetOutputPower(new PowerDBm(powerValue));
236 RoadmConnections newRdmConn = rdmConnBldr.build();
238 Future<Optional<DeviceTransaction>> deviceTxFuture =
239 deviceTransactionManager.getDeviceTransaction(deviceId);
240 DeviceTransaction deviceTx;
242 Optional<DeviceTransaction> deviceTxOpt = deviceTxFuture.get();
243 if (deviceTxOpt.isPresent()) {
244 deviceTx = deviceTxOpt.get();
246 LOG.error("Transaction for device {} was not found!", deviceId);
249 } catch (InterruptedException | ExecutionException e) {
250 LOG.error("Unable to get transaction for device {}!", deviceId, e);
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))
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);
264 LOG.info("Roadm connection power level successfully set ");
266 } catch (InterruptedException | ExecutionException ex) {
267 LOG.warn("Failed to post {}", newRdmConn, ex);
271 LOG.warn("Roadm-Connection is null in set power level ({})", ctName);
276 private InstanceIdentifier<RoadmConnections> generateRdmConnectionIID(String connectionNumber) {
277 return InstanceIdentifier
278 .builderOfInherited(OrgOpenroadmDeviceData.class, OrgOpenroadmDevice.class)
279 .child(RoadmConnections.class, new RoadmConnectionsKey(connectionNumber))
283 private InstanceIdentifier<OduConnection> generateOduConnectionIID(String connectionNumber) {
284 return InstanceIdentifier
285 .builderOfInherited(OrgOpenroadmDeviceData.class, OrgOpenroadmDevice.class)
286 .child(OduConnection.class, new OduConnectionKey(connectionNumber))
290 private String generateConnectionName(String srcTp, String destTp, String spectralSlotName) {
291 return String.join(GridConstant.NAME_PARAMETERS_SEPARATOR,srcTp, destTp, spectralSlotName);
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 OduConnectionBuilder oduConnectionBuilder = new OduConnectionBuilder()
301 .setConnectionName(srcTp + "-x-" + dstTp)
302 .setDestination(new org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.odu.connection
303 .DestinationBuilder().setDstIf(dstTp).build())
304 .setSource(new org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.odu.connection
305 .SourceBuilder().setSrcIf(srcTp).build())
306 .setDirection(Direction.Bidirectional);
308 InstanceIdentifier<OduConnection> oduConnectionIID = InstanceIdentifier
309 .builderOfInherited(OrgOpenroadmDeviceData.class, OrgOpenroadmDevice.class)
310 .child(OduConnection.class, new OduConnectionKey(oduConnectionBuilder.getConnectionName()))
313 Future<Optional<DeviceTransaction>> deviceTxFuture = deviceTransactionManager.getDeviceTransaction(deviceId);
314 DeviceTransaction deviceTx;
316 Optional<DeviceTransaction> deviceTxOpt = deviceTxFuture.get();
317 if (deviceTxOpt.isPresent()) {
318 deviceTx = deviceTxOpt.get();
320 LOG.error(DEV_TRANSACTION_NOT_FOUND, deviceId);
321 return Optional.empty();
323 } catch (InterruptedException | ExecutionException e) {
324 LOG.error(UNABLE_DEV_TRANSACTION, deviceId, e);
325 return Optional.empty();
328 // post the cross connect on the device
329 deviceTx.merge(LogicalDatastoreType.CONFIGURATION, oduConnectionIID, oduConnectionBuilder.build());
330 FluentFuture<? extends @NonNull CommitInfo> commit =
331 deviceTx.commit(Timeouts.DEVICE_WRITE_TIMEOUT, Timeouts.DEVICE_WRITE_TIMEOUT_UNIT);
334 LOG.info("Otn-connection successfully created: {}-{}", srcTp, dstTp);
335 return Optional.of(srcTp + "-x-" + dstTp);
336 } catch (InterruptedException | ExecutionException e) {
337 LOG.warn("Failed to post {}.", oduConnectionBuilder.build(), e);
339 return Optional.empty();