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