ee4caacfc7c76fcc3aeea4e95e132ea52a63c462
[transportpce.git] / renderer / src / main / java / org / opendaylight / transportpce / renderer / provisiondevice / DeviceRenderer.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
9 package org.opendaylight.transportpce.renderer.provisiondevice;
10
11 import java.util.HashSet;
12 import java.util.List;
13 import java.util.Set;
14 import java.util.concurrent.Future;
15
16 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
17 import org.opendaylight.controller.md.sal.binding.api.MountPointService;
18 import org.opendaylight.transportpce.renderer.mapping.PortMapping;
19 import org.opendaylight.transportpce.renderer.openroadminterface.OpenRoadmInterfaces;
20 import org.opendaylight.transportpce.renderer.openroadminterface.OpenRoadmOchInterface;
21 import org.opendaylight.transportpce.renderer.openroadminterface.OpenRoadmXponderInterface;
22 import org.opendaylight.yang.gen.v1.http.org.openroadm.optical.channel.interfaces.rev161014.OchAttributes.ModulationFormat;
23 import org.opendaylight.yang.gen.v1.http.org.openroadm.optical.channel.interfaces.rev161014.R100G;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.renderer.rev170228.RendererService;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.renderer.rev170228.ServicePathInput;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.renderer.rev170228.ServicePathOutput;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.renderer.rev170228.ServicePathOutputBuilder;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.renderer.rev170228.service.path.input.Nodes;
29 import org.opendaylight.yangtools.yang.common.RpcResult;
30 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
31 import org.slf4j.Logger;
32 import org.slf4j.LoggerFactory;
33
34 public class DeviceRenderer implements RendererService {
35
36     private final DataBroker db;
37     private final MountPointService mps;
38     private static final Logger LOG = LoggerFactory.getLogger(RendererService.class);
39     private final Set<String> currentMountedDevice;
40     private final Set<String> nodesProvisioned;
41
42     public DeviceRenderer(DataBroker db, MountPointService mps, Set<String> currentMountedDevice) {
43         this.db = db;
44         this.mps = mps;
45         this.currentMountedDevice = currentMountedDevice;
46         this.nodesProvisioned = new HashSet<>();
47     }
48
49     /**
50      * This method is the implementation of the 'service-path' RESTCONF service,
51      * which is one of the external APIs into the renderer application. The service
52      * provides two functions:
53      *
54      * <p>
55      * 1. Create This operation results in provisioning the device for a given
56      * wavelength and a list of nodes with each node listing its termination points.
57      *
58      * <p>
59      * 2. Delete This operation results in de-provisioning the device for a given
60      * wavelength and a list of nodes with each node listing its termination points.
61      *
62      * <p>
63      * The signature for this method was generated by yang tools from the renderer
64      * API model.
65      *
66      * @param input
67      *            Input parameter from the service-path yang model
68      *
69      * @return Result of the request
70      */
71     @Override
72     public Future<RpcResult<ServicePathOutput>> servicePath(ServicePathInput input) {
73
74         if (input.getOperation().getIntValue() == 1) {
75             LOG.info("Create operation request received");
76             return RpcResultBuilder.success(setupServicePath(input)).buildFuture();
77         } else if (input.getOperation().getIntValue() == 2) {
78             LOG.info("Delete operation request received");
79             return RpcResultBuilder.success(deleteServicePath(input)).buildFuture();
80         }
81         return RpcResultBuilder.success(new ServicePathOutputBuilder().setResult("Invalid operation")).buildFuture();
82     }
83
84     /**
85      * This method set's wavelength path based on following steps: For each node:
86      *
87      * <p>
88      * 1. Create Och interface on source termination point. 2. Create Och interface
89      * on destination termination point. 3. Create cross connect between source and
90      * destination tps created in step 1 and 2.
91      *
92      * <p>
93      * Naming convention used for OCH interfaces name : tp-wavenumber Naming
94      * convention used for cross connect name : src-dest-wavenumber
95      *
96      * @param input
97      *            Input parameter from the service-path yang model
98      *
99      * @return Result list of all nodes if request successful otherwise specific
100      *         reason of failure.
101      */
102     public ServicePathOutputBuilder setupServicePath(ServicePathInput input) {
103
104         String serviceName = input.getServiceName();
105         List<Nodes> nodes = input.getNodes();
106         ServicePathOutputBuilder setServBldr = new ServicePathOutputBuilder();
107         LOG.info(currentMountedDevice.toString());
108         int crossConnectFlag;
109         for (Nodes n : nodes) {
110             LOG.info("Starting provisioning for node : " + n.getNodeId());
111             crossConnectFlag = 0;
112             String nodeId = n.getNodeId();
113             // if the node is currently mounted then proceed
114             if (currentMountedDevice.contains(n.getNodeId())) {
115                 String srcTp = n.getSrcTp();
116                 String destTp = n.getDestTp();
117
118                 Long waveNumber = input.getWaveNumber();
119                 String mf = input.getModulationFormat();
120                 if (destTp.contains("LINE")) {
121                     crossConnectFlag++;
122
123                     ModulationFormat modulationFormat = null;
124                     for (int i = 0; i < ModulationFormat.values().length; i++) {
125                         ModulationFormat smodulationFormat = ModulationFormat.forValue(i);
126                         if (smodulationFormat.getName().equals(mf)) {
127                             modulationFormat = smodulationFormat;
128                         }
129                     }
130                     try {
131                         LOG.info("Modulation Format {} configured exists.", modulationFormat.getName());
132                     } catch (NullPointerException e) {
133                         LOG.error(mf + " modulation format does not exist.");
134                     }
135
136                     if (!new OpenRoadmXponderInterface(db, mps, nodeId, destTp, serviceName)
137                             .createLineInterfaces(waveNumber, R100G.class, modulationFormat)) {
138
139                         return setServBldr.setResult("Unable to LINE interface on " + nodeId + " at " + destTp);
140                     }
141                     LOG.info("LINE interface created for node " + nodeId);
142                 }
143                 if (srcTp.contains("CLNT")) {
144                     crossConnectFlag++;
145                     if (!new OpenRoadmXponderInterface(db, mps, nodeId, srcTp, serviceName).createClientInterfaces()) {
146                         return setServBldr.setResult("Unable to Client interface on " + nodeId + " at " + srcTp);
147                     }
148                 }
149                 String srcIf;
150                 String dstIf;
151                 if (srcTp.contains("TTP") || srcTp.contains("PP")) {
152                     srcIf = new OpenRoadmOchInterface(db, mps, nodeId, srcTp, serviceName).createInterface(waveNumber);
153                     // if source interface creation was successful then proceed
154                     // otherwise return.
155                     if (srcIf == null) {
156                         LOG.warn("Unable to create OCH interface on " + nodeId + " at " + srcTp);
157                         return setServBldr.setResult("Unable to create OCH interface on " + nodeId + " at " + srcTp);
158                     }
159                 }
160                 if (destTp.contains("TTP") || destTp.contains("PP")) {
161                     dstIf = new OpenRoadmOchInterface(db, mps, nodeId, destTp, serviceName).createInterface(waveNumber);
162                     // if destination interface creation was successful then proceed
163                     // otherwise return.
164                     if (dstIf == null) {
165                         LOG.warn("Unable to create OCH interface on " + nodeId + " at " + destTp);
166                         return setServBldr.setResult("Unable to create OCH interface on " + nodeId + " at " + destTp);
167                     }
168                 }
169                 if (crossConnectFlag < 1) {
170                     LOG.info("Creating cross connect between source :" + srcTp + " destination " + destTp + " for node "
171                             + n.getNodeId());
172                     DataBroker netconfNodeDataBroker = PortMapping.getDeviceDataBroker(nodeId, mps);
173                     String crossConnectName = srcTp + "-" + destTp + "-" + waveNumber;
174                     CrossConnect roadmConnections = new CrossConnect(netconfNodeDataBroker);
175                     if (roadmConnections.postCrossConnect(waveNumber, srcTp, destTp)) {
176                         nodesProvisioned.add(nodeId);
177                         roadmConnections.getConnectionPortTrail(nodeId, mps, waveNumber, srcTp, destTp);
178                     } else {
179                         return setServBldr.setResult("Unable to post Roadm-connection for node " + nodeId);
180                     }
181                 }
182             } else {
183                 LOG.warn(nodeId + " is not mounted on the controller");
184                 return setServBldr.setResult(nodeId + " is not mounted on the controller");
185             }
186         }
187         return setServBldr.setResult("Roadm-connection successfully created for nodes " + nodesProvisioned.toString());
188     }
189
190     /**
191      * This method removes wavelength path based on following steps: For each node:
192      *
193      * <p>
194      * 1. Delete Cross connect between source and destination tps. 2. Delete Och
195      * interface on source termination point. 3. Delete Och interface on destination
196      * termination point.
197      *
198      * <p>
199      * Naming convention used for OCH interfaces name : tp-wavenumber Naming
200      * convention used for cross connect name : src-dest-wavenumber
201      *
202      * @param input
203      *            Input parameter from the service-path yang model
204      *
205      * @return Result result of the request.
206      */
207     public ServicePathOutputBuilder deleteServicePath(ServicePathInput input) {
208         List<Nodes> nodes = input.getNodes();
209         ServicePathOutputBuilder delServBldr = new ServicePathOutputBuilder();
210         LOG.info(currentMountedDevice.toString());
211         for (Nodes n : nodes) {
212
213             String nodeId = n.getNodeId();
214             LOG.info("Deleting service setup on node " + nodeId);
215             String srcTp = n.getSrcTp();
216             String destTp = n.getDestTp();
217             Long waveNumber = input.getWaveNumber();
218
219             // if the node is currently mounted then proceed.
220             if (currentMountedDevice.contains(nodeId)) {
221
222                 if (destTp.contains("LINE")) {
223                     if (new OpenRoadmInterfaces(db, mps, nodeId, destTp)
224                             .deleteInterface(destTp + "-ODU") == false) {
225                         LOG.error("Failed to delete interface " + destTp + "-ODU");
226                     }
227                     if (new OpenRoadmInterfaces(db, mps, nodeId, destTp)
228                             .deleteInterface(destTp + "-OTU") == false) {
229                         LOG.error("Failed to delete interface " + destTp + "-OTU");
230                     }
231                     if (new OpenRoadmInterfaces(db, mps, nodeId, destTp)
232                             .deleteInterface(destTp + "-" + waveNumber) == false) {
233                         LOG.error("Failed to delete interface " + destTp + "-" + waveNumber);
234                     }
235                 }
236                 if (srcTp.contains("CLNT")) {
237                     // Deleting interface on source termination point
238                     if (new OpenRoadmInterfaces(db, mps, nodeId, srcTp)
239                             .deleteInterface(srcTp + "-ETHERNET") == false) {
240                         LOG.error("Failed to delete Ethernet interface  on " + srcTp);
241                     }
242                     continue;
243                 }
244                 String connectionNumber = srcTp + "-" + destTp + "-" + waveNumber;
245                 CrossConnect roadmConnection = new CrossConnect(PortMapping.getDeviceDataBroker(nodeId, mps),
246                         connectionNumber);
247                 if (!roadmConnection.deleteCrossConnect()) {
248                     LOG.error("Failed to delete {} ", srcTp + "-" + destTp + "-" + waveNumber);
249                 }
250                 // Deleting interface on source termination point
251                 if (!new OpenRoadmInterfaces(db, mps, nodeId, srcTp)
252                         .deleteInterface(srcTp + "-" + waveNumber.toString())) {
253                     LOG.error("Failed to delete interface " + srcTp + "-" + waveNumber.toString());
254                 }
255
256                 // Deleting interface on destination termination point
257                 if (!new OpenRoadmInterfaces(db, mps, nodeId, destTp)
258                         .deleteInterface(destTp + "-" + waveNumber.toString())) {
259                     LOG.error("Failed to delete interface " + destTp + "-" + waveNumber.toString());
260                 }
261             } else {
262                 LOG.warn(nodeId + " is not mounted on the controller");
263                 return delServBldr.setResult(nodeId + " is not mounted on the controller");
264             }
265         }
266         return delServBldr.setResult("Request processed");
267     }
268 }