Corrects various javadoc problems
[transportpce.git] / renderer / src / main / java / org / opendaylight / transportpce / renderer / mapping / PortMapping.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.mapping;
10
11 import com.google.common.base.Optional;
12 import com.google.common.util.concurrent.CheckedFuture;
13
14 import java.util.ArrayList;
15 import java.util.List;
16 import java.util.concurrent.ExecutionException;
17
18 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
19 import org.opendaylight.controller.md.sal.binding.api.MountPoint;
20 import org.opendaylight.controller.md.sal.binding.api.MountPointService;
21 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
22 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
23 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
24 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
25 import org.opendaylight.transportpce.renderer.openroadminterface.OpenRoadmInterfaces;
26 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.types.rev161014.NodeTypes;
27 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.circuit.pack.Ports;
28 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.circuit.pack.PortsKey;
29 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.circuit.packs.CircuitPacks;
30 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.circuit.packs.CircuitPacksKey;
31 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.degree.ConnectionPorts;
32 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.org.openroadm.device.container.OrgOpenroadmDevice;
33 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.org.openroadm.device.container.org.openroadm.device.Degree;
34 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.org.openroadm.device.container.org.openroadm.device.DegreeKey;
35 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.org.openroadm.device.container.org.openroadm.device.Info;
36 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.org.openroadm.device.container.org.openroadm.device.SharedRiskGroup;
37 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.org.openroadm.device.container.org.openroadm.device.SharedRiskGroupKey;
38 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.port.Interfaces;
39 import org.opendaylight.yang.gen.v1.http.org.openroadm.interfaces.rev161014.InterfaceType;
40 import org.opendaylight.yang.gen.v1.http.org.openroadm.interfaces.rev161014.OpenROADMOpticalMultiplex;
41 import org.opendaylight.yang.gen.v1.http.org.openroadm.interfaces.rev161014.OpticalTransport;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.network.topology.topology.topology.types.TopologyNetconf;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.portmapping.rev170228.Network;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.portmapping.rev170228.NetworkBuilder;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.portmapping.rev170228.network.Nodes;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.portmapping.rev170228.network.NodesBuilder;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.portmapping.rev170228.network.NodesKey;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.portmapping.rev170228.network.nodes.Mapping;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.portmapping.rev170228.network.nodes.MappingBuilder;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.portmapping.rev170228.network.nodes.MappingKey;
51 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
52 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
53 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
54 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
55 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
56 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
57 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
58 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
59 import org.slf4j.Logger;
60 import org.slf4j.LoggerFactory;
61
62 public class PortMapping {
63
64     private static final Logger LOG = LoggerFactory.getLogger(PortMapping.class);
65     private final DataBroker db;
66     private final MountPointService mps;
67     private final String nodeId;
68
69     public PortMapping(DataBroker db, MountPointService mps, String nodeId) {
70         this.db = db;
71         this.mps = mps;
72         this.nodeId = nodeId;
73
74     }
75
76     /**
77      * This method creates logical to physical port mapping for a given device.
78      * Instead of parsing all the circuit packs/ports in the device this methods
79      * does a selective read operation on degree/srg subtree to get circuit
80      * packs/ports that map to :
81      *
82      * <p>
83      * 1. DEGn-TTP-TX, DEGn-TTP-RX, DEGn-TTP-TXRX
84      *
85      * <p>
86      * 2. SRGn-PPp-TX, SRGn-PPp-RX, SRGn-PPp-TXRX
87      *
88      * <p>
89      * 3. LINEn
90      *
91      * <p>
92      * 4. CLNTn.
93      *
94      * <p>
95      * If the port is Mw it also store the OMS, OTS interface provisioned on the
96      * port. It skips the logical ports that are internal. If operation is
97      * successful the mapping gets stored in datastore corresponding to
98      * portmapping.yang data model.
99      *
100      * @return true/false based on status of operation
101      */
102     public boolean createMappingData() {
103
104         LOG.info("Create Mapping Data for node " + nodeId);
105         DataBroker deviceDb = getDeviceDataBroker(nodeId, mps);
106         List<Mapping> portMapList = new ArrayList<>();
107         Info deviceInfo;
108         Integer nodeType = 1;
109         if (deviceDb != null) {
110             deviceInfo = getDeviceInfo(deviceDb);
111             if (deviceInfo != null) {
112                 if (deviceInfo.getNodeType() == null) {
113                     LOG.info("Node type mandatory field is missing");
114                     return false;
115                 }
116                 nodeType = deviceInfo.getNodeType().getIntValue();
117                 // Create Mapping for Roadm Node
118                 if (nodeType == 1) {
119                     // Get TTP port mapping
120                     if (!createTtpPortMapping(deviceDb, deviceInfo, portMapList)) {
121                         // return false if mapping creation for TTP's failed
122                         LOG.info("Unable to create mapping for TTP's");
123                         return false;
124                     }
125
126                     // Get PP port mapping
127                     if (!createPpPortMapping(deviceDb, deviceInfo, portMapList)) {
128                         // return false if mapping creation for PP's failed
129                         LOG.info("Unable tp create mapping for PP's");
130                         return false;
131                     }
132                 }
133                 // Create Mapping for Xponder Node
134                 if (nodeType == 2) {
135                     if (!createXpdrPortMapping(deviceDb, deviceInfo, portMapList)) {
136                         LOG.info("Unable to create mapping for Xponder");
137                         return false;
138                     }
139                 }
140             } else {
141                 LOG.info("Device info subtree is absent for " + nodeId);
142                 return false;
143             }
144
145         } else {
146             LOG.info("Unable to get Data broker for node " + nodeId);
147             return false;
148         }
149         return postPortMapping(deviceInfo, portMapList, nodeType);
150     }
151
152     /**
153      * This private method gets the list of external ports on a degree. For each
154      * port in the degree, it does a get on port subtree with
155      * circuit-pack-name/port-name as key in order to get the logical connection
156      * point name corresponding to it.
157      *
158      * @param deviceDb
159      *            Reference to device's databroker
160      * @param deviceInfo
161      *            Info subtree read from the device
162      * @param portMapList
163      *            Reference to the list containing the mapping to be pushed to
164      *            MD-SAL
165      *
166      * @return true/false based on status of operation
167      */
168     private boolean createTtpPortMapping(DataBroker deviceDb, Info deviceInfo, List<Mapping> portMapList) {
169         // Creating mapping data for degree TTP's
170         List<ConnectionPorts> degreeConPorts = getDegreePorts(deviceDb, deviceInfo);
171
172         // Getting circuit-pack-name/port-name corresponding to TTP's
173         for (ConnectionPorts cp : degreeConPorts) {
174             String circuitPackName = cp.getCircuitPackName();
175             String portName = cp.getPortName().toString();
176             InstanceIdentifier<Ports> portIID = InstanceIdentifier.create(OrgOpenroadmDevice.class).child(
177                 CircuitPacks.class, new CircuitPacksKey(circuitPackName)).child(Ports.class, new PortsKey(portName));
178             try {
179                 LOG.info("Fetching logical Connection Point value for port " + portName + " at circuit pack "
180                     + circuitPackName);
181                 ReadOnlyTransaction rtx = deviceDb.newReadOnlyTransaction();
182                 Optional<Ports> portObject = rtx.read(LogicalDatastoreType.OPERATIONAL, portIID).get();
183                 if (portObject.isPresent()) {
184                     Ports port = portObject.get();
185                     if (port.getLogicalConnectionPoint() != null) {
186
187                         LOG.info("Logical Connection Point for " + circuitPackName + " " + portName + " is " + port
188                             .getLogicalConnectionPoint());
189                         portMapList.add(createMappingObject(port, circuitPackName, port.getLogicalConnectionPoint(),
190                             deviceDb));
191                     } else {
192
193                         LOG.warn("Logical Connection Point value missing for " + circuitPackName + " " + port
194                             .getPortName());
195                     }
196                 }
197             } catch (InterruptedException | ExecutionException ex) {
198                 LOG.warn("Read failed for Logical Connection Point value missing for " + circuitPackName + " "
199                     + portName,ex);
200                 return false;
201             }
202         }
203         return true;
204     }
205
206     /**
207      * This private method gets the list of circuit packs on an Srg. For each
208      * circuit pack on an Srg, it does a get on circuit-pack subtree with
209      * circuit-pack-name as key in order to get the list of ports. It then
210      * iterates over the list of ports to get ports with port-qual as
211      * roadm-external. It appends a TX,RX,TXRX to the logical connection point
212      * name based on the direction of the port.
213      *
214      * @param deviceDb
215      *            Reference to device's databroker
216      * @param deviceInfo
217      *            Info subtree read from the device
218      * @param portMapList
219      *            Reference to the list containing the mapping to be pushed to
220      *            MD-SAL
221      *
222      * @return true/false based on status of operation
223      */
224
225     private boolean createPpPortMapping(DataBroker deviceDb, Info deviceInfo, List<Mapping> portMapList) {
226         // Creating mapping data for degree PP's
227         List<org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.srg.CircuitPacks> srgCps = getSrgCps(
228             deviceDb, deviceInfo);
229
230         for (org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.srg.CircuitPacks cps : srgCps) {
231             String circuitPackName = cps.getCircuitPackName();
232             try {
233                 InstanceIdentifier<CircuitPacks> cpIID = InstanceIdentifier.create(OrgOpenroadmDevice.class).child(
234                     CircuitPacks.class, new CircuitPacksKey(circuitPackName));
235                 ReadOnlyTransaction rtx = deviceDb.newReadOnlyTransaction();
236                 Optional<CircuitPacks> circuitPackObject = rtx.read(LogicalDatastoreType.OPERATIONAL, cpIID).get();
237
238                 if (circuitPackObject.isPresent()) {
239                     CircuitPacks cp = circuitPackObject.get();
240                     if (!cp.getPorts().isEmpty()) {
241                         for (Ports port : cp.getPorts()) {
242
243                             if (port.getLogicalConnectionPoint() != null && port.getPortQual().getIntValue() == 2) {
244                                 String logicalConnectionPoint = null;
245                                 if (port.getPortDirection().getIntValue() == 1) {
246                                     // Port direction is transmit
247                                     logicalConnectionPoint = port.getLogicalConnectionPoint() + "-TX";
248                                 }
249                                 if (port.getPortDirection().getIntValue() == 2) {
250                                     // Port direction is receive
251                                     logicalConnectionPoint = port.getLogicalConnectionPoint() + "-RX";
252                                 }
253                                 if (port.getPortDirection().getIntValue() == 3) {
254                                     // port is bi-directional
255                                     logicalConnectionPoint = port.getLogicalConnectionPoint() + "-TXRX";
256                                 }
257
258                                 LOG.info("Logical Connection Point for " + circuitPackName + " " + port.getPortName()
259                                     + " is " + logicalConnectionPoint);
260
261                                 portMapList.add(createMappingObject(port, circuitPackName, logicalConnectionPoint,
262                                     deviceDb));
263
264                             } else if (port.getPortQual().getIntValue() == 1) {
265
266                                 LOG.info("Port is internal, skipping Logical Connection Point missing for "
267                                     + circuitPackName + " " + port.getPortName());
268
269                             } else if (port.getLogicalConnectionPoint() == null) {
270
271                                 LOG.info("Value missing, Skipping Logical Connection Point missing for "
272                                     + circuitPackName + " " + port.getPortName());
273                             }
274
275                         }
276
277                     }
278
279                 }
280             } catch (InterruptedException | ExecutionException ex) {
281                 LOG.warn("Read failed for " + circuitPackName,ex);
282                 return false;
283             }
284         }
285
286         return true;
287     }
288
289     /**
290      * This private method gets the list of circuit packs on a xponder. For each
291      * circuit pack on a Xponder, it does a get on circuit-pack subtree with
292      * circuit-pack-name as key in order to get the list of ports. It then
293      * iterates over the list of ports to get ports with port-qual as
294      * xpdr-network/xpdr-client. The line and client ports are saved as:
295      *
296      * <p>
297      * 1. LINEn
298      *
299      * <p>
300      * 2. CLNTn
301      *
302      * @param deviceDb
303      *            Reference to device's databroker
304      * @param deviceInfo
305      *            Info subtree read from the device
306      * @param portMapList
307      *            Reference to the list containing the mapping to be pushed to
308      *            MD-SAL
309      *
310      * @return true/false based on status of operation
311      */
312
313     private boolean createXpdrPortMapping(DataBroker deviceDb, Info deviceInfo, List<Mapping> portMapList) {
314         // Creating for Xponder Line and Client Ports
315         try {
316             InstanceIdentifier<OrgOpenroadmDevice> deviceIID = InstanceIdentifier.create(OrgOpenroadmDevice.class);
317             ReadOnlyTransaction rtx = deviceDb.newReadOnlyTransaction();
318             Optional<OrgOpenroadmDevice> deviceObject = rtx.read(LogicalDatastoreType.OPERATIONAL, deviceIID).get();
319
320             // Variable to keep track of number of line ports
321             int line = 1;
322             // Variable to keep track of number of client ports
323             int client = 1;
324             if (deviceObject.isPresent()) {
325                 for (CircuitPacks cp : deviceObject.get().getCircuitPacks()) {
326                     String circuitPackName = cp.getCircuitPackName();
327                     for (Ports port : cp.getPorts()) {
328                         if (port.getPortQual().getIntValue() == 3) {
329                             // Port is xpdr-network
330                             portMapList.add(createMappingObject(port, circuitPackName, "LINE" + line, deviceDb));
331                             line++;
332                         }
333                         if (port.getPortQual().getIntValue() == 4) {
334                             // port is xpdr-client
335                             portMapList.add(createMappingObject(port, circuitPackName, "CLNT" + client, deviceDb));
336                             client++;
337                         }
338                     }
339                 }
340             } else {
341                 LOG.info("Circuit Packs are not present for " + nodeId);
342                 return false;
343             }
344
345         } catch (InterruptedException | ExecutionException ex) {
346             LOG.warn("Read failed for CircuitPacks of " + nodeId,ex);
347             return false;
348         }
349         return true;
350     }
351
352     /**
353      * This private method builds the mapping object to be pushed in MD-SAL in
354      * order to save port mapping. In case of TTP ports, it also saves the
355      * OTS,OMS interfaces provisioned on the port.
356      *
357      * @param port
358      *            Reference to device's port subtree object.
359      * @param circuitPackName
360      *            Name of cp where port exists.
361      * @param logicalConnectionPoint
362      *            logical name of the port.
363      * @param deviceDb
364      *            Reference to device's databroker.
365      *
366      * @return true/false based on status of operation
367      */
368
369     private Mapping createMappingObject(Ports port, String circuitPackName, String logicalConnectionPoint,
370         DataBroker deviceDb) {
371         MappingBuilder mpBldr = new MappingBuilder();
372         mpBldr.setKey(new MappingKey(logicalConnectionPoint)).setLogicalConnectionPoint(logicalConnectionPoint)
373             .setSupportingCircuitPackName(circuitPackName).setSupportingPort(port.getPortName());
374
375         // Get OMS and OTS interface provisioned on the TTP's
376         if (logicalConnectionPoint.contains("TTP") && port.getInterfaces() != null) {
377             for (Interfaces interfaces : port.getInterfaces()) {
378                 Class<? extends InterfaceType> interfaceType = new OpenRoadmInterfaces(db, mps, nodeId,
379                     logicalConnectionPoint).getInterface(interfaces.getInterfaceName()).getType();
380                 // Check if interface type is OMS or OTS
381                 if (interfaceType.equals(OpenROADMOpticalMultiplex.class)) {
382                     String omsInterfaceName = interfaces.getInterfaceName();
383                     mpBldr.setSupportingOms(omsInterfaceName);
384                 }
385                 if (interfaceType.equals(OpticalTransport.class)) {
386                     String otsInterfaceName = interfaces.getInterfaceName();
387                     mpBldr.setSupportingOts(otsInterfaceName);
388                 }
389             }
390         }
391         return mpBldr.build();
392     }
393
394     /**
395      * This method does a get operation on info subtree of the netconf device's
396      * configuration datastore and returns info object.It is required to get
397      * device attributes such as maxDegrees,maxSrgs and node-type.
398      *
399      * @param deviceDb
400      *            Reference to device's databroker
401      * @return Info object
402      *
403      */
404     private Info getDeviceInfo(DataBroker deviceDb) {
405         ReadOnlyTransaction rtx = deviceDb.newReadOnlyTransaction();
406         InstanceIdentifier<Info> infoIID = InstanceIdentifier.create(OrgOpenroadmDevice.class).child(Info.class);
407         try {
408             Optional<Info> ordmInfoObject = rtx.read(LogicalDatastoreType.OPERATIONAL, infoIID).get();
409             if (ordmInfoObject.isPresent()) {
410                 LOG.info("Info subtree is present {}", ordmInfoObject.get());
411                 return ordmInfoObject.get();
412             } else {
413                 LOG.error("Info subtree is not present");
414             }
415         } catch (NullPointerException ex) {
416             LOG.warn("Try to get Info from a non Open ROADM device {}", deviceDb);
417             return null;
418         } catch (InterruptedException | ExecutionException ex) {
419             LOG.error("Read failed on info subtree ", ex);
420             return null;
421         }
422         return null;
423     }
424
425     /**
426      * This method does a get operation on degree subtree of the netconf
427      * device's config datastore and returns a list of all connection port
428      * objects. It is required for doing a selective get on ports that
429      * correspond to logical connection points of interest.
430      *
431      * @param deviceDb
432      *            Reference to device's databroker
433      * @param ordmInfo
434      *            Info subtree from the device
435      * @return List of connection ports object belonging to- degree subtree
436      */
437     private List<ConnectionPorts> getDegreePorts(DataBroker deviceDb, Info ordmInfo) {
438
439         List<ConnectionPorts> degreeConPorts = new ArrayList<>();
440         ReadOnlyTransaction rtx = deviceDb.newReadOnlyTransaction();
441         Integer maxDegree;
442
443         // Get value for max degree from info subtree, required for iteration
444         // if not present assume to be 20 (temporary)
445         if (ordmInfo.getMaxDegrees() != null) {
446             maxDegree = ordmInfo.getMaxDegrees();
447         } else {
448             maxDegree = 20;
449         }
450         Integer degreeCounter = 1;
451         while (degreeCounter <= maxDegree) {
452             LOG.info("Getting Connection ports for Degree Number " + degreeCounter);
453             InstanceIdentifier<Degree> deviceIID = InstanceIdentifier.create(OrgOpenroadmDevice.class).child(
454                 Degree.class, new DegreeKey(degreeCounter));
455             try {
456                 Optional<Degree> ordmDegreeObject = rtx.read(LogicalDatastoreType.CONFIGURATION, deviceIID).get();
457
458                 if (ordmDegreeObject.isPresent()) {
459                     degreeConPorts.addAll(new ArrayList<>(ordmDegreeObject.get().getConnectionPorts()));
460
461                 } else {
462                     LOG.info("Device has " + (degreeCounter - 1) + " degree");
463                     break;
464                 }
465             } catch (InterruptedException | ExecutionException ex) {
466                 LOG.error("Failed to read degree " + degreeCounter,ex);
467                 break;
468
469             }
470             degreeCounter++;
471         }
472         return degreeConPorts;
473     }
474
475     /**
476      * This method does a get operation on shared risk group subtree of the
477      * netconf device's config datastore and returns a list of all circuit packs
478      * objects that are part of srgs. It is required to do a selective get on
479      * all the circuit packs that contain add/drop ports of interest.
480      *
481      * @param deviceDb
482      *            Reference to device's databroker
483      * @param ordmInfo
484      *            Info subtree from the device
485      * @return List of circuit packs object belonging to- shared risk group
486      *         subtree
487      */
488
489     private List<org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.srg.CircuitPacks> getSrgCps(
490         DataBroker deviceDb, Info ordmInfo) {
491
492         List<org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.srg.CircuitPacks> srgCps =
493             new ArrayList<>();
494         ReadOnlyTransaction rtx = deviceDb.newReadOnlyTransaction();
495         Integer maxSrg;
496         // Get value for max Srg from info subtree, required for iteration
497         // if not present assume to be 20 (temporary)
498         if (ordmInfo.getMaxSrgs() != null) {
499             maxSrg = ordmInfo.getMaxSrgs();
500         } else {
501             maxSrg = 20;
502         }
503
504         Integer srgCounter = 1;
505         while (srgCounter <= maxSrg) {
506             LOG.info("Getting Circuitpacks for Srg Number " + srgCounter);
507             InstanceIdentifier<SharedRiskGroup> srgIID = InstanceIdentifier.create(OrgOpenroadmDevice.class).child(
508                 SharedRiskGroup.class, new SharedRiskGroupKey(srgCounter));
509             try {
510                 Optional<SharedRiskGroup> ordmSrgObject = rtx.read(LogicalDatastoreType.CONFIGURATION, srgIID).get();
511
512                 if (ordmSrgObject.isPresent()) {
513
514                     srgCps.addAll(
515                         new ArrayList<>(ordmSrgObject.get().getCircuitPacks()));
516
517                 } else {
518                     LOG.info("Device has " + (srgCounter - 1) + " Srg");
519                     break;
520                 }
521             } catch (InterruptedException | ExecutionException ex) {
522                 LOG.warn("Failed to read Srg " + srgCounter,ex);
523                 break;
524             }
525             srgCounter++;
526         }
527
528         return srgCps;
529     }
530
531     /**
532      * This method for ports the portMapping corresponding to the
533      * portmapping.yang file to the MD-SAL datastore.
534      *
535      * <p>
536      * 1. Supporting circuit pack 2. Supporting port 3. Supporting OMS interface
537      * (if port on ROADM)
538      *
539      * @param deviceInfo
540      *            Info subtree from the device.
541      * @param portMapList
542      *            Reference to the list containing the mapping to be pushed to
543      *            MD-SAL.
544      *
545      * @return Result true/false based on status of operation.
546      */
547     private boolean postPortMapping(Info deviceInfo, List<Mapping> portMapList, Integer nodeType) {
548
549         NodesBuilder nodesBldr = new NodesBuilder();
550         nodesBldr.setKey(new NodesKey(deviceInfo.getNodeId())).setNodeId(deviceInfo.getNodeId());
551         nodesBldr.setNodeType(NodeTypes.forValue(nodeType));
552         nodesBldr.setMapping(portMapList);
553         List<Nodes> nodesList = new ArrayList<>();
554         nodesList.add(nodesBldr.build());
555         NetworkBuilder nwBldr = new NetworkBuilder();
556         nwBldr.setNodes(nodesList);
557         final WriteTransaction writeTransaction = db.newWriteOnlyTransaction();
558         InstanceIdentifier<Network> nodesIID = InstanceIdentifier.builder(Network.class).build();
559         writeTransaction.merge(LogicalDatastoreType.CONFIGURATION, nodesIID, nwBldr.build());
560         CheckedFuture<Void, TransactionCommitFailedException> submit = writeTransaction.submit();
561         try {
562             submit.checkedGet();
563             return true;
564
565         } catch (TransactionCommitFailedException e) {
566             LOG.warn("Failed to post {} ", nwBldr.build(), e);
567             return false;
568
569         }
570     }
571
572     /**
573      * This method for a given node's termination point returns the Mapping
574      * object based on portmapping.yang model stored in the MD-SAL data store
575      * which is created when the node is connected for the first time. The
576      * mapping object basically contains the following attributes of interest:
577      *
578      * <p>
579      * 1. Supporting circuit pack
580      *
581      * <p>
582      * 2. Supporting port
583      *
584      * <p>
585      * 3. Supporting OMS interface (if port on ROADM) 4. Supporting OTS
586      * interface (if port on ROADM)
587      *
588      * @param nodeId
589      *            Unique Identifier for the node of interest.
590      * @param logicalConnPoint
591      *            Name of the logical point
592      * @param db
593      *            Databroker / MD-SAL data store
594      *
595      * @return Result Mapping object if success otherwise null.
596      */
597     public static Mapping getMapping(String nodeId, String logicalConnPoint, DataBroker db) {
598
599         /*
600          * Getting physical mapping corresponding to logical connection point
601          */
602         InstanceIdentifier<Mapping> portMapping = InstanceIdentifier.builder(Network.class).child(Nodes.class,
603             new NodesKey(nodeId)).child(Mapping.class, new MappingKey(logicalConnPoint)).build();
604         ReadOnlyTransaction readTx = db.newReadOnlyTransaction();
605         Optional<Mapping> mapObject;
606         try {
607             mapObject = readTx.read(LogicalDatastoreType.CONFIGURATION, portMapping).get();
608             if (mapObject.isPresent()) {
609                 LOG.info("Found mapping for the logical port " + mapObject.get().toString());
610                 return mapObject.get();
611             } else {
612                 LOG.info("Could not find mapping for logical connection point : " + logicalConnPoint + " for nodeId "
613                     + nodeId);
614                 return null;
615             }
616         } catch (InterruptedException | ExecutionException ex) {
617             LOG.error("Unable to read mapping for logical connection point : " + logicalConnPoint + " for nodeId "
618                 + nodeId,ex);
619         }
620         return null;
621     }
622
623     /**
624      * This static method returns the DataBroker for a netconf node.
625      *
626      * @param nodeId
627      *            Unique identifier for the mounted netconf- node
628      * @param mps
629      *            Reference to mount service
630      * @return Databroker for the given device
631      */
632     public static DataBroker getDeviceDataBroker(String nodeId, MountPointService mps) {
633         MountPoint netconfNode = getDeviceMountPoint(nodeId, mps);
634         if (netconfNode != null) {
635             DataBroker netconfNodeDataBroker = netconfNode.getService(DataBroker.class).get();
636             return netconfNodeDataBroker;
637         } else {
638             LOG.error("Device Data broker not found for :" + nodeId);
639             return null;
640         }
641     }
642
643     public static MountPoint getDeviceMountPoint(String nodeId, MountPointService mps) {
644         InstanceIdentifier<Node> netconfNodeIID = InstanceIdentifier.builder(NetworkTopology.class).child(
645             Topology.class, new TopologyKey(new TopologyId(TopologyNetconf.QNAME.getLocalName()))).child(Node.class,
646                 new NodeKey(new NodeId(nodeId))).build();
647
648         // Get mount point for specified device
649         final Optional<MountPoint> netconfNodeOptional = mps.getMountPoint(netconfNodeIID);
650         if (netconfNodeOptional.isPresent()) {
651             MountPoint netconfNode = netconfNodeOptional.get();
652             return netconfNode;
653         } else {
654             LOG.error("Mount Point not found for :" + nodeId);
655             return null;
656         }
657
658     }
659 }