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