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.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.fixedflex.GridConstant;
27 import org.opendaylight.transportpce.common.fixedflex.SpectrumInformation;
28 import org.opendaylight.transportpce.common.openroadminterfaces.OpenRoadmInterfaceException;
29 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.types.rev181019.OpticalControlMode;
30 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.types.rev181019.PowerDBm;
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.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.OduConnectionBuilder;
40 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.org.openroadm.device.container.org.openroadm.device.OduConnectionKey;
41 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.org.openroadm.device.container.org.openroadm.device.RoadmConnections;
42 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.org.openroadm.device.container.org.openroadm.device.RoadmConnectionsBuilder;
43 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.org.openroadm.device.container.org.openroadm.device.RoadmConnectionsKey;
44 import org.opendaylight.yang.gen.v1.http.org.transportpce.common.types.rev201211.otn.renderer.input.Nodes;
45 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
46 import org.opendaylight.yangtools.yang.common.RpcResult;
47 import org.slf4j.Logger;
48 import org.slf4j.LoggerFactory;
50 public class CrossConnectImpl221 {
52 private static final Logger LOG = LoggerFactory.getLogger(CrossConnectImpl221.class);
53 private final DeviceTransactionManager deviceTransactionManager;
55 public CrossConnectImpl221(DeviceTransactionManager deviceTransactionManager) {
56 this.deviceTransactionManager = deviceTransactionManager;
59 public Optional<RoadmConnections> getCrossConnect(String deviceId, String connectionNumber) {
60 //TODO Change it to Operational later for real device
61 return deviceTransactionManager.getDataFromDevice(deviceId, LogicalDatastoreType.CONFIGURATION,
62 generateRdmConnectionIID(connectionNumber), Timeouts.DEVICE_READ_TIMEOUT,
63 Timeouts.DEVICE_READ_TIMEOUT_UNIT);
66 public Optional<org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.org.openroadm.device.container.org
67 .openroadm.device.OduConnection> getOtnCrossConnect(String deviceId, String connectionNumber) {
68 //TODO Change it to Operational later for real device
69 return deviceTransactionManager.getDataFromDevice(deviceId, LogicalDatastoreType.CONFIGURATION,
70 generateOduConnectionIID(connectionNumber), Timeouts.DEVICE_READ_TIMEOUT,
71 Timeouts.DEVICE_READ_TIMEOUT_UNIT);
74 public Optional<String> postCrossConnect(String deviceId, String srcTp, String destTp,
75 SpectrumInformation spectrumInformation) {
76 String connectionNumber = spectrumInformation.getIdentifierFromParams(srcTp, destTp);
77 RoadmConnectionsBuilder rdmConnBldr = new RoadmConnectionsBuilder()
78 .setConnectionName(connectionNumber)
79 .setOpticalControlMode(OpticalControlMode.Off)
80 .setSource(new SourceBuilder()
81 .setSrcIf(spectrumInformation.getIdentifierFromParams(srcTp,"nmc"))
83 .setDestination(new DestinationBuilder()
84 .setDstIf(spectrumInformation.getIdentifierFromParams(destTp,"nmc"))
87 InstanceIdentifier<RoadmConnections> rdmConnectionIID =
88 InstanceIdentifier.create(OrgOpenroadmDevice.class)
89 .child(RoadmConnections.class, new RoadmConnectionsKey(rdmConnBldr.getConnectionName()));
91 Future<Optional<DeviceTransaction>> deviceTxFuture = deviceTransactionManager.getDeviceTransaction(deviceId);
92 DeviceTransaction deviceTx;
94 Optional<DeviceTransaction> deviceTxOpt = deviceTxFuture.get();
95 if (deviceTxOpt.isPresent()) {
96 deviceTx = deviceTxOpt.get();
98 LOG.error("Device transaction for device {} was not found!", deviceId);
99 return Optional.empty();
101 } catch (InterruptedException | ExecutionException e) {
102 LOG.error("Unable to obtain device transaction for device {}!", deviceId, e);
103 return Optional.empty();
106 // post the cross connect on the device
107 deviceTx.merge(LogicalDatastoreType.CONFIGURATION, rdmConnectionIID, rdmConnBldr.build());
108 FluentFuture<? extends @NonNull CommitInfo> commit =
109 deviceTx.commit(Timeouts.DEVICE_WRITE_TIMEOUT, Timeouts.DEVICE_WRITE_TIMEOUT_UNIT);
112 LOG.info("Roadm-connection successfully created: {}-{}-{}-{}", srcTp, destTp,
113 spectrumInformation.getLowerSpectralSlotNumber(),
114 spectrumInformation.getHigherSpectralSlotNumber());
115 return Optional.of(connectionNumber);
116 } catch (InterruptedException | ExecutionException e) {
117 LOG.warn("Failed to post {}. Exception: ", rdmConnBldr.build(), e);
119 return Optional.empty();
123 public List<String> deleteCrossConnect(String deviceId, String connectionName, boolean isOtn) {
124 List<String> interfList = new ArrayList<>();
125 Optional<RoadmConnections> xc = getCrossConnect(deviceId, connectionName);
126 Optional<org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.org.openroadm.device.container.org
127 .openroadm.device.OduConnection> otnXc = getOtnCrossConnect(deviceId, connectionName);
128 //Check if cross connect exists before delete
129 if (xc.isPresent()) {
130 interfList.add(xc.get().getSource().getSrcIf());
131 interfList.add(xc.get().getDestination().getDstIf());
132 interfList.add(xc.get().getSource().getSrcIf().replace("nmc", "mc"));
133 interfList.add(xc.get().getDestination().getDstIf().replace("nmc", "mc"));
134 } else if (otnXc.isPresent()) {
135 interfList.add(otnXc.get().getSource().getSrcIf());
136 interfList.add(otnXc.get().getDestination().getDstIf());
138 LOG.warn("Cross connect {} does not exist, halting delete", connectionName);
141 Future<Optional<DeviceTransaction>> deviceTxFuture = deviceTransactionManager.getDeviceTransaction(deviceId);
142 DeviceTransaction deviceTx;
144 Optional<DeviceTransaction> deviceTxOpt = deviceTxFuture.get();
145 if (deviceTxOpt.isPresent()) {
146 deviceTx = deviceTxOpt.get();
148 LOG.error("Device transaction for device {} was not found!", deviceId);
151 } catch (InterruptedException | ExecutionException e) {
152 LOG.error("Unable to obtain device transaction for device {}!", deviceId, e);
156 // post the cross connect on the device
158 deviceTx.delete(LogicalDatastoreType.CONFIGURATION, generateOduConnectionIID(connectionName));
160 deviceTx.delete(LogicalDatastoreType.CONFIGURATION, generateRdmConnectionIID(connectionName));
162 FluentFuture<? extends @NonNull CommitInfo> commit =
163 deviceTx.commit(Timeouts.DEVICE_WRITE_TIMEOUT, Timeouts.DEVICE_WRITE_TIMEOUT_UNIT);
166 LOG.info("Connection {} successfully deleted on {}", connectionName, deviceId);
168 } catch (InterruptedException | ExecutionException e) {
169 LOG.warn("Failed to delete {}", connectionName, e);
175 public List<Ports> getConnectionPortTrail(String nodeId, String srcTp, String destTp,
176 int lowerSpectralSlotNumber, int higherSpectralSlotNumber)
177 throws OpenRoadmInterfaceException {
178 String spectralSlotName = String.join(GridConstant.SPECTRAL_SLOT_SEPARATOR,
179 String.valueOf(lowerSpectralSlotNumber),
180 String.valueOf(higherSpectralSlotNumber));
181 String connectionName = generateConnectionName(srcTp, destTp, spectralSlotName);
182 Optional<MountPoint> mountPointOpt = deviceTransactionManager.getDeviceMountPoint(nodeId);
183 List<Ports> ports = null;
184 MountPoint mountPoint;
185 if (mountPointOpt.isPresent()) {
186 mountPoint = mountPointOpt.get();
188 LOG.error("Failed to obtain mount point for device {}!", nodeId);
189 return Collections.emptyList();
191 final Optional<RpcConsumerRegistry> service = mountPoint.getService(RpcConsumerRegistry.class);
192 if (!service.isPresent()) {
193 LOG.error("Failed to get RpcService for node {}", nodeId);
195 final OrgOpenroadmDeviceService rpcService = service.get().getRpcService(OrgOpenroadmDeviceService.class);
196 final GetConnectionPortTrailInputBuilder portTrainInputBuilder = new GetConnectionPortTrailInputBuilder();
197 portTrainInputBuilder.setConnectionName(connectionName);
198 final Future<RpcResult<GetConnectionPortTrailOutput>> portTrailOutput = rpcService.getConnectionPortTrail(
199 portTrainInputBuilder.build());
200 if (portTrailOutput != null) {
202 RpcResult<GetConnectionPortTrailOutput> connectionPortTrailOutputRpcResult = portTrailOutput.get();
203 GetConnectionPortTrailOutput connectionPortTrailOutput = connectionPortTrailOutputRpcResult.getResult();
204 if (connectionPortTrailOutput == null) {
205 throw new OpenRoadmInterfaceException(String.format("RPC get connection port trail called on"
206 + " node %s returned null!", nodeId));
208 LOG.info("Getting port trail for node {}'s connection number {}", nodeId, connectionName);
209 ports = connectionPortTrailOutput.getPorts();
210 for (Ports port : ports) {
211 LOG.info("{} - Circuit pack {} - Port {}", nodeId, port.getCircuitPackName(), port.getPortName());
213 } catch (InterruptedException | ExecutionException e) {
214 LOG.warn("Exception caught", e);
217 LOG.warn("Port trail is null in getConnectionPortTrail for nodeId {}", nodeId);
219 return ports != null ? ports : Collections.emptyList();
223 public boolean setPowerLevel(String deviceId, OpticalControlMode mode, BigDecimal powerValue, String ctName) {
224 Optional<RoadmConnections> rdmConnOpt = getCrossConnect(deviceId, ctName);
225 if (rdmConnOpt.isPresent()) {
226 RoadmConnectionsBuilder rdmConnBldr = new RoadmConnectionsBuilder(rdmConnOpt.get());
227 rdmConnBldr.setOpticalControlMode(mode);
228 if (powerValue != null) {
229 rdmConnBldr.setTargetOutputPower(new PowerDBm(powerValue));
231 RoadmConnections newRdmConn = rdmConnBldr.build();
233 Future<Optional<DeviceTransaction>> deviceTxFuture =
234 deviceTransactionManager.getDeviceTransaction(deviceId);
235 DeviceTransaction deviceTx;
237 Optional<DeviceTransaction> deviceTxOpt = deviceTxFuture.get();
238 if (deviceTxOpt.isPresent()) {
239 deviceTx = deviceTxOpt.get();
241 LOG.error("Transaction for device {} was not found!", deviceId);
244 } catch (InterruptedException | ExecutionException e) {
245 LOG.error("Unable to get transaction for device {}!", deviceId, e);
249 // post the cross connect on the device
250 InstanceIdentifier<RoadmConnections> roadmConnIID = InstanceIdentifier.create(OrgOpenroadmDevice.class)
251 .child(RoadmConnections.class, new RoadmConnectionsKey(ctName));
252 deviceTx.merge(LogicalDatastoreType.CONFIGURATION, roadmConnIID, newRdmConn);
253 FluentFuture<? extends @NonNull CommitInfo> commit =
254 deviceTx.commit(Timeouts.DEVICE_WRITE_TIMEOUT, Timeouts.DEVICE_WRITE_TIMEOUT_UNIT);
257 LOG.info("Roadm connection power level successfully set ");
259 } catch (InterruptedException | ExecutionException ex) {
260 LOG.warn("Failed to post {}", newRdmConn, ex);
264 LOG.warn("Roadm-Connection is null in set power level ({})", ctName);
269 private InstanceIdentifier<RoadmConnections> generateRdmConnectionIID(String connectionNumber) {
270 return InstanceIdentifier.create(OrgOpenroadmDevice.class)
271 .child(RoadmConnections.class, new RoadmConnectionsKey(connectionNumber));
274 private InstanceIdentifier<org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.org.openroadm.device
275 .container.org.openroadm.device.OduConnection> generateOduConnectionIID(String connectionNumber) {
276 return InstanceIdentifier.create(OrgOpenroadmDevice.class).child(org.opendaylight.yang.gen.v1.http.org
277 .openroadm.device.rev181019.org.openroadm.device.container.org.openroadm.device.OduConnection.class,
278 new OduConnectionKey(connectionNumber));
281 private String generateConnectionName(String srcTp, String destTp, String spectralSlotName) {
282 return String.join(GridConstant.NAME_PARAMETERS_SEPARATOR,srcTp, destTp, spectralSlotName);
285 public Optional<String> postOtnCrossConnect(List<String> createdOduInterfaces, Nodes node) {
286 String deviceId = node.getNodeId();
287 String srcTp = createdOduInterfaces.get(0);
288 String dstTp = createdOduInterfaces.get(1);
289 OduConnectionBuilder oduConnectionBuilder = new OduConnectionBuilder()
290 .setConnectionName(srcTp + "-x-" + dstTp)
291 .setDestination(new org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.odu.connection
292 .DestinationBuilder().setDstIf(dstTp).build())
293 .setSource(new org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.odu.connection
294 .SourceBuilder().setSrcIf(srcTp).build())
295 .setDirection(Direction.Bidirectional);
297 InstanceIdentifier<org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.org.openroadm.device
298 .container.org.openroadm.device.OduConnection> oduConnectionIID =
299 InstanceIdentifier.create(OrgOpenroadmDevice.class)
300 .child(org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.org.openroadm.device
301 .container.org.openroadm.device.OduConnection.class,
302 new OduConnectionKey(oduConnectionBuilder.getConnectionName())
305 Future<Optional<DeviceTransaction>> deviceTxFuture = deviceTransactionManager.getDeviceTransaction(deviceId);
306 DeviceTransaction deviceTx;
308 Optional<DeviceTransaction> deviceTxOpt = deviceTxFuture.get();
309 if (deviceTxOpt.isPresent()) {
310 deviceTx = deviceTxOpt.get();
312 LOG.error("Device transaction for device {} was not found!", deviceId);
313 return Optional.empty();
315 } catch (InterruptedException | ExecutionException e) {
316 LOG.error("Unable to obtain device transaction for device {}!", deviceId, e);
317 return Optional.empty();
320 // post the cross connect on the device
321 deviceTx.merge(LogicalDatastoreType.CONFIGURATION, oduConnectionIID, oduConnectionBuilder.build());
322 FluentFuture<? extends @NonNull CommitInfo> commit =
323 deviceTx.commit(Timeouts.DEVICE_WRITE_TIMEOUT, Timeouts.DEVICE_WRITE_TIMEOUT_UNIT);
326 LOG.info("Otn-connection successfully created: {}-{}", srcTp, dstTp);
327 return Optional.of(srcTp + "-x-" + dstTp);
328 } catch (InterruptedException | ExecutionException e) {
329 LOG.warn("Failed to post {}.", oduConnectionBuilder.build(), e);
331 return Optional.empty();