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