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