Merge "Refactor ConvertORTopoToTapiTopoTest"
[transportpce.git] / common / src / main / java / org / opendaylight / transportpce / common / crossconnect / CrossConnectImpl121.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.rev161014.OpticalControlMode;
29 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.types.rev161014.PowerDBm;
30 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.GetConnectionPortTrail;
31 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.GetConnectionPortTrailInputBuilder;
32 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.GetConnectionPortTrailOutput;
33 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.OrgOpenroadmDeviceData;
34 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.connection.DestinationBuilder;
35 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.connection.SourceBuilder;
36 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.get.connection.port.trail.output.Ports;
37 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.org.openroadm.device.container.OrgOpenroadmDevice;
38 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.org.openroadm.device.container.org.openroadm.device.RoadmConnections;
39 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.org.openroadm.device.container.org.openroadm.device.RoadmConnectionsBuilder;
40 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.org.openroadm.device.container.org.openroadm.device.RoadmConnectionsKey;
41 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
42 import org.opendaylight.yangtools.yang.common.Decimal64;
43 import org.opendaylight.yangtools.yang.common.RpcResult;
44 import org.slf4j.Logger;
45 import org.slf4j.LoggerFactory;
46
47 public class CrossConnectImpl121 {
48     private static final Logger LOG = LoggerFactory.getLogger(CrossConnectImpl121.class);
49
50     private final DeviceTransactionManager deviceTransactionManager;
51
52     public CrossConnectImpl121(DeviceTransactionManager deviceTransactionManager) {
53         this.deviceTransactionManager = deviceTransactionManager;
54     }
55
56     public Optional<RoadmConnections> getCrossConnect(String deviceId, String connectionNumber) {
57         return deviceTransactionManager.getDataFromDevice(deviceId, LogicalDatastoreType.OPERATIONAL,
58                 generateRdmConnectionIID(connectionNumber), Timeouts.DEVICE_READ_TIMEOUT,
59                 Timeouts.DEVICE_READ_TIMEOUT_UNIT);
60     }
61
62     public Optional<String> postCrossConnect(
63             String deviceId, String srcTp, String destTp, SpectrumInformation spectrumInformation) {
64         Future<Optional<DeviceTransaction>> deviceTxFuture = deviceTransactionManager.getDeviceTransaction(deviceId);
65         DeviceTransaction deviceTx;
66         try {
67             Optional<DeviceTransaction> deviceTxOpt = deviceTxFuture.get();
68             if (deviceTxOpt.isEmpty()) {
69                 LOG.error("Device transaction for device {} was not found!", deviceId);
70                 return Optional.empty();
71             }
72             deviceTx = deviceTxOpt.orElseThrow();
73         } catch (InterruptedException | ExecutionException e) {
74             LOG.error("Unable to obtain device transaction for device {}!", deviceId, e);
75             return Optional.empty();
76         }
77         String connectionNumber = spectrumInformation.getIdentifierFromParams(srcTp, destTp);
78         RoadmConnections rdmConn = new RoadmConnectionsBuilder()
79             .setConnectionNumber(connectionNumber)
80             .setWavelengthNumber(spectrumInformation.getWaveLength())
81             .setOpticalControlMode(OpticalControlMode.Off)
82             .setSource(
83                 new SourceBuilder().setSrcIf(spectrumInformation.getIdentifierFromParams(srcTp)).build())
84             .setDestination(
85                 new DestinationBuilder().setDstIf(spectrumInformation.getIdentifierFromParams(destTp)).build())
86             .build();
87         // post the cross connect on the device
88         deviceTx.merge(
89             LogicalDatastoreType.CONFIGURATION,
90             InstanceIdentifier
91                 .builderOfInherited(OrgOpenroadmDeviceData.class, OrgOpenroadmDevice.class)
92                 .child(RoadmConnections.class, new RoadmConnectionsKey(connectionNumber))
93                 .build(),
94             rdmConn);
95         FluentFuture<? extends @NonNull CommitInfo> commit =
96                 deviceTx.commit(Timeouts.DEVICE_WRITE_TIMEOUT, Timeouts.DEVICE_WRITE_TIMEOUT_UNIT);
97         try {
98             commit.get();
99             LOG.info("Roadm-connection successfully created: {}-{}-{}-{}", srcTp, destTp,
100                     spectrumInformation.getLowerSpectralSlotNumber(),
101                     spectrumInformation.getHigherSpectralSlotNumber());
102             return Optional.of(connectionNumber);
103         } catch (InterruptedException | ExecutionException e) {
104             LOG.warn("Failed to post {}. Exception: ", rdmConn, e);
105         }
106         return Optional.empty();
107     }
108
109     public List<String> deleteCrossConnect(String deviceId, String connectionNumber) {
110         Optional<RoadmConnections> xc = getCrossConnect(deviceId, connectionNumber);
111         //Check if cross connect exists before delete
112         if (xc.isEmpty()) {
113             LOG.warn("Cross connect does not exist, halting delete");
114             return null;
115         }
116         Future<Optional<DeviceTransaction>> deviceTxFuture = deviceTransactionManager.getDeviceTransaction(deviceId);
117         DeviceTransaction deviceTx;
118         try {
119             Optional<DeviceTransaction> deviceTxOpt = deviceTxFuture.get();
120             if (deviceTxOpt.isEmpty()) {
121                 LOG.error("Device transaction for device {} was not found!", deviceId);
122                 return null;
123             }
124             deviceTx = deviceTxOpt.orElseThrow();
125         } catch (InterruptedException | ExecutionException e) {
126             LOG.error("Unable to obtain device transaction for device {}!", deviceId, e);
127             return null;
128         }
129         // post the cross connect on the device
130         deviceTx.delete(LogicalDatastoreType.CONFIGURATION, generateRdmConnectionIID(connectionNumber));
131         FluentFuture<? extends @NonNull CommitInfo> commit =
132                 deviceTx.commit(Timeouts.DEVICE_WRITE_TIMEOUT, Timeouts.DEVICE_WRITE_TIMEOUT_UNIT);
133         try {
134             commit.get();
135             LOG.info("Roadm connection successfully deleted ");
136             return new ArrayList<>(List.of(
137                 xc.orElseThrow().getSource().getSrcIf(),
138                 xc.orElseThrow().getDestination().getDstIf()));
139         } catch (InterruptedException | ExecutionException e) {
140             LOG.warn("Failed to delete {}", connectionNumber, e);
141         }
142         return null;
143     }
144
145
146     public List<Ports> getConnectionPortTrail(String nodeId, String srcTp, String destTp,
147             int lowerSpectralSlotNumber, int higherSpectralSlotNumber) throws OpenRoadmInterfaceException {
148         Optional<MountPoint> mountPointOpt = deviceTransactionManager.getDeviceMountPoint(nodeId);
149         if (mountPointOpt.isEmpty()) {
150             LOG.error("Failed to obtain mount point for device {}!", nodeId);
151             return Collections.emptyList();
152         }
153         String connectionName = generateConnectionNumber(srcTp, destTp,
154             String.join(GridConstant.SPECTRAL_SLOT_SEPARATOR,
155                 String.valueOf(lowerSpectralSlotNumber), String.valueOf(higherSpectralSlotNumber)));
156         MountPoint mountPoint = mountPointOpt.orElseThrow();
157         final Optional<RpcService> service = mountPoint.getService(RpcService.class);
158         if (service.isEmpty()) {
159             LOG.error("Failed to get RpcService for node {}", nodeId);
160         }
161         final GetConnectionPortTrail rpcService = service.orElseThrow().getRpc(GetConnectionPortTrail.class);
162         final Future<RpcResult<GetConnectionPortTrailOutput>> portTrailOutput = rpcService.invoke(
163                 new GetConnectionPortTrailInputBuilder().setConnectionNumber(connectionName).build());
164         if (portTrailOutput == null) {
165             LOG.warn("Port trail is null in getConnectionPortTrail for nodeId {}", nodeId);
166             return Collections.emptyList();
167         }
168         List<Ports> ports = null;
169         try {
170             RpcResult<GetConnectionPortTrailOutput> connectionPortTrailOutputRpcResult = portTrailOutput.get();
171             GetConnectionPortTrailOutput connectionPortTrailOutput = connectionPortTrailOutputRpcResult.getResult();
172             if (connectionPortTrailOutput == null) {
173                 throw new OpenRoadmInterfaceException(String.format(
174                     "RPC get connection port trail called on node %s returned null!", nodeId));
175             }
176             LOG.info("Getting port trail for node {}'s connection number {}", nodeId, connectionName);
177             ports = connectionPortTrailOutput.getPorts();
178             for (Ports port : ports) {
179                 LOG.info("{} - Circuit pack {} - Port {}", nodeId, port.getCircuitPackName(), port.getPortName());
180             }
181         } catch (InterruptedException | ExecutionException e) {
182             LOG.warn("Exception caught", e);
183         }
184         return ports != null ? ports : Collections.emptyList();
185     }
186
187     private InstanceIdentifier<RoadmConnections> generateRdmConnectionIID(String connectionNumber) {
188         return InstanceIdentifier.builderOfInherited(OrgOpenroadmDeviceData.class, OrgOpenroadmDevice.class)
189             .child(RoadmConnections.class, new RoadmConnectionsKey(connectionNumber))
190             .build();
191     }
192
193     private String generateConnectionNumber(String srcTp, String destTp, String spectralSlotName) {
194         return String.join(GridConstant.NAME_PARAMETERS_SEPARATOR, srcTp, destTp, spectralSlotName);
195     }
196
197     public boolean setPowerLevel(String deviceId, OpticalControlMode mode, Decimal64 powerValue, String ctNumber) {
198         Optional<RoadmConnections> rdmConnOpt = getCrossConnect(deviceId, ctNumber);
199         if (rdmConnOpt.isEmpty()) {
200             LOG.warn("Roadm-Connection is null in set power level ({})", ctNumber);
201             return false;
202         }
203         RoadmConnections newRdmConn =
204             powerValue == null
205                 ? new RoadmConnectionsBuilder(rdmConnOpt.orElseThrow())
206                     .setOpticalControlMode(mode)
207                     .build()
208                 : new RoadmConnectionsBuilder(rdmConnOpt.orElseThrow())
209                     .setOpticalControlMode(mode)
210                     .setTargetOutputPower(new PowerDBm(powerValue))
211                     .build();
212         Future<Optional<DeviceTransaction>> deviceTxFuture = deviceTransactionManager.getDeviceTransaction(deviceId);
213         DeviceTransaction deviceTx;
214         try {
215             Optional<DeviceTransaction> deviceTxOpt = deviceTxFuture.get();
216             if (deviceTxOpt.isEmpty()) {
217                 LOG.error("Transaction for device {} was not found!", deviceId);
218                 return false;
219             }
220             deviceTx = deviceTxOpt.orElseThrow();
221         } catch (InterruptedException | ExecutionException e) {
222             LOG.error("Unable to get transaction for device {}!", deviceId, e);
223             return false;
224         }
225         // post the cross connect on the device
226         deviceTx.merge(
227             LogicalDatastoreType.CONFIGURATION,
228             InstanceIdentifier
229                 .builderOfInherited(OrgOpenroadmDeviceData.class, OrgOpenroadmDevice.class)
230                 .child(RoadmConnections.class, new RoadmConnectionsKey(ctNumber))
231                 .build(),
232             newRdmConn);
233         FluentFuture<? extends @NonNull CommitInfo> commit =
234             deviceTx.commit(Timeouts.DEVICE_WRITE_TIMEOUT, Timeouts.DEVICE_WRITE_TIMEOUT_UNIT);
235         try {
236             commit.get();
237             LOG.info("Roadm connection power level successfully set ");
238             return true;
239         } catch (InterruptedException | ExecutionException ex) {
240             LOG.warn("Failed to post {}", newRdmConn, ex);
241         }
242         return false;
243     }
244 }