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