e5fb17932148dd9b7d09bdbb225891a7f2ec128c
[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 com.google.common.util.concurrent.CheckedFuture;
12
13 import java.util.HashSet;
14 import java.util.List;
15 import java.util.Set;
16 import java.util.concurrent.Future;
17
18 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
19 import org.opendaylight.controller.md.sal.binding.api.MountPointService;
20 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
21 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
22 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
23 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
24 import org.opendaylight.transportpce.renderer.mapping.PortMapping;
25 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.types.rev161014.OpticalControlMode;
26 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev161014.connection.DestinationBuilder;
27 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev161014.connection.SourceBuilder;
28 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev161014.interfaces.grp.Interface;
29 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev161014.interfaces.grp.InterfaceKey;
30 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev161014.org.openroadm.device.container.OrgOpenroadmDevice;
31 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev161014.org.openroadm.device.container.org.openroadm.device.RoadmConnections;
32 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev161014.org.openroadm.device.container.org.openroadm.device.RoadmConnectionsBuilder;
33 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev161014.org.openroadm.device.container.org.openroadm.device.RoadmConnectionsKey;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.renderer.rev170228.RendererService;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.renderer.rev170228.ServicePathInput;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.renderer.rev170228.ServicePathOutput;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.renderer.rev170228.ServicePathOutputBuilder;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.renderer.rev170228.service.path.input.Nodes;
39 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
40 import org.opendaylight.yangtools.yang.common.RpcResult;
41 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
42 import org.slf4j.Logger;
43 import org.slf4j.LoggerFactory;
44
45 public class DeviceRenderer implements RendererService {
46
47     private final DataBroker db;
48     private final MountPointService mps;
49     private static final Logger LOG = LoggerFactory.getLogger(RendererService.class);
50     private final Set<String> currentMountedDevice;
51     private final Set<String> nodesProvisioned;
52
53     public DeviceRenderer(DataBroker db, MountPointService mps, Set<String> currentMountedDevice) {
54         this.db = db;
55         this.mps = mps;
56         this.currentMountedDevice = currentMountedDevice;
57         this.nodesProvisioned = new HashSet<>();
58     }
59
60     /**
61      * This method is the implementation of the 'service-path' RESTCONF service,
62      * which is one of the external APIs into the renderer application. The
63      * service provides two functions:
64      *
65      * <p>
66      * 1. Create
67      * This operation results in provisioning the device for a given wavelength and a
68      * list of nodes with each node listing its termination points.
69      *
70      * <p>
71      * 2. Delete
72      * This operation results in de-provisioning the device for a given wavelength and a
73      * list of nodes with each node listing its termination points.
74      *
75      * <p>
76      * The signature for this method was generated by yang tools from the
77      * renderer API model.
78      *
79      * @param input Input parameter from the service-path yang model
80      *
81      * @return Result of the request
82      */
83     @Override
84     public Future<RpcResult<ServicePathOutput>> servicePath(ServicePathInput input) {
85
86         if (input.getOperation().getIntValue() == 1) {
87             LOG.info("Create operation request received");
88             return RpcResultBuilder.success(setupServicePath(input)).buildFuture();
89         } else if (input.getOperation().getIntValue() == 2) {
90             LOG.info("Delete operation request received");
91             return RpcResultBuilder.success(deleteServicePath(input)).buildFuture();
92         }
93         return RpcResultBuilder.success(new ServicePathOutputBuilder().setResult("Invalid operation")).buildFuture();
94     }
95
96     /**
97      * This method set's wavelength path based on following steps:
98      * For each node:
99      *
100      * <p>
101      *  1. Create Och interface on source termination point.
102      *  2. Create Och interface on destination termination point.
103      *  3. Create cross connect between source and destination
104      *  tps created in step 1 and 2.
105      *
106      * <p>
107      * Naming convention used for OCH interfaces name : tp-wavenumber
108      * Naming convention used for cross connect name : src-dest-wavenumber
109      *
110      * @param input Input parameter from the service-path yang model
111      *
112      * @return Result list of all nodes if request successful
113      *         otherwise specific reason of failure.
114      */
115     public ServicePathOutputBuilder setupServicePath(ServicePathInput input) {
116
117         List<Nodes> nodes = input.getNodes();
118         ServicePathOutputBuilder setServBldr = new ServicePathOutputBuilder();
119         LOG.info(currentMountedDevice.toString());
120         for (Nodes n : nodes) {
121             LOG.info("Starting provisioning for node : " + n.getNodeId());
122             //if the node is currently mounted then proceed
123             if (currentMountedDevice.contains(n.getNodeId())) {
124                 String srcTp = n.getSrcTp();
125                 String destTp = n.getDestTp();
126                 Long waveNumber = input.getWaveNumber();
127                 String srcIf = new OpenRoadmInterfaces(db, mps, n.getNodeId(), srcTp).createOchInterface(waveNumber);
128                 //if source interface creation was successful then proceed otherwise return.
129                 if (srcIf == null) {
130                     LOG.warn("Unable to create OCH interface on " + n.getNodeId() + " at " + srcTp);
131                     return setServBldr.setResult("Unable to create OCH interface on " + n.getNodeId() + " at " + srcTp);
132                 }
133                 //if destination interface creation was then proceed otherwise return.
134                 String dstIf = new OpenRoadmInterfaces(db, mps, n.getNodeId(), destTp).createOchInterface(waveNumber);
135                 if (dstIf == null) {
136                     LOG.warn("Unable to create OCH interface on " + n.getNodeId() + " at " + destTp);
137                     return setServBldr.setResult("Unable to create OCH interface on " + n.getNodeId() + " at "
138                         + destTp);
139                 }
140                 LOG.info("Creating cross connect between source :" + srcTp + " destination " + destTp + " for node " + n
141                     .getNodeId());
142                 //Build cross connect object
143                 RoadmConnectionsBuilder rdmConnBldr = new RoadmConnectionsBuilder();
144                 rdmConnBldr.setConnectionNumber(srcTp + "-" + destTp + "-" + waveNumber);
145                 rdmConnBldr.setWavelengthNumber(waveNumber);
146                 rdmConnBldr.setOpticalControlMode(OpticalControlMode.Off);
147                 rdmConnBldr.setSource(new SourceBuilder().setSrcIf(srcIf).build());
148                 rdmConnBldr.setDestination(new DestinationBuilder().setDstIf(dstIf).build());
149                 InstanceIdentifier<RoadmConnections> rdmConnectionIID = InstanceIdentifier.create(
150                     OrgOpenroadmDevice.class).child(RoadmConnections.class, new RoadmConnectionsKey(rdmConnBldr
151                         .getConnectionNumber()));
152                 DataBroker netconfNodeDataBroker = PortMapping.getDeviceDataBroker(n.getNodeId(), mps);
153                 if (netconfNodeDataBroker != null) {
154                     final WriteTransaction writeTransaction = netconfNodeDataBroker.newWriteOnlyTransaction();
155                     //post the cross connect on the device
156                     writeTransaction.put(LogicalDatastoreType.CONFIGURATION, rdmConnectionIID, rdmConnBldr.build());
157                     final CheckedFuture<Void, TransactionCommitFailedException> submit = writeTransaction.submit();
158                     try {
159                         submit.checkedGet();
160                         nodesProvisioned.add(n.getNodeId());
161                         LOG.info("Roadm-connection successfully created: " + srcTp + "-" + destTp);
162
163                     } catch (TransactionCommitFailedException ex) {
164                         LOG.warn("Failed to post {} ", rdmConnBldr.build(), ex);
165                         return setServBldr.setResult("Unable to post Roadm-connection for node " + n.getNodeId());
166                     }
167                 } else {
168                     LOG.error("Unable to get device broker for node " + n.getNodeId());
169                     return setServBldr.setResult("Unable to get device broker for node " + n.getNodeId());
170                 }
171             } else {
172                 LOG.warn(n.getNodeId() + " is not mounted on the controller");
173                 return setServBldr.setResult(n.getNodeId() + " is not mounted on the controller");
174             }
175         }
176         return setServBldr.setResult("Roadm-connection successfully created for nodes " + nodesProvisioned.toString());
177     }
178
179     /**
180      * This method removes wavelength path based on following steps:
181      * For each node:
182      *
183      * <p>
184      *  1. Delete Cross connect between source and destination tps.
185      *  2. Delete Och interface on source termination point.
186      *  3. Delete Och interface on destination termination point.
187      *
188      *<p>
189      * Naming convention used for OCH interfaces name : tp-wavenumber
190      * Naming convention used for cross connect name : src-dest-wavenumber
191      *
192      * @param input 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             LOG.info("Deleting service setup on node " + n.getNodeId());
202             String srcTp = n.getSrcTp();
203             String destTp = n.getDestTp();
204             Long waveNumber = input.getWaveNumber();
205             //if the node is currently mounted then proceed.
206             if (currentMountedDevice.contains(n.getNodeId())) {
207                 DataBroker netconfNodeDataBroker = PortMapping.getDeviceDataBroker(n.getNodeId(), mps);
208                 if (netconfNodeDataBroker != null) {
209                     // Deleting roadm connection
210                     InstanceIdentifier<RoadmConnections> rdmConnectionIID = InstanceIdentifier.create(
211                         OrgOpenroadmDevice.class).child(RoadmConnections.class, new RoadmConnectionsKey(srcTp + "-"
212                             + destTp + "-" + waveNumber));
213                     ReadWriteTransaction writeTx = netconfNodeDataBroker.newReadWriteTransaction();
214                     writeTx.delete(LogicalDatastoreType.CONFIGURATION, rdmConnectionIID);
215                     final CheckedFuture<Void, TransactionCommitFailedException> submit = writeTx.submit();
216                     try {
217                         submit.checkedGet();
218                         LOG.info("Successfully deleted interface " + srcTp + "-" + destTp + "-" + waveNumber);
219
220                     } catch (TransactionCommitFailedException ex) {
221                         LOG.error("Failed to delete {} ", srcTp + "-" + destTp + "-" + waveNumber, ex);
222                     }
223                     // Deleting interface on source termination point
224                     writeTx = netconfNodeDataBroker.newReadWriteTransaction();
225                     InstanceIdentifier<Interface> srcInterfacesIID = InstanceIdentifier.create(OrgOpenroadmDevice.class)
226                         .child(Interface.class, new InterfaceKey(srcTp + "-" + waveNumber.toString()));
227                     writeTx.delete(LogicalDatastoreType.CONFIGURATION, srcInterfacesIID);
228                     final CheckedFuture<Void, TransactionCommitFailedException> submitSrcDel = writeTx.submit();
229
230                     try {
231                         submitSrcDel.checkedGet();
232                         LOG.info("Successfully deleted " + srcTp + "-" + waveNumber.toString());
233                     } catch (TransactionCommitFailedException ex) {
234                         LOG.error("Failed to delete interface {} ", srcTp + "-" + waveNumber.toString(), ex);
235                     }
236                     // Deleting interface on destination termination point
237                     writeTx = netconfNodeDataBroker.newReadWriteTransaction();
238                     InstanceIdentifier<Interface> destInterfacesIID = InstanceIdentifier.create(
239                         OrgOpenroadmDevice.class).child(Interface.class, new InterfaceKey(destTp + "-" + waveNumber
240                             .toString()));
241                     writeTx.delete(LogicalDatastoreType.CONFIGURATION, destInterfacesIID);
242                     final CheckedFuture<Void, TransactionCommitFailedException> submitDestDel = writeTx.submit();
243
244                     try {
245                         submitDestDel.checkedGet();
246                         LOG.info("Successfully deleted " + destTp + "-" + waveNumber.toString());
247
248                     } catch (TransactionCommitFailedException ex) {
249                         LOG.error("Failed to delete interface {} ", destTp + "-" + waveNumber.toString(), ex);
250                     }
251                 }
252             } else {
253                 LOG.warn(n.getNodeId() + " is not mounted on the controller");
254                 return delServBldr.setResult(n.getNodeId() + " is not mounted on the controller");
255             }
256         }
257         return delServBldr.setResult("Request processed");
258     }
259
260 }