Bug corrections in topo and portmapping modules
[transportpce.git] / common / src / main / java / org / opendaylight / transportpce / common / mapping / PortMappingImpl.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.common.mapping;
10
11 import com.google.common.util.concurrent.CheckedFuture;
12
13 import java.util.ArrayList;
14 import java.util.Comparator;
15 import java.util.HashMap;
16 import java.util.List;
17 import java.util.Map;
18 import java.util.Map.Entry;
19 import java.util.Optional;
20 import java.util.Set;
21 import java.util.concurrent.ExecutionException;
22 import java.util.concurrent.TimeUnit;
23 import java.util.concurrent.TimeoutException;
24 import java.util.stream.Collectors;
25
26 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
27 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
28 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
29 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
30 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
31 import org.opendaylight.transportpce.common.Timeouts;
32 import org.opendaylight.transportpce.common.device.DeviceTransactionManager;
33 import org.opendaylight.transportpce.common.openroadminterfaces.OpenRoadmInterfaceException;
34 import org.opendaylight.transportpce.common.openroadminterfaces.OpenRoadmInterfaces;
35 import org.opendaylight.transportpce.common.openroadminterfaces.OpenRoadmInterfacesImpl;
36 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.types.rev161014.NodeTypes;
37 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.CircuitPack;
38 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.Port;
39 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.circuit.pack.Ports;
40 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.circuit.pack.PortsKey;
41 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.circuit.packs.CircuitPacks;
42 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.circuit.packs.CircuitPacksKey;
43 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.degree.ConnectionPorts;
44 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.interfaces.grp.Interface;
45 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.org.openroadm.device.container.OrgOpenroadmDevice;
46 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.org.openroadm.device.container.org.openroadm.device.Degree;
47 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.org.openroadm.device.container.org.openroadm.device.DegreeKey;
48 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.org.openroadm.device.container.org.openroadm.device.Info;
49 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.org.openroadm.device.container.org.openroadm.device.SharedRiskGroup;
50 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.org.openroadm.device.container.org.openroadm.device.SharedRiskGroupKey;
51 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.port.Interfaces;
52 import org.opendaylight.yang.gen.v1.http.org.openroadm.interfaces.rev161014.InterfaceType;
53 import org.opendaylight.yang.gen.v1.http.org.openroadm.interfaces.rev161014.OpenROADMOpticalMultiplex;
54 import org.opendaylight.yang.gen.v1.http.org.openroadm.interfaces.rev161014.OpticalTransport;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.portmapping.rev170228.Network;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.portmapping.rev170228.NetworkBuilder;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.portmapping.rev170228.network.Nodes;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.portmapping.rev170228.network.NodesBuilder;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.portmapping.rev170228.network.NodesKey;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.portmapping.rev170228.network.nodes.CpToDegree;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.portmapping.rev170228.network.nodes.CpToDegreeBuilder;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.portmapping.rev170228.network.nodes.CpToDegreeKey;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.portmapping.rev170228.network.nodes.Mapping;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.portmapping.rev170228.network.nodes.MappingBuilder;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.portmapping.rev170228.network.nodes.MappingKey;
66 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
67 import org.slf4j.Logger;
68 import org.slf4j.LoggerFactory;
69
70 public class PortMappingImpl implements PortMapping {
71
72     private static final Logger LOG = LoggerFactory.getLogger(PortMappingImpl.class);
73
74     private final DataBroker dataBroker;
75     private final DeviceTransactionManager deviceTransactionManager;
76     private final OpenRoadmInterfaces openRoadmInterfaces;
77
78     public PortMappingImpl(DataBroker dataBroker, DeviceTransactionManager deviceTransactionManager,
79         OpenRoadmInterfaces openRoadmInterfaces) {
80         this.dataBroker = dataBroker;
81         this.deviceTransactionManager = deviceTransactionManager;
82         this.openRoadmInterfaces = openRoadmInterfaces;
83     }
84
85     @Override
86     public boolean createMappingData(String nodeId) {
87
88         LOG.info("Create Mapping Data for node {}", nodeId);
89         List<Mapping> portMapList = new ArrayList<>();
90         InstanceIdentifier<Info> infoIID = InstanceIdentifier.create(OrgOpenroadmDevice.class).child(Info.class);
91         Optional<Info> deviceInfoOptional = this.deviceTransactionManager.getDataFromDevice(nodeId,
92             LogicalDatastoreType.OPERATIONAL, infoIID,
93             Timeouts.DEVICE_READ_TIMEOUT, Timeouts.DEVICE_READ_TIMEOUT_UNIT);
94
95         Info deviceInfo;
96         if (deviceInfoOptional.isPresent()) {
97             deviceInfo = deviceInfoOptional.get();
98         } else {
99             LOG.warn("Device info subtree is absent for {}", nodeId);
100             return false;
101         }
102         if (deviceInfo.getNodeType() == null) {
103             LOG.error("Node type field is missing"); // TODO make mandatory in yang
104             return false;
105         }
106         switch (deviceInfo.getNodeType()) {
107
108             case Rdm:
109                 // Get TTP port mapping
110                 if (!createTtpPortMapping(nodeId, deviceInfo, portMapList)) {
111                     // return false if mapping creation for TTP's failed
112                     LOG.warn("Unable to create mapping for TTP's on node {}", nodeId);
113                     return false;
114                 }
115
116                 // Get PP port mapping
117                 if (!createPpPortMapping(nodeId, deviceInfo, portMapList)) {
118                     // return false if mapping creation for PP's failed
119                     LOG.warn("Unable to create mapping for PP's on node {}", nodeId);
120                     return false;
121                 }
122                 break;
123             case Xpdr:
124                 if (!createXpdrPortMapping(nodeId, portMapList)) {
125                     LOG.warn("Unable to create mapping for Xponder on node {}", nodeId);
126                     return false;
127                 }
128                 break;
129             default:
130                 LOG.error("Unable to create mapping for node {} : unknown nodetype ", nodeId);
131                 break;
132
133         }
134         return postPortMapping(deviceInfo, portMapList, deviceInfo.getNodeType().getIntValue(), null);
135     }
136
137     /**
138      * This private method gets the list of external ports on a degree. For each
139      * port in the degree, it does a get on port subtree with
140      * circuit-pack-name/port-name as key in order to get the logical connection
141      * point name corresponding to it.
142      *
143      * @param deviceInfo
144      *            Info subtree read from the device
145      * @param portMapList
146      *            Reference to the list containing the mapping to be pushed to
147      *            MD-SAL
148      *
149      * @return true/false based on status of operation
150      */
151     private boolean createTtpPortMapping(String nodeId, Info deviceInfo, List<Mapping> portMapList) {
152         // Creating mapping data for degree TTP's
153
154         List<Degree> degrees = getDegrees(nodeId, deviceInfo);
155         List<ConnectionPorts> degreeConPorts = getDegreePorts(degrees);
156         List<CpToDegree> cpToDegreeList = getCpToDegreeList(degrees);
157
158         postPortMapping(deviceInfo, null, deviceInfo.getNodeType().getIntValue(), cpToDegreeList);
159
160         // Getting circuit-pack-name/port-name corresponding to TTP's
161         for (ConnectionPorts cp : degreeConPorts) {
162             String circuitPackName = cp.getCircuitPackName();
163             String portName = cp.getPortName().toString();
164             InstanceIdentifier<Ports> portIID = InstanceIdentifier.create(OrgOpenroadmDevice.class)
165                 .child(CircuitPacks.class, new CircuitPacksKey(circuitPackName))
166                 .child(Ports.class, new PortsKey(portName));
167
168             LOG.info("Fetching logical Connection Point value for port {} at circuit pack {}", portName,
169                 circuitPackName);
170             Optional<Ports> portObject = this.deviceTransactionManager.getDataFromDevice(nodeId,
171                 LogicalDatastoreType.OPERATIONAL, portIID,
172                 Timeouts.DEVICE_READ_TIMEOUT, Timeouts.DEVICE_READ_TIMEOUT_UNIT);
173             if (portObject.isPresent()) {
174                 Ports port = portObject.get();
175                 if (port.getLogicalConnectionPoint() != null) {
176                     LOG.info("Logical Connection Point for {} {} is {}", circuitPackName, portName,
177                         port.getLogicalConnectionPoint());
178                     portMapList.add(createMappingObject(nodeId, port, circuitPackName,
179                         port.getLogicalConnectionPoint()));
180                 } else {
181                     LOG.warn("Logical Connection Point value is missing for {} {}", circuitPackName,
182                         port.getPortName());
183                 }
184             } else {
185                 LOG.warn("Port {} is not present in node {} in circuit pack {}!", portName, nodeId, circuitPackName);
186                 continue; // TODO continue or return true?
187             }
188         }
189         return true;
190     }
191
192     private List<Degree> getDegrees(String deviceId, Info ordmInfo) {
193         List<Degree> degrees = new ArrayList<>();
194         Integer maxDegree;
195
196         // Get value for max degree from info subtree, required for iteration
197         // if not present assume to be 20 (temporary)
198         if (ordmInfo.getMaxDegrees() != null) {
199             maxDegree = ordmInfo.getMaxDegrees();
200         } else {
201             maxDegree = 20;
202         }
203
204         for (int degreeCounter = 1; degreeCounter <= maxDegree; degreeCounter++) {
205             LOG.info("Getting Connection ports for Degree Number {}", degreeCounter);
206             InstanceIdentifier<Degree> deviceIID = InstanceIdentifier.create(OrgOpenroadmDevice.class)
207                 .child(Degree.class, new DegreeKey(degreeCounter));
208             Optional<Degree> ordmDegreeObject = this.deviceTransactionManager.getDataFromDevice(deviceId,
209                 LogicalDatastoreType.CONFIGURATION,
210                 deviceIID, Timeouts.DEVICE_READ_TIMEOUT, Timeouts.DEVICE_READ_TIMEOUT_UNIT);
211             if (ordmDegreeObject.isPresent()) {
212                 degrees.add(ordmDegreeObject.get());
213             } else {
214                 LOG.info("Device has {} degree", degreeCounter - 1);
215                 break;
216             }
217         }
218         return degrees;
219     }
220
221     /**
222      * This private method gets the list of circuit packs on an Srg. For each
223      * circuit pack on an Srg, it does a get on circuit-pack subtree with
224      * circuit-pack-name as key in order to get the list of ports. It then
225      * iterates over the list of ports to get ports with port-qual as
226      * roadm-external. It appends a TX,RX,TXRX to the logical connection point
227      * name based on the direction of the port.
228      *
229      * @param nodeId
230      *            Id of device
231      * @param deviceInfo
232      *            Info subtree read from the device
233      * @param portMapList
234      *            Reference to the list containing the mapping to be pushed to
235      *            MD-SAL
236      *
237      * @return true/false based on status of operation
238      */
239
240     private boolean createPpPortMapping(String nodeId, Info deviceInfo, List<Mapping> portMapList) {
241         // Creating mapping data for SRG's PP
242         HashMap<Integer, List<org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.srg
243             .CircuitPacks>> srgCps = getSrgCps(nodeId, deviceInfo);
244         Set<Map.Entry<Integer, List<org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206
245             .srg.CircuitPacks>>> circuitPacks = srgCps.entrySet();
246         for (Entry<Integer, List<org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.srg
247                 .CircuitPacks>> entry : circuitPacks) {
248             Integer srgIndex = entry.getKey();
249             for (org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.srg.CircuitPacks cp : entry
250                 .getValue()) {
251                 String circuitPackName = cp.getCircuitPackName();
252                 InstanceIdentifier<CircuitPacks> cpIID = InstanceIdentifier.create(OrgOpenroadmDevice.class)
253                     .child(CircuitPacks.class, new CircuitPacksKey(circuitPackName));
254                 Optional<CircuitPacks> circuitPackObject = this.deviceTransactionManager.getDataFromDevice(nodeId,
255                     LogicalDatastoreType.OPERATIONAL, cpIID,
256                     Timeouts.DEVICE_READ_TIMEOUT, Timeouts.DEVICE_READ_TIMEOUT_UNIT);
257
258                 if (!circuitPackObject.isPresent() || (circuitPackObject.get().getPorts() == null)) {
259                     LOG.warn("{} : Circuit pack {} not found or without ports.", nodeId, circuitPackName);
260                     continue; // TODO continue or return false?
261                 }
262                 CircuitPacks circuitPack = circuitPackObject.get();
263                 for (Ports port : circuitPack.getPorts()) {
264                     if (port.getLogicalConnectionPoint() != null) {
265                         String logicalConnectionPoint = getLogicalConnectionPort(port, srgIndex);
266                         LOG.info("{} : Logical Connection Point for {} {} is {}", nodeId, circuitPackName, port
267                             .getPortName(),
268                             logicalConnectionPoint);
269                         portMapList.add(createMappingObject(nodeId, port, circuitPackName, logicalConnectionPoint));
270                     } else if (Port.PortQual.RoadmInternal.equals(port.getPortQual())) {
271                         LOG.info("Port is internal, skipping Logical Connection Point missing for {} {}",
272                             circuitPackName,
273                             port.getPortName());
274                     } else if (port.getLogicalConnectionPoint() == null) {
275                         LOG.info("Value missing, Skipping Logical Connection Point missing for {} {}", circuitPackName,
276                             port.getPortName());
277                     }
278                 }
279             }
280         }
281         return true;
282     }
283
284     /**
285      * This method does a get operation on shared risk group subtree of the
286      * netconf device's config datastore and returns a list of all circuit packs
287      * objects that are part of srgs. It is required to do a selective get on
288      * all the circuit packs that contain add/drop ports of interest.
289      *
290      * @param deviceId
291      *            Device id
292      * @param ordmInfo
293      *            Info subtree from the device
294      * @return List of circuit packs object belonging to- shared risk group
295      *         subtree
296      */
297     private HashMap<Integer, List<org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.srg
298         .CircuitPacks>> getSrgCps(String deviceId, Info ordmInfo) {
299         HashMap<Integer, List<org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.srg
300             .CircuitPacks>> cpPerSrg = new HashMap<>();
301         Integer maxSrg;
302         // Get value for max Srg from info subtree, required for iteration
303         // if not present assume to be 20 (temporary)
304         if (ordmInfo.getMaxSrgs() != null) {
305             maxSrg = ordmInfo.getMaxSrgs();
306         } else {
307             maxSrg = 20;
308         }
309         for (int srgCounter = 1; srgCounter <= maxSrg; srgCounter++) {
310             List<org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.srg.CircuitPacks> srgCps =
311                 new ArrayList<>();
312             LOG.info("Getting Circuitpacks for Srg Number {}", srgCounter);
313             InstanceIdentifier<SharedRiskGroup> srgIID = InstanceIdentifier.create(OrgOpenroadmDevice.class)
314                 .child(SharedRiskGroup.class, new SharedRiskGroupKey(srgCounter));
315             Optional<SharedRiskGroup> ordmSrgObject = this.deviceTransactionManager.getDataFromDevice(deviceId,
316                 LogicalDatastoreType.CONFIGURATION,
317                 srgIID, Timeouts.DEVICE_READ_TIMEOUT, Timeouts.DEVICE_READ_TIMEOUT_UNIT);
318             if (ordmSrgObject.isPresent()) {
319                 srgCps.addAll(ordmSrgObject.get().getCircuitPacks());
320                 cpPerSrg.put(ordmSrgObject.get().getSrgNumber(), srgCps);
321             }
322         }
323         LOG.info("Device {} has {} Srg", deviceId, cpPerSrg.size());
324         return cpPerSrg;
325     }
326
327     /**
328      * This private method gets the list of circuit packs on a xponder. For each
329      * circuit pack on a Xponder, it does a get on circuit-pack subtree with
330      * circuit-pack-name as key in order to get the list of ports. It then
331      * iterates over the list of ports to get ports with port-qual as
332      * xpdr-network/xpdr-client. The line and client ports are saved as:
333      *
334      * <p>
335      * 1. LINEn
336      *
337      * <p>
338      * 2. CLNTn
339      *
340      * @param nodeId
341      *            Id of device
342      * @param portMapList
343      *            Reference to the list containing the mapping to be pushed to
344      *            MD-SAL
345      *
346      * @return true/false based on status of operation
347      */
348     private boolean createXpdrPortMapping(String nodeId, List<Mapping> portMapList) {
349         // Creating for Xponder Line and Client Ports
350         InstanceIdentifier<OrgOpenroadmDevice> deviceIID = InstanceIdentifier.create(OrgOpenroadmDevice.class);
351         Optional<OrgOpenroadmDevice> deviceObject = this.deviceTransactionManager.getDataFromDevice(nodeId,
352             LogicalDatastoreType.OPERATIONAL, deviceIID,
353             Timeouts.DEVICE_READ_TIMEOUT, Timeouts.DEVICE_READ_TIMEOUT_UNIT);
354
355         // Variable to keep track of number of line ports
356         int line = 1;
357         // Variable to keep track of number of client ports
358         int client = 1;
359         if (!deviceObject.isPresent() || (deviceObject.get().getCircuitPacks() == null)) {
360             LOG.warn("Circuit Packs are not present for {}", nodeId);
361             return false; // TODO return false or continue?
362         }
363
364         List<CircuitPacks> circuitPackList = deviceObject.get().getCircuitPacks();
365         circuitPackList.sort(Comparator.comparing(CircuitPack::getCircuitPackName));
366
367         for (CircuitPacks cp : circuitPackList) {
368             String circuitPackName = cp.getCircuitPackName();
369             if (cp.getPorts() == null) {
370                 LOG.warn("Ports were not found for circuit pack: {}", circuitPackName);
371                 continue;
372             }
373             for (Ports port : cp.getPorts()) {
374                 if (Port.PortQual.XpdrNetwork.equals(port.getPortQual())) {
375                     portMapList.add(createMappingObject(nodeId, port, circuitPackName,
376                         OpenRoadmInterfacesImpl.NETWORK_TOKEN + line));
377                     line++;
378                 } else if (Port.PortQual.XpdrClient.equals(port.getPortQual())) {
379                     portMapList.add(createMappingObject(nodeId, port, circuitPackName,
380                         OpenRoadmInterfacesImpl.CLIENT_TOKEN + client));
381                     client++;
382                 } else {
383                     LOG.warn("Not supported type of port! Port type: {}", port.getPortQual());
384                 }
385             }
386         }
387         return true;
388     }
389
390     /**
391      * This private method builds the mapping object to be pushed in MD-SAL in
392      * order to save port mapping. In case of TTP ports, it also saves the
393      * OTS,OMS interfaces provisioned on the port.
394      *
395      * @param port
396      *            Reference to device's port subtree object.
397      * @param circuitPackName
398      *            Name of cp where port exists.
399      * @param logicalConnectionPoint
400      *            logical name of the port.
401      *
402      * @return true/false based on status of operation
403      */
404
405     private Mapping createMappingObject(String nodeId, Ports port, String circuitPackName,
406         String logicalConnectionPoint) {
407         MappingBuilder mpBldr = new MappingBuilder();
408         mpBldr.setKey(new MappingKey(logicalConnectionPoint)).setLogicalConnectionPoint(logicalConnectionPoint)
409             .setSupportingCircuitPackName(circuitPackName).setSupportingPort(port.getPortName());
410
411         // Get OMS and OTS interface provisioned on the TTP's
412         if (logicalConnectionPoint.contains(OpenRoadmInterfacesImpl.TTP_TOKEN) && (port.getInterfaces() != null)) {
413             for (Interfaces interfaces : port.getInterfaces()) {
414                 try {
415                     Optional<Interface> openRoadmInterface = this.openRoadmInterfaces.getInterface(nodeId,
416                         interfaces.getInterfaceName());
417                     if (openRoadmInterface.isPresent()) {
418                         Class<? extends InterfaceType> interfaceType = openRoadmInterface.get().getType();
419                         // Check if interface type is OMS or OTS
420                         if (interfaceType.equals(OpenROADMOpticalMultiplex.class)) {
421                             mpBldr.setSupportingOms(interfaces.getInterfaceName());
422                         }
423                         if (interfaceType.equals(OpticalTransport.class)) {
424                             mpBldr.setSupportingOts(interfaces.getInterfaceName());
425                         }
426                     } else {
427                         LOG.warn("Interface {} from node {} was null!", interfaces.getInterfaceName(), nodeId);
428                     }
429                 } catch (OpenRoadmInterfaceException ex) {
430                     LOG.warn("Error while getting interface {} from node {}!", interfaces.getInterfaceName(), nodeId,
431                         ex);
432                 }
433             }
434         }
435         return mpBldr.build();
436     }
437
438     private static CpToDegree createCpToDegreeObject(String circuitPackName, String degreeNumber) {
439         return new CpToDegreeBuilder().setKey(new CpToDegreeKey(circuitPackName)).setCircuitPackName(circuitPackName)
440             .setDegreeNumber(new Long(degreeNumber)).build();
441     }
442
443     private static List<ConnectionPorts> getDegreePorts(List<Degree> degrees) {
444         return degrees.stream().filter(degree -> degree.getConnectionPorts() != null)
445             .flatMap(degree -> degree.getConnectionPorts().stream()).collect(Collectors.toList());
446     }
447
448     private List<CpToDegree> getCpToDegreeList(List<Degree> degrees) {
449         List<CpToDegree> cpToDegreeList = new ArrayList<>();
450         for (Degree degree : degrees) {
451             if (degree.getCircuitPacks() != null) {
452                 cpToDegreeList.addAll(degree.getCircuitPacks().stream()
453                     .map(cp -> createCpToDegreeObject(cp.getCircuitPackName(), degree.getDegreeNumber().toString()))
454                     .collect(Collectors.toList()));
455             }
456         }
457         return cpToDegreeList;
458     }
459
460     /**
461      * This method for ports the portMapping corresponding to the
462      * portmapping.yang file to the MD-SAL datastore.
463      *
464      * <p>
465      * 1. Supporting circuit pack 2. Supporting port 3. Supporting OMS interface
466      * (if port on ROADM)
467      *
468      * @param deviceInfo
469      *            Info subtree from the device.
470      * @param portMapList
471      *            Reference to the list containing the mapping to be pushed to
472      *            MD-SAL.
473      *
474      * @return Result true/false based on status of operation.
475      */
476     private boolean postPortMapping(Info deviceInfo, List<Mapping> portMapList, Integer nodeType,
477         List<CpToDegree> cp2DegreeList) {
478         NodesBuilder nodesBldr = new NodesBuilder();
479         nodesBldr.setKey(new NodesKey(deviceInfo.getNodeId())).setNodeId(deviceInfo.getNodeId());
480         nodesBldr.setNodeType(NodeTypes.forValue(nodeType));
481
482         if (portMapList != null) {
483             nodesBldr.setMapping(portMapList);
484         }
485         if (cp2DegreeList != null) {
486             nodesBldr.setCpToDegree(cp2DegreeList);
487         }
488
489         List<Nodes> nodesList = new ArrayList<>();
490         nodesList.add(nodesBldr.build());
491
492         NetworkBuilder nwBldr = new NetworkBuilder();
493         nwBldr.setNodes(nodesList);
494
495         final WriteTransaction writeTransaction = this.dataBroker.newWriteOnlyTransaction();
496         InstanceIdentifier<Network> nodesIID = InstanceIdentifier.builder(Network.class).build();
497         Network network = nwBldr.build();
498         writeTransaction.merge(LogicalDatastoreType.CONFIGURATION, nodesIID, network);
499         CheckedFuture<Void, TransactionCommitFailedException> submit = writeTransaction.submit();
500         try {
501             submit.checkedGet();
502             return true;
503
504         } catch (TransactionCommitFailedException e) {
505             LOG.warn("Failed to post {}", network, e);
506             return false;
507         }
508     }
509
510     @Override
511     public Mapping getMapping(String nodeId, String logicalConnPoint) {
512
513         /*
514          * Getting physical mapping corresponding to logical connection point
515          */
516         InstanceIdentifier<Mapping> portMappingIID = InstanceIdentifier.builder(Network.class).child(Nodes.class,
517             new NodesKey(nodeId)).child(Mapping.class, new MappingKey(logicalConnPoint)).build();
518         try (ReadOnlyTransaction readTx = this.dataBroker.newReadOnlyTransaction()) {
519             Optional<Mapping> mapObject = readTx.read(LogicalDatastoreType.CONFIGURATION, portMappingIID).get()
520                 .toJavaUtil();
521             if (mapObject.isPresent()) {
522                 Mapping mapping = mapObject.get();
523                 LOG.info("Found mapping for the logical port {}. Mapping: {}", logicalConnPoint, mapping.toString());
524                 return mapping;
525             } else {
526                 LOG.warn("Could not find mapping for logical connection point {} for nodeId {}", logicalConnPoint,
527                     nodeId);
528             }
529         } catch (InterruptedException | ExecutionException ex) {
530             LOG.error("Unable to read mapping for logical connection point : {} for nodeId {}", logicalConnPoint,
531                 nodeId, ex);
532         }
533         return null;
534     }
535
536     private static String getLogicalConnectionPort(Ports port, int srgCounter) {
537         String logicalConnectionPoint = null;
538         if (port.getLogicalConnectionPoint() != null) {
539             switch (port.getPortDirection()) {
540                 case Tx:
541                     // Port direction is transmit
542                     if (!port.getLogicalConnectionPoint().contains("SRG")) {
543                         logicalConnectionPoint = "SRG" + srgCounter + "-" + port.getLogicalConnectionPoint() + "-TX";
544                     } else {
545                         logicalConnectionPoint = port.getLogicalConnectionPoint() + "-TX";
546                     }
547                     break;
548                 case Rx:
549                     // Port direction is receive
550                     if (!port.getLogicalConnectionPoint().contains("SRG")) {
551                         logicalConnectionPoint = "SRG" + srgCounter + "-" + port.getLogicalConnectionPoint() + "-RX";
552                     } else {
553                         logicalConnectionPoint = port.getLogicalConnectionPoint() + "-RX";
554                     }
555                     break;
556                 case Bidirectional:
557                     // port is bidirectional
558                     if (!port.getLogicalConnectionPoint().contains("SRG")) {
559                         logicalConnectionPoint = "SRG" + srgCounter + "-" + port.getLogicalConnectionPoint();
560                     } else {
561                         logicalConnectionPoint = port.getLogicalConnectionPoint();
562                     }
563                     if (!port.getLogicalConnectionPoint().endsWith("-TXRX")) {
564                         logicalConnectionPoint = logicalConnectionPoint.concat("-TXRX");
565                     }
566                     break;
567                 default:
568                     // Unsupported Port direction
569                     LOG.error("Unsupported port direction for port {}  {}", port, port.getPortDirection());
570                     return null; // TODO return false or continue?
571             }
572             return logicalConnectionPoint;
573         }
574         LOG.warn("Unsupported port direction for port {} - {} - LogicalConnectionPoint is null",
575             port, port.getPortDirection());
576         return null; // TODO return false or continue?
577     }
578
579     @Override
580     public void deleteMappingData(String nodeId) {
581         LOG.info("Deleting Mapping Data corresponding at node '{}'", nodeId);
582         WriteTransaction rw = this.dataBroker.newWriteOnlyTransaction();
583         InstanceIdentifier<Nodes> nodesIID = InstanceIdentifier.create(Network.class)
584             .child(Nodes.class, new NodesKey(nodeId));
585         rw.delete(LogicalDatastoreType.CONFIGURATION, nodesIID);
586         try {
587             rw.submit().get(1, TimeUnit.SECONDS);
588             LOG.info("Port mapping removal for node '{}'", nodeId);
589         } catch (InterruptedException | ExecutionException | TimeoutException e) {
590             LOG.error("Error for removing port mapping infos for node '{}'", nodeId);
591         }
592
593     }
594
595 }