Updates to Renderer
[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
52      * service 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
57      * points.
58      *
59      * <p>
60      * 2. Delete This operation results in de-provisioning the device for a
61      * given wavelength and a list of nodes with each node listing its
62      * termination points.
63      *
64      * <p>
65      * The signature for this method was generated by yang tools from the
66      * renderer API model.
67      *
68      * @param input
69      *            Input parameter from the service-path yang model
70      *
71      * @return Result of the request
72      */
73     @Override
74     public Future<RpcResult<ServicePathOutput>> servicePath(ServicePathInput input) {
75
76         if (input.getOperation().getIntValue() == 1) {
77             LOG.info("Create operation request received");
78             return RpcResultBuilder.success(setupServicePath(input)).buildFuture();
79         } else if (input.getOperation().getIntValue() == 2) {
80             LOG.info("Delete operation request received");
81             return RpcResultBuilder.success(deleteServicePath(input)).buildFuture();
82         }
83         return RpcResultBuilder.success(new ServicePathOutputBuilder().setResult("Invalid operation")).buildFuture();
84     }
85
86     /**
87      * This method set's wavelength path based on following steps: For each
88      * node:
89      *
90      * <p>
91      * 1. Create Och interface on source termination point. 2. Create Och
92      * interface on destination termination point. 3. Create cross connect
93      * between source and destination tps created in step 1 and 2.
94      *
95      * <p>
96      * Naming convention used for OCH interfaces name : tp-wavenumber Naming
97      * convention used for cross connect name : src-dest-wavenumber
98      *
99      * @param input
100      *            Input parameter from the service-path yang model
101      *
102      * @return Result list of all nodes if request successful otherwise specific
103      *         reason of failure.
104      */
105     public ServicePathOutputBuilder setupServicePath(ServicePathInput input) {
106
107         String serviceName = input.getServiceName();
108         List<Nodes> nodes = input.getNodes();
109         ServicePathOutputBuilder setServBldr = new ServicePathOutputBuilder();
110         LOG.info(currentMountedDevice.toString());
111         int crossConnectFlag;
112         for (Nodes n : nodes) {
113             LOG.info("Starting provisioning for node : " + n.getNodeId());
114             crossConnectFlag = 0;
115             String nodeId = n.getNodeId();
116             // if the node is currently mounted then proceed
117             if (currentMountedDevice.contains(n.getNodeId())) {
118                 String srcTp = n.getSrcTp();
119                 String destTp = n.getDestTp();
120
121                 Long waveNumber = input.getWaveNumber();
122                 if (destTp.contains("NETWORK")) {
123                     crossConnectFlag++;
124                     if (!new OpenRoadmXponderInterface(db, mps, nodeId, destTp, serviceName)
125                             .createLineInterfaces(waveNumber, R100G.class, ModulationFormat.Qpsk)) {
126
127                         return setServBldr.setResult("Unable to LINE interface on " + nodeId + " at " + destTp);
128                     }
129                 }
130                 if (srcTp.contains("CLIENT")) {
131                     crossConnectFlag++;
132                     if (!new OpenRoadmXponderInterface(db, mps, nodeId, srcTp, serviceName).createClientInterfaces()) {
133                         return setServBldr.setResult("Unable to Client interface on " + nodeId + " at " + srcTp);
134                     }
135                 }
136                 String srcIf;
137                 String dstIf;
138                 if (srcTp.contains("TTP") || srcTp.contains("PP")) {
139                     srcIf = new OpenRoadmOchInterface(db, mps, nodeId, srcTp, serviceName).createInterface(waveNumber);
140                     // if source interface creation was successful then proceed
141                     // otherwise return.
142                     if (srcIf == null) {
143                         LOG.warn("Unable to create OCH interface on " + nodeId + " at " + srcTp);
144                         return setServBldr.setResult("Unable to create OCH interface on " + nodeId + " at " + srcTp);
145                     }
146                 }
147                 if (destTp.contains("TTP") || destTp.contains("PP")) {
148                     dstIf = new OpenRoadmOchInterface(db, mps, nodeId, destTp, serviceName).createInterface(waveNumber);
149                     // if destination interface creation was successful then proceed
150                     // otherwise return.
151                     if (dstIf == null) {
152                         LOG.warn("Unable to create OCH interface on " + nodeId + " at " + destTp);
153                         return setServBldr.setResult("Unable to create OCH interface on " + nodeId + " at " + destTp);
154                     }
155                 }
156                 if (crossConnectFlag < 1) {
157                     LOG.info("Creating cross connect between source :" + srcTp + " destination " + destTp + " for node "
158                             + n.getNodeId());
159                     DataBroker netconfNodeDataBroker = PortMapping.getDeviceDataBroker(nodeId, mps);
160                     String crossConnectName = srcTp + "-" + destTp + "-" + waveNumber;
161                     CrossConnect roadmConnections = new CrossConnect(netconfNodeDataBroker);
162                     if (roadmConnections.postCrossConnect(waveNumber, srcTp, destTp) == true) {
163                         nodesProvisioned.add(nodeId);
164                         roadmConnections.getConnectionPortTrail(nodeId, mps, waveNumber, srcTp, destTp);
165                     } else {
166                         return setServBldr.setResult("Unable to post Roadm-connection for node " + nodeId);
167                     }
168                 }
169             } else {
170                 LOG.warn(nodeId + " is not mounted on the controller");
171                 return setServBldr.setResult(nodeId + " is not mounted on the controller");
172             }
173         }
174         return setServBldr.setResult("Roadm-connection successfully created for nodes " + nodesProvisioned.toString());
175     }
176
177
178     /**
179      * This method removes wavelength path based on following steps: For each
180      * node:
181      *
182      * <p>
183      * 1. Delete Cross connect between source and destination tps. 2. Delete Och
184      * interface on source termination point. 3. Delete Och interface on
185      * destination termination point.
186      *
187      * <p>
188      * Naming convention used for OCH interfaces name : tp-wavenumber Naming
189      * convention used for cross connect name : src-dest-wavenumber
190      *
191      * @param input
192      *            Input parameter from the service-path yang model
193      *
194      * @return Result result of the request.
195      */
196     public ServicePathOutputBuilder deleteServicePath(ServicePathInput input) {
197         List<Nodes> nodes = input.getNodes();
198         ServicePathOutputBuilder delServBldr = new ServicePathOutputBuilder();
199         LOG.info(currentMountedDevice.toString());
200         for (Nodes n : nodes) {
201
202             String nodeId = n.getNodeId();
203             LOG.info("Deleting service setup on node " + nodeId);
204             String srcTp = n.getSrcTp();
205             String destTp = n.getDestTp();
206             Long waveNumber = input.getWaveNumber();
207
208             // if the node is currently mounted then proceed.
209             if (currentMountedDevice.contains(nodeId)) {
210
211                 if (destTp.contains("NETWORK")) {
212                     if (new OpenRoadmInterfaces(db, mps, nodeId, destTp)
213                              .deleteInterface(destTp + "-ODU") == false) {
214                         LOG.error("Failed to delete interface " + destTp + "-ODU");
215                     }
216                     if (new OpenRoadmInterfaces(db, mps, nodeId, destTp)
217                              .deleteInterface(destTp + "-OTU") == false) {
218                         LOG.error("Failed to delete interface " + destTp + "-OTU");
219                     }
220                     if (new OpenRoadmInterfaces(db, mps, nodeId, destTp)
221                              .deleteInterface(destTp + "-" + waveNumber) == false) {
222                         LOG.error("Failed to delete interface " + destTp + "-" + waveNumber);
223                     }
224                 }
225                 if (srcTp.contains("CLIENT")) {
226                     // Deleting interface on source termination point
227                     if (new OpenRoadmInterfaces(db, mps, nodeId, srcTp)
228                             .deleteInterface(srcTp + "-ETHERNET") == false) {
229                         LOG.error("Failed to delete Ethernet interface  on " + srcTp);
230                     }
231                     continue;
232                 }
233                 String connectionNumber = srcTp + "-" + destTp + "-" + waveNumber;
234                 CrossConnect roadmConnection = new CrossConnect(PortMapping.getDeviceDataBroker(nodeId, mps),
235                         connectionNumber);
236                 if (!roadmConnection.deleteCrossConnect()) {
237                     LOG.error("Failed to delete {} ", srcTp + "-" + destTp + "-" + waveNumber);
238                 }
239                 // Deleting interface on source termination point
240                 if (new OpenRoadmInterfaces(db, mps, nodeId, srcTp)
241                         .deleteInterface(srcTp + "-" + waveNumber.toString()) == false) {
242                     LOG.error("Failed to delete interface " + srcTp + "-" + waveNumber.toString());
243                 }
244
245                 // Deleting interface on destination termination point
246                 if (new OpenRoadmInterfaces(db, mps, nodeId, destTp)
247                         .deleteInterface(destTp + "-" + waveNumber.toString()) == false) {
248                     LOG.error("Failed to delete interface " + destTp + "-" + waveNumber.toString());
249                 }
250             } else {
251                 LOG.warn(nodeId + " is not mounted on the controller");
252                 return delServBldr.setResult(nodeId + " is not mounted on the controller");
253             }
254         }
255         return delServBldr.setResult("Request processed");
256     }
257 }