PortMapping Refactoring step 1
[transportpce.git] / common / src / main / java / org / opendaylight / transportpce / common / mapping / PortMappingVersion121.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.FluentFuture;
12 import java.util.ArrayList;
13 import java.util.Collections;
14 import java.util.Comparator;
15 import java.util.HashMap;
16 import java.util.List;
17 import java.util.Locale;
18 import java.util.Map;
19 import java.util.Map.Entry;
20 import java.util.Optional;
21 import java.util.concurrent.ExecutionException;
22 import java.util.stream.Collectors;
23 import org.eclipse.jdt.annotation.NonNull;
24 import org.eclipse.jdt.annotation.Nullable;
25 import org.opendaylight.mdsal.binding.api.DataBroker;
26 import org.opendaylight.mdsal.binding.api.WriteTransaction;
27 import org.opendaylight.mdsal.common.api.CommitInfo;
28 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
29 import org.opendaylight.transportpce.common.StringConstants;
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.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev210426.Network;
35 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev210426.NetworkBuilder;
36 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev210426.OpenroadmNodeVersion;
37 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev210426.cp.to.degree.CpToDegree;
38 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev210426.cp.to.degree.CpToDegreeBuilder;
39 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev210426.cp.to.degree.CpToDegreeKey;
40 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev210426.mapping.Mapping;
41 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev210426.mapping.MappingBuilder;
42 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev210426.mapping.MappingKey;
43 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev210426.network.Nodes;
44 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev210426.network.NodesBuilder;
45 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev210426.network.NodesKey;
46 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev210426.network.nodes.NodeInfo;
47 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev210426.network.nodes.NodeInfoBuilder;
48 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.types.rev161014.Direction;
49 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.CircuitPack;
50 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.Port;
51 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.circuit.pack.Ports;
52 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.circuit.pack.PortsKey;
53 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.circuit.packs.CircuitPacks;
54 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.circuit.packs.CircuitPacksKey;
55 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.degree.ConnectionPorts;
56 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.interfaces.grp.Interface;
57 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.interfaces.grp.InterfaceKey;
58 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.org.openroadm.device.container.OrgOpenroadmDevice;
59 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.org.openroadm.device.container.org.openroadm.device.ConnectionMap;
60 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.org.openroadm.device.container.org.openroadm.device.Degree;
61 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.org.openroadm.device.container.org.openroadm.device.DegreeKey;
62 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.org.openroadm.device.container.org.openroadm.device.Info;
63 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.org.openroadm.device.container.org.openroadm.device.Protocols;
64 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.org.openroadm.device.container.org.openroadm.device.SharedRiskGroup;
65 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.org.openroadm.device.container.org.openroadm.device.SharedRiskGroupKey;
66 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.org.openroadm.device.container.org.openroadm.device.connection.map.Destination;
67 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.port.Interfaces;
68 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.types.rev191129.NodeTypes;
69 import org.opendaylight.yang.gen.v1.http.org.openroadm.interfaces.rev161014.InterfaceType;
70 import org.opendaylight.yang.gen.v1.http.org.openroadm.interfaces.rev161014.OpenROADMOpticalMultiplex;
71 import org.opendaylight.yang.gen.v1.http.org.openroadm.interfaces.rev161014.OpticalTransport;
72 import org.opendaylight.yang.gen.v1.http.org.openroadm.lldp.rev161014.Protocols1;
73 import org.opendaylight.yang.gen.v1.http.org.openroadm.lldp.rev161014.lldp.container.Lldp;
74 import org.opendaylight.yang.gen.v1.http.org.openroadm.lldp.rev161014.lldp.container.lldp.PortConfig;
75 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
76 import org.opendaylight.yangtools.yang.common.Uint16;
77 import org.opendaylight.yangtools.yang.common.Uint32;
78 import org.slf4j.Logger;
79 import org.slf4j.LoggerFactory;
80
81 // FIXME: many common pieces of code between PortMapping Versions 121 and 221 and 710
82 // some mutualization would be helpful
83 @SuppressWarnings("CPD-START")
84 public class PortMappingVersion121 {
85
86     private static final Logger LOG = LoggerFactory.getLogger(PortMappingVersion121.class);
87     private static final Map<Direction, String> SUFFIX;
88
89     private final DataBroker dataBroker;
90     private final DeviceTransactionManager deviceTransactionManager;
91     private final OpenRoadmInterfaces openRoadmInterfaces;
92
93     static {
94         SUFFIX =  Map.of(
95             Direction.Tx, "TX",
96             Direction.Rx, "RX",
97             Direction.Bidirectional, "TXRX");
98     }
99
100     public PortMappingVersion121(DataBroker dataBroker, DeviceTransactionManager deviceTransactionManager,
101             OpenRoadmInterfaces openRoadmInterfaces) {
102         this.dataBroker = dataBroker;
103         this.deviceTransactionManager = deviceTransactionManager;
104         this.openRoadmInterfaces = openRoadmInterfaces;
105     }
106
107     public boolean createMappingData(String nodeId) {
108         LOG.info(PortMappingUtils.CREATE_MAPPING_DATA_LOGMSG, nodeId, "1.2.1");
109         List<Mapping> portMapList = new ArrayList<>();
110         InstanceIdentifier<Info> infoIID = InstanceIdentifier.create(OrgOpenroadmDevice.class).child(Info.class);
111         Optional<Info> deviceInfoOptional = this.deviceTransactionManager.getDataFromDevice(nodeId, LogicalDatastoreType
112             .OPERATIONAL, infoIID, Timeouts.DEVICE_READ_TIMEOUT, Timeouts.DEVICE_READ_TIMEOUT_UNIT);
113         if (deviceInfoOptional.isEmpty()) {
114             LOG.warn(PortMappingUtils.DEVICE_HAS_LOGMSG, nodeId, "no info", "subtree");
115             return false;
116         }
117         Info deviceInfo = deviceInfoOptional.get();
118         NodeInfo nodeInfo = createNodeInfo(deviceInfo);
119         if (nodeInfo == null) {
120             return false;
121         }
122         postPortMapping(nodeId, nodeInfo, null, null);
123
124         switch (deviceInfo.getNodeType()) {
125
126             case Rdm:
127                 // Get TTP port mapping
128                 if (!createTtpPortMapping(nodeId, deviceInfo, portMapList)) {
129                     // return false if mapping creation for TTP's failed
130                     LOG.warn(PortMappingUtils.UNABLE_MAPPING_LOGMSG, nodeId, "create", "TTP's");
131                     return false;
132                 }
133
134                 // Get PP port mapping
135                 if (!createPpPortMapping(nodeId, deviceInfo, portMapList)) {
136                     // return false if mapping creation for PP's failed
137                     LOG.warn(PortMappingUtils.UNABLE_MAPPING_LOGMSG, nodeId, "create", "PP's");
138                     return false;
139                 }
140                 break;
141             case Xpdr:
142                 if (!createXpdrPortMapping(nodeId, portMapList)) {
143                     LOG.warn(PortMappingUtils.UNABLE_MAPPING_LOGMSG, nodeId, "create", "Xponder");
144                     return false;
145                 }
146                 break;
147             default:
148                 LOG.error(PortMappingUtils.UNABLE_MAPPING_LOGMSG,
149                     nodeId, "create", deviceInfo.getNodeType() + " - unknown nodetype");
150                 break;
151
152         }
153         return postPortMapping(nodeId, nodeInfo, portMapList, null);
154     }
155
156     public boolean updateMapping(String nodeId, Mapping oldMapping) {
157         if (nodeId == null) {
158             LOG.error(PortMappingUtils.UNABLE_MAPPING_LOGMSG, "node id null" , "update", "a null value");
159             return false;
160         }
161         if (oldMapping == null) {
162             LOG.error(PortMappingUtils.UNABLE_MAPPING_LOGMSG, nodeId, "update", "a null value");
163             return false;
164         }
165         InstanceIdentifier<Ports> portId = InstanceIdentifier.create(OrgOpenroadmDevice.class)
166             .child(CircuitPacks.class, new CircuitPacksKey(oldMapping.getSupportingCircuitPackName()))
167             .child(Ports.class, new PortsKey(oldMapping.getSupportingPort()));
168         try {
169             Ports port = deviceTransactionManager.getDataFromDevice(nodeId, LogicalDatastoreType.OPERATIONAL,
170                 portId, Timeouts.DEVICE_READ_TIMEOUT, Timeouts.DEVICE_READ_TIMEOUT_UNIT).get();
171             Mapping newMapping = updateMappingObject(nodeId, port, oldMapping);
172             LOG.debug(PortMappingUtils.UPDATE_MAPPING_LOGMSG,
173                 nodeId, oldMapping, oldMapping.getLogicalConnectionPoint(), newMapping);
174             final WriteTransaction writeTransaction = this.dataBroker.newWriteOnlyTransaction();
175             InstanceIdentifier<Mapping> mapIID = InstanceIdentifier.create(Network.class)
176                 .child(Nodes.class, new NodesKey(nodeId))
177                 .child(Mapping.class, new MappingKey(oldMapping.getLogicalConnectionPoint()));
178             writeTransaction.merge(LogicalDatastoreType.CONFIGURATION, mapIID, newMapping);
179             FluentFuture<? extends @NonNull CommitInfo> commit = writeTransaction.commit();
180             commit.get();
181             return true;
182         } catch (InterruptedException | ExecutionException e) {
183             LOG.error(PortMappingUtils.UNABLE_MAPPING_LOGMSG,
184                 nodeId, "update", oldMapping.getLogicalConnectionPoint(), e);
185             return false;
186         }
187     }
188
189     private boolean createXpdrPortMapping(String nodeId, List<Mapping> portMapList) {
190         // Creating for Xponder Line and Client Ports
191         InstanceIdentifier<OrgOpenroadmDevice> deviceIID = InstanceIdentifier.create(OrgOpenroadmDevice.class);
192         Optional<OrgOpenroadmDevice> deviceObject = deviceTransactionManager.getDataFromDevice(nodeId,
193             LogicalDatastoreType.OPERATIONAL, deviceIID,
194             Timeouts.DEVICE_READ_TIMEOUT, Timeouts.DEVICE_READ_TIMEOUT_UNIT);
195         if (deviceObject.isEmpty()) {
196             LOG.error(PortMappingUtils.CANNOT_GET_DEV_CONF_LOGMSG, nodeId);
197             return false;
198         }
199         OrgOpenroadmDevice device = deviceObject.get();
200         if (device.getCircuitPacks() == null) {
201             LOG.warn(PortMappingUtils.MISSING_CP_LOGMSG, nodeId, "found");
202             return false;
203         }
204         // Variable to keep track of number of line ports
205         int line = 1;
206         // Variable to keep track of number of client ports
207         int client = 1;
208         Map<String, String> lcpMap = new HashMap<>();
209         Map<String, Mapping> mappingMap = new HashMap<>();
210         List<CircuitPacks> circuitPackList = new ArrayList<>(device.nonnullCircuitPacks().values());
211         circuitPackList.sort(Comparator.comparing(CircuitPack::getCircuitPackName));
212
213         for (CircuitPacks cp : circuitPackList) {
214             String circuitPackName = cp.getCircuitPackName();
215             if (cp.getPorts() == null) {
216                 LOG.warn(PortMappingUtils.NO_PORT_ON_CP_LOGMSG, nodeId, "found", circuitPackName);
217                 continue;
218             }
219             List<Ports> portList = new ArrayList<>(cp.nonnullPorts().values());
220             portList.sort(Comparator.comparing(Ports::getPortName));
221             for (Ports port : portList) {
222                 int[] counters = fillXpdrLcpsMaps(line, client, nodeId,
223                     1, circuitPackName, port,
224                     circuitPackList, lcpMap, mappingMap);
225                 line = counters[0];
226                 client = counters[1];
227             }
228         }
229
230         for (ConnectionMap cm : deviceObject.get().nonnullConnectionMap().values()) {
231             String skey = cm.getSource().getCircuitPackName() + "+" + cm.getSource().getPortName();
232             Destination destination0 = cm.nonnullDestination().values().iterator().next();
233             String dkey = destination0.getCircuitPackName() + "+" + destination0.getPortName();
234             if (!lcpMap.containsKey(skey)) {
235                 LOG.error(PortMappingUtils.CONMAP_ISSUE_LOGMSG, nodeId, skey, dkey);
236                 continue;
237             }
238             String slcp = lcpMap.get(skey);
239             Mapping mapping = mappingMap.get(slcp);
240             mappingMap.remove(slcp);
241             portMapList.add(createXpdrMappingObject(nodeId, null, null, null, null, mapping,
242                 //dlcp
243                 lcpMap.containsKey(dkey) ? lcpMap.get(dkey) : null));
244         }
245
246         for (Mapping m : mappingMap.values()) {
247             portMapList.add(m);
248         }
249         return true;
250     }
251
252     private boolean checkPartnerPortNotNull(Ports port) {
253         return (port.getPartnerPort() != null
254             && port.getPartnerPort().getCircuitPackName() != null
255             && port.getPartnerPort().getPortName() != null);
256     }
257
258     private boolean checkPartnerPortNoDir(String circuitPackName, Ports port1, Ports port2) {
259         return (checkPartnerPortNotNull(port2)
260             && port2.getPartnerPort().getCircuitPackName().equals(circuitPackName)
261             && port2.getPartnerPort().getPortName().equals(port1.getPortName()));
262     }
263
264     private boolean checkPartnerPort(String circuitPackName, Ports port1, Ports port2) {
265         return (checkPartnerPortNoDir(circuitPackName, port1, port2)
266             && ((Direction.Rx.getIntValue() == port1.getPortDirection().getIntValue()
267                     && Direction.Tx.getIntValue() == port2.getPortDirection().getIntValue())
268                 ||
269                 (Direction.Tx.getIntValue() == port1.getPortDirection().getIntValue()
270                     && Direction.Rx.getIntValue() == port2.getPortDirection().getIntValue())));
271     }
272
273     private HashMap<Integer, List<org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.srg
274             .CircuitPacks>> getSrgCps(String deviceId, Info ordmInfo) {
275         HashMap<Integer, List<org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.srg
276             .CircuitPacks>> cpPerSrg = new HashMap<>();
277         // Get value for max Srg from info subtree, required for iteration
278         // if not present assume to be 20 (temporary)
279         Integer maxSrg = ordmInfo.getMaxSrgs() == null ? 20 : ordmInfo.getMaxSrgs().toJava();
280         for (int srgCounter = 1; srgCounter <= maxSrg; srgCounter++) {
281             List<org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.srg.CircuitPacks> srgCps
282                 = new ArrayList<>();
283             LOG.debug(PortMappingUtils.GETTING_CP_LOGMSG, deviceId, srgCounter);
284             InstanceIdentifier<SharedRiskGroup> srgIID = InstanceIdentifier.create(OrgOpenroadmDevice.class)
285                 .child(SharedRiskGroup.class, new SharedRiskGroupKey(Uint16.valueOf(srgCounter)));
286             Optional<SharedRiskGroup> ordmSrgObject = this.deviceTransactionManager.getDataFromDevice(deviceId,
287                 LogicalDatastoreType.OPERATIONAL, srgIID,
288                 Timeouts.DEVICE_READ_TIMEOUT, Timeouts.DEVICE_READ_TIMEOUT_UNIT);
289             if (ordmSrgObject.isPresent()) {
290                 srgCps.addAll(ordmSrgObject.get().nonnullCircuitPacks().values());
291                 cpPerSrg.put(ordmSrgObject.get().getSrgNumber().toJava(), srgCps);
292             }
293         }
294         LOG.info(PortMappingUtils.DEVICE_HAS_LOGMSG, deviceId, cpPerSrg.size(), "SRG");
295         return cpPerSrg;
296     }
297
298     private boolean createPpPortMapping(String nodeId, Info deviceInfo, List<Mapping> portMapList) {
299         // Creating mapping data for SRG's PP
300         HashMap<Integer, List<org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.srg.CircuitPacks>> srgCps
301             = getSrgCps(nodeId, deviceInfo);
302
303         for (Entry<Integer, List<org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.srg.CircuitPacks>>
304                 srgCpEntry : srgCps.entrySet()) {
305             List<org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.srg.CircuitPacks> cpList =
306                 srgCps.get(srgCpEntry.getKey());
307             List<String> keys = new ArrayList<>();
308             for (org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.srg.CircuitPacks cp : cpList) {
309                 String circuitPackName = cp.getCircuitPackName();
310                 InstanceIdentifier<CircuitPacks> cpIID = InstanceIdentifier.create(OrgOpenroadmDevice.class)
311                     .child(CircuitPacks.class, new CircuitPacksKey(circuitPackName));
312                 Optional<CircuitPacks> circuitPackObject = this.deviceTransactionManager.getDataFromDevice(nodeId,
313                     LogicalDatastoreType.OPERATIONAL, cpIID,
314                     Timeouts.DEVICE_READ_TIMEOUT, Timeouts.DEVICE_READ_TIMEOUT_UNIT);
315
316                 if (circuitPackObject.isEmpty()) {
317                     LOG.warn(PortMappingUtils.MISSING_CP_LOGMSG + PortMappingUtils.PORTMAPPING_IGNORE_LOGMSG,
318                         nodeId, circuitPackName);
319                     continue;
320                 }
321                 if (circuitPackObject.get().getPorts() == null) {
322                     LOG.warn(PortMappingUtils.NO_PORT_ON_CP_LOGMSG, nodeId, "found", circuitPackName);
323                     continue;
324                 }
325
326                 // com.google.common.collect.ImmutableList implementation of List
327                 @Nullable
328                 List<Ports> portList = new ArrayList<>(circuitPackObject.get().nonnullPorts().values());
329                 Collections.sort(portList, new SortPort121ByName());
330                 int portIndex = 1;
331                 for (Ports port : portList) {
332                     String currentKey = circuitPackName + "-" + port.getPortName();
333                     if (port.getPortQual() == null) {
334                         continue;
335                     }
336
337                     if (Port.PortQual.RoadmExternal.getIntValue() != port.getPortQual().getIntValue()) {
338                         LOG.debug(PortMappingUtils.PORT_NOT_RDMEXT_LOGMSG + PortMappingUtils.CANNOT_AS_LCP_LOGMSG,
339                             nodeId, port.getPortName(), circuitPackName);
340                         continue;
341                     }
342
343                     if (keys.contains(currentKey)) {
344                         LOG.debug(PortMappingUtils.PORT_ALREADY_HANDLED_LOGMSG + PortMappingUtils.CANNOT_AS_LCP_LOGMSG,
345                             nodeId, port.getPortName(), circuitPackName);
346                         continue;
347                     }
348
349                     switch (port.getPortDirection()) {
350
351                         case Bidirectional:
352                             String lcp = createLogicalConnectionPort(port, srgCpEntry.getKey(), portIndex);
353                             LOG.info(PortMappingUtils.ASSOCIATED_LCP_LOGMSG,
354                                 nodeId, port.getPortName(), circuitPackName, lcp);
355                             portMapList.add(createMappingObject(nodeId, port, circuitPackName, lcp));
356                             portIndex++;
357                             keys.add(currentKey);
358                             break;
359
360                         case Rx:
361                         case Tx:
362                             if (!checkPartnerPortNotNull(port)) {
363                                 LOG.info(PortMappingUtils.NO_VALID_PARTNERPORT_LOGMSG
364                                         + PortMappingUtils.CANNOT_AS_LCP_LOGMSG,
365                                     nodeId, port.getPortName(), circuitPackName);
366                                 continue;
367                             }
368
369                             String lcp1 = createLogicalConnectionPort(port, srgCpEntry.getKey(), portIndex);
370                             LOG.info(PortMappingUtils.ASSOCIATED_LCP_LOGMSG,
371                                     nodeId, port.getPortName(), circuitPackName, lcp1);
372                             InstanceIdentifier<Ports> port2ID = InstanceIdentifier.create(OrgOpenroadmDevice.class)
373                                 .child(CircuitPacks.class,
374                                     new CircuitPacksKey(port.getPartnerPort().getCircuitPackName()))
375                                 .child(Ports.class, new PortsKey(port.getPartnerPort().getPortName()));
376                             Optional<Ports> port2Object = this.deviceTransactionManager
377                                 .getDataFromDevice(nodeId, LogicalDatastoreType.OPERATIONAL, port2ID,
378                                     Timeouts.DEVICE_READ_TIMEOUT, Timeouts.DEVICE_READ_TIMEOUT_UNIT);
379                             if (port2Object.isEmpty()
380                                 || port2Object.get().getPortQual().getIntValue()
381                                     != Port.PortQual.RoadmExternal.getIntValue()) {
382                                 LOG.error(PortMappingUtils.NOT_CORRECT_PARTNERPORT_LOGMSG
383                                         + PortMappingUtils.PARTNERPORT_GET_ERROR_LOGMSG,
384                                     nodeId, port.getPartnerPort().getPortName(),
385                                     port.getPartnerPort().getCircuitPackName(),
386                                     port.getPortName(), circuitPackName);
387
388                                 continue;
389                             }
390
391                             Ports port2 = port2Object.get();
392                             if (!checkPartnerPort(circuitPackName, port, port2)) {
393                                 LOG.error(PortMappingUtils.NOT_CORRECT_PARTNERPORT_LOGMSG
394                                         + PortMappingUtils.PARTNERPORT_CONF_ERROR_LOGMSG,
395                                     nodeId, port2.getPortName(), port.getPartnerPort().getCircuitPackName(),
396                                     port.getPortName(), circuitPackName);
397                                 portIndex++;
398                                 continue;
399                             }
400                             String lcp2 = createLogicalConnectionPort(port2, srgCpEntry.getKey(),portIndex);
401                             LOG.info(PortMappingUtils.ASSOCIATED_LCP_LOGMSG,
402                                 nodeId, port2.getPortName(), circuitPackName, lcp2);
403                             portMapList.add(createMappingObject(nodeId, port, circuitPackName, lcp1));
404                             portMapList.add(
405                                 createMappingObject(nodeId ,port2, port.getPartnerPort().getCircuitPackName(), lcp2));
406                             portIndex++;
407                             keys.add(currentKey);
408                             keys.add(port.getPartnerPort().getCircuitPackName() + "-" + port2.getPortName());
409                             break;
410
411                         default:
412                             LOG.error(PortMappingUtils.UNSUPPORTED_DIR_LOGMSG + PortMappingUtils.CANNOT_AS_LCP_LOGMSG,
413                                 nodeId, port.getPortName(), circuitPackName, port.getPortDirection());
414
415                     }
416                 }
417             }
418         }
419         return true;
420     }
421
422     private String createLogicalConnectionPort(Ports port, int index, int portIndex) {
423         if (SUFFIX.containsKey(port.getPortDirection())) {
424             return String.join("-", "SRG" + index, "PP" + portIndex, SUFFIX.get(port.getPortDirection()));
425         }
426         LOG.error(PortMappingUtils.UNSUPPORTED_DIR_LOGMSG,
427             "createLogicalConnectionPort", port, "SRG" + index + "-PP" + portIndex, port.getPortDirection());
428         return null;
429     }
430
431     private Map<Integer, Degree> getDegreesMap(String deviceId, Info ordmInfo) {
432         Map<Integer, Degree> degrees = new HashMap<>();
433
434         // Get value for max degree from info subtree, required for iteration
435         // if not present assume to be 20 (temporary)
436         Integer maxDegree = ordmInfo.getMaxDegrees() == null ? 20 : ordmInfo.getMaxDegrees().toJava();
437
438         for (int degreeCounter = 1; degreeCounter <= maxDegree; degreeCounter++) {
439             LOG.debug(PortMappingUtils.GETTING_CONPORT_LOGMSG, deviceId, degreeCounter);
440             InstanceIdentifier<Degree> deviceIID = InstanceIdentifier.create(OrgOpenroadmDevice.class)
441                 .child(Degree.class, new DegreeKey(Uint16.valueOf(degreeCounter)));
442             Optional<Degree> ordmDegreeObject = this.deviceTransactionManager.getDataFromDevice(deviceId,
443                 LogicalDatastoreType.OPERATIONAL, deviceIID,
444                 Timeouts.DEVICE_READ_TIMEOUT, Timeouts.DEVICE_READ_TIMEOUT_UNIT);
445             if (ordmDegreeObject.isPresent()) {
446                 degrees.put(degreeCounter, ordmDegreeObject.get());
447             }
448         }
449         LOG.info(PortMappingUtils.DEVICE_HAS_LOGMSG,
450                 deviceId, degrees.size(), degrees.size() <= 1 ? "degree" : "degrees");
451         return degrees;
452     }
453
454     private Map<Integer, List<ConnectionPorts>> getPerDegreePorts(String deviceId, Info ordmInfo) {
455         Map<Integer, List<ConnectionPorts>> conPortMap = new HashMap<>();
456         getDegreesMap(deviceId, ordmInfo).forEach(
457             (index, degree) -> conPortMap.put(index, new ArrayList<>(degree.nonnullConnectionPorts().values())));
458         return conPortMap;
459     }
460
461     private Map<String, String> getEthInterfaceList(String nodeId) {
462         LOG.info(PortMappingUtils.GETTING_ETH_LIST_LOGMSG, nodeId);
463         InstanceIdentifier<Protocols> protocoliid = InstanceIdentifier.create(OrgOpenroadmDevice.class)
464             .child(Protocols.class);
465         Optional<Protocols> protocolObject = this.deviceTransactionManager.getDataFromDevice(nodeId,
466             LogicalDatastoreType.OPERATIONAL, protocoliid, Timeouts.DEVICE_READ_TIMEOUT,
467             Timeouts.DEVICE_READ_TIMEOUT_UNIT);
468         if (!protocolObject.isPresent() || protocolObject.get().augmentation(Protocols1.class).getLldp() == null) {
469             LOG.warn(PortMappingUtils.PROCESSING_DONE_LOGMSG, nodeId, PortMappingUtils.CANNOT_GET_LLDP_CONF_LOGMSG);
470             return new HashMap<>();
471         }
472         Map<String, String> cpToInterfaceMap = new HashMap<>();
473         Lldp lldp = protocolObject.get().augmentation(Protocols1.class).getLldp();
474         for (PortConfig portConfig : lldp.nonnullPortConfig().values()) {
475             if (!portConfig.getAdminStatus().equals(PortConfig.AdminStatus.Txandrx)) {
476                 continue;
477             }
478             InstanceIdentifier<Interface> interfaceIID = InstanceIdentifier.create(OrgOpenroadmDevice.class)
479                 .child(Interface.class, new InterfaceKey(portConfig.getIfName()));
480             Optional<Interface> interfaceObject = this.deviceTransactionManager.getDataFromDevice(nodeId,
481                 LogicalDatastoreType.OPERATIONAL, interfaceIID, Timeouts.DEVICE_READ_TIMEOUT,
482                 Timeouts.DEVICE_READ_TIMEOUT_UNIT);
483             if (interfaceObject.isEmpty() || interfaceObject.get().getSupportingCircuitPackName() == null) {
484                 continue;
485             }
486             String supportingCircuitPackName = interfaceObject.get().getSupportingCircuitPackName();
487             cpToInterfaceMap.put(supportingCircuitPackName, portConfig.getIfName());
488             InstanceIdentifier<CircuitPacks> circuitPacksIID = InstanceIdentifier
489                 .create(OrgOpenroadmDevice.class)
490                 .child(CircuitPacks.class, new CircuitPacksKey(supportingCircuitPackName));
491             Optional<CircuitPacks> circuitPackObject = this.deviceTransactionManager.getDataFromDevice(
492                 nodeId, LogicalDatastoreType.OPERATIONAL, circuitPacksIID, Timeouts.DEVICE_READ_TIMEOUT,
493                 Timeouts.DEVICE_READ_TIMEOUT_UNIT);
494             if (circuitPackObject.isEmpty() || circuitPackObject.get().getParentCircuitPack() == null) {
495                 continue;
496             }
497             cpToInterfaceMap.put(circuitPackObject.get().getParentCircuitPack().getCircuitPackName(),
498                 portConfig.getIfName());
499         }
500         LOG.info(PortMappingUtils.PROCESSING_DONE_LOGMSG, nodeId, " - success");
501         return cpToInterfaceMap;
502     }
503
504     private List<CpToDegree> getCpToDegreeList(Map<Integer, Degree> degrees, Map<String, String> interfaceList) {
505         List<CpToDegree> cpToDegreeList = new ArrayList<>();
506         for (Degree degree : degrees.values()) {
507             cpToDegreeList.addAll(degree.nonnullCircuitPacks().values().stream()
508                 .map(cp -> createCpToDegreeObject(cp.getCircuitPackName(),
509                     degree.getDegreeNumber().toString(), interfaceList))
510                 .collect(Collectors.toList()));
511         }
512         return cpToDegreeList;
513     }
514
515     private boolean postPortMapping(String nodeId, NodeInfo nodeInfo, List<Mapping> portMapList,
516             List<CpToDegree> cp2DegreeList) {
517         NodesBuilder nodesBldr = new NodesBuilder().withKey(new NodesKey(nodeId)).setNodeId(nodeId);
518         if (nodeInfo != null) {
519             nodesBldr.setNodeInfo(nodeInfo);
520         }
521         if (portMapList != null) {
522             Map<MappingKey, Mapping> mappingMap = new HashMap<>();
523             // No element in the list below should be null at this stage
524             for (Mapping mapping: portMapList) {
525                 mappingMap.put(mapping.key(), mapping);
526             }
527             nodesBldr.setMapping(mappingMap);
528         }
529         if (cp2DegreeList != null) {
530             Map<CpToDegreeKey, CpToDegree> cpToDegreeMap = new HashMap<>();
531             // No element in the list below should be null at this stage
532             for (CpToDegree cp2Degree: cp2DegreeList) {
533                 cpToDegreeMap.put(cp2Degree.key(), cp2Degree);
534             }
535             nodesBldr.setCpToDegree(cpToDegreeMap);
536         }
537
538         Map<NodesKey,Nodes> nodesList = new HashMap<>();
539         Nodes nodes = nodesBldr.build();
540         nodesList.put(nodes.key(),nodes);
541
542         Network network = new NetworkBuilder().setNodes(nodesList).build();
543
544         final WriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction();
545         InstanceIdentifier<Network> nodesIID = InstanceIdentifier.builder(Network.class).build();
546         writeTransaction.merge(LogicalDatastoreType.CONFIGURATION, nodesIID, network);
547         FluentFuture<? extends @NonNull CommitInfo> commit = writeTransaction.commit();
548         try {
549             commit.get();
550             return true;
551         } catch (InterruptedException | ExecutionException e) {
552             LOG.warn(PortMappingUtils.PORTMAPPING_POST_FAIL_LOGMSG, nodeId, network, e);
553             return false;
554         }
555     }
556
557     private CpToDegree createCpToDegreeObject(String circuitPackName, String degreeNumber,
558             Map<String, String> interfaceList) {
559         return new CpToDegreeBuilder()
560             .withKey(new CpToDegreeKey(circuitPackName))
561             .setCircuitPackName(circuitPackName)
562             .setDegreeNumber(Uint32.valueOf(degreeNumber))
563             .setInterfaceName(interfaceList.get(circuitPackName)).build();
564     }
565
566     private Mapping createMappingObject(String nodeId, Ports port, String circuitPackName,
567             String logicalConnectionPoint) {
568         MappingBuilder mpBldr = new MappingBuilder()
569                 .withKey(new MappingKey(logicalConnectionPoint))
570                 .setLogicalConnectionPoint(logicalConnectionPoint)
571                 .setSupportingCircuitPackName(circuitPackName)
572                 .setSupportingPort(port.getPortName())
573                 .setPortDirection(port.getPortDirection().getName());
574         if (port.getAdministrativeState() != null) {
575             mpBldr.setPortAdminState(port.getAdministrativeState().name());
576         }
577         if (port.getOperationalState() != null) {
578             mpBldr.setPortOperState(port.getOperationalState().name());
579         }
580         if (!logicalConnectionPoint.contains(StringConstants.TTP_TOKEN) || (port.getInterfaces() == null)) {
581             return mpBldr.build();
582         }
583         mpBldr = updateMappingInterfaces(nodeId, mpBldr, port);
584         return mpBldr.build();
585     }
586
587     private Mapping updateMappingObject(String nodeId, Ports port, Mapping oldmapping) {
588         MappingBuilder mpBldr = new MappingBuilder(oldmapping);
589         updateMappingStates(mpBldr, port, oldmapping);
590         if ((port.getInterfaces() == null)
591             || (!oldmapping.getLogicalConnectionPoint().contains(StringConstants.TTP_TOKEN)
592                 && !oldmapping.getLogicalConnectionPoint().contains(StringConstants.NETWORK_TOKEN))) {
593             return mpBldr.build();
594         }
595         // Get interfaces provisioned on the port
596         mpBldr = updateMappingInterfaces(nodeId, mpBldr, port);
597         return mpBldr.build();
598     }
599
600     private MappingBuilder updateMappingStates(MappingBuilder mpBldr, Ports port, Mapping oldmapping) {
601         if (port.getAdministrativeState() != null
602             && !port.getAdministrativeState().getName().equals(oldmapping.getPortAdminState())) {
603             mpBldr.setPortAdminState(port.getAdministrativeState().name());
604         }
605         if (port.getOperationalState() != null
606             && !port.getOperationalState().getName().equals(oldmapping.getPortOperState())) {
607             mpBldr.setPortOperState(port.getOperationalState().name());
608         }
609         return mpBldr;
610     }
611
612     private MappingBuilder updateMappingInterfaces(String nodeId, MappingBuilder mpBldr, Ports port) {
613         for (Interfaces interfaces : port.getInterfaces()) {
614             try {
615                 Optional<Interface> openRoadmInterface = this.openRoadmInterfaces.getInterface(nodeId,
616                     interfaces.getInterfaceName());
617                 if (openRoadmInterface.isEmpty()) {
618                     LOG.warn(PortMappingUtils.INTF_ISSUE_LOGMSG,
619                         nodeId, interfaces.getInterfaceName() + "- empty interface");
620                     continue;
621                 }
622                 LOG.debug(PortMappingUtils.GOT_INTF_LOGMSG,
623                     nodeId, openRoadmInterface.get().getName(), openRoadmInterface.get().getType());
624                 Class<? extends InterfaceType> interfaceType
625                     = (Class<? extends InterfaceType>) openRoadmInterface.get().getType();
626                 // Check if interface type is OMS or OTS
627                 if (interfaceType.equals(OpenROADMOpticalMultiplex.class)) {
628                     mpBldr.setSupportingOms(interfaces.getInterfaceName());
629                 }
630                 if (interfaceType.equals(OpticalTransport.class)) {
631                     mpBldr.setSupportingOts(interfaces.getInterfaceName());
632                 }
633             } catch (OpenRoadmInterfaceException ex) {
634                 LOG.warn(PortMappingUtils.INTF_ISSUE_LOGMSG, nodeId, interfaces.getInterfaceName(), ex);
635             }
636         }
637         return mpBldr;
638     }
639
640     private Mapping createXpdrMappingObject(String nodeId, Ports port, String circuitPackName,
641             String logicalConnectionPoint, String partnerLcp, Mapping mapping, String assoLcp) {
642
643         if (mapping != null && assoLcp != null) {
644             // update existing mapping
645             return new MappingBuilder(mapping).setConnectionMapLcp(assoLcp).build();
646         }
647
648         // create a new mapping
649         String nodeIdLcp = nodeId + "-" + logicalConnectionPoint;
650         MappingBuilder mpBldr = new MappingBuilder()
651                 .withKey(new MappingKey(logicalConnectionPoint))
652                 .setLogicalConnectionPoint(logicalConnectionPoint)
653                 .setSupportingCircuitPackName(circuitPackName)
654                 .setSupportingPort(port.getPortName())
655                 .setPortDirection(port.getPortDirection().getName())
656                 .setLcpHashVal(PortMappingUtils.fnv1size64(nodeIdLcp));
657         if (port.getPortQual() != null) {
658             mpBldr.setPortQual(port.getPortQual().getName());
659         }
660         if (partnerLcp != null) {
661             mpBldr.setPartnerLcp(partnerLcp);
662         }
663         if (port.getAdministrativeState() != null) {
664             mpBldr.setPortAdminState(port.getAdministrativeState().name());
665         }
666         if (port.getOperationalState() != null) {
667             mpBldr.setPortOperState(port.getOperationalState().name());
668         }
669         return mpBldr.build();
670     }
671
672     private Ports getPort2(Ports port, String nodeId, String circuitPackName, StringBuilder circuitPackName2,
673             //circuitPackName2 will be updated by reference contrary to circuitPackName
674             List<CircuitPacks> circuitPackList, Map<String, String> lcpMap) {
675         if (!checkPartnerPortNotNull(port)) {
676             LOG.warn(PortMappingUtils.NO_VALID_PARTNERPORT_LOGMSG, nodeId, port.getPortName(), circuitPackName);
677             return null;
678         }
679         if (lcpMap.containsKey(circuitPackName + '+' + port.getPortName())) {
680             return null;
681         }
682         Optional<CircuitPacks> cpOpt = circuitPackList.stream()
683             .filter(cP -> cP.getCircuitPackName().equals(port.getPartnerPort().getCircuitPackName()))
684             .findFirst();
685         if (cpOpt.isEmpty()) {
686             LOG.error(PortMappingUtils.MISSING_CP_LOGMSG, nodeId, port.getPartnerPort().getCircuitPackName());
687             return null;
688         }
689         Optional<Ports> poOpt = cpOpt.get().nonnullPorts().values().stream()
690             .filter(p -> p.getPortName().equals(port.getPartnerPort().getPortName()))
691             .findFirst();
692         if (poOpt.isEmpty()) {
693             LOG.error(PortMappingUtils.NO_PORT_ON_CP_LOGMSG,
694                 nodeId, port.getPartnerPort().getPortName(), port.getPartnerPort().getCircuitPackName());
695             return null;
696         }
697         Ports port2 = poOpt.get();
698         circuitPackName2.append(cpOpt.get().getCircuitPackName());
699         if (!checkPartnerPort(circuitPackName, port, port2)) {
700             LOG.error(PortMappingUtils.NOT_CORRECT_PARTNERPORT_LOGMSG,
701                 nodeId, port2.getPortName(), circuitPackName2, port.getPortName(), circuitPackName);
702             return null;
703         }
704         return port2;
705     }
706
707     private void putXpdrLcpsInMaps(int line, String nodeId,
708             Integer xponderNb,
709             String circuitPackName, String circuitPackName2, Ports port, Ports port2,
710             Map<String, String> lcpMap, Map<String, Mapping> mappingMap) {
711         String lcp1 =
712             PortMappingUtils.createXpdrLogicalConnectionPort(xponderNb, line, StringConstants.NETWORK_TOKEN);
713         if (lcpMap.containsKey(lcp1)) {
714             LOG.warn(PortMappingUtils.UNABLE_MAPPING_LOGMSG, nodeId, "add", lcp1 + " - already exist");
715             return;
716         }
717         String lcp2 =
718             PortMappingUtils.createXpdrLogicalConnectionPort(xponderNb, line + 1, StringConstants.NETWORK_TOKEN);
719         if (lcpMap.containsKey(lcp2)) {
720             LOG.warn(PortMappingUtils.UNABLE_MAPPING_LOGMSG, nodeId, "add", lcp2 + " - already exist");
721             return;
722         }
723         lcpMap.put(circuitPackName + '+' + port.getPortName(), lcp1);
724         lcpMap.put(circuitPackName2 + '+' + port2.getPortName(), lcp2);
725         mappingMap.put(lcp1,
726                 createXpdrMappingObject(nodeId, port, circuitPackName, lcp1, lcp2, null, null));
727         mappingMap.put(lcp2,
728                 createXpdrMappingObject(nodeId, port2, circuitPackName2, lcp2, lcp1, null, null));
729         return;
730     }
731
732     private int[] fillXpdrLcpsMaps(int line, int client, String nodeId,
733             Integer xponderNb,
734             String circuitPackName,  Ports port,
735             List<CircuitPacks> circuitPackList, Map<String, String> lcpMap, Map<String, Mapping> mappingMap) {
736
737         if (port.getPortQual() == null) {
738             LOG.warn(PortMappingUtils.PORTQUAL_LOGMSG, nodeId, port.getPortName(), circuitPackName, "not found");
739             return new int[] {line, client};
740         }
741
742         switch (port.getPortQual()) {
743
744             case XpdrClient:
745                 String lcp0 =
746                     PortMappingUtils.createXpdrLogicalConnectionPort(xponderNb, client, StringConstants.CLIENT_TOKEN);
747                 lcpMap.put(circuitPackName + '+' + port.getPortName(), lcp0);
748                 mappingMap.put(lcp0,
749                     createXpdrMappingObject(nodeId, port, circuitPackName, lcp0, null, null, null));
750                 client++;
751                 break;
752
753             case XpdrNetwork:
754                 line = fillXpdrNetworkLcpsMaps(line, nodeId,
755                         xponderNb,
756                         circuitPackName,  port,
757                         circuitPackList,  lcpMap, mappingMap);
758                 break;
759
760             default:
761                 LOG.error(PortMappingUtils.PORTQUAL_LOGMSG,
762                     nodeId, port.getPortName(), circuitPackName, port.getPortQual() + " not supported");
763         }
764         return new int[] {line, client};
765     }
766
767     private int fillXpdrNetworkLcpsMaps(int line, String nodeId,
768             Integer xponderNb,
769             String circuitPackName,  Ports port,
770             List<CircuitPacks> circuitPackList, Map<String, String> lcpMap, Map<String, Mapping> mappingMap) {
771
772         switch (port.getPortDirection()) {
773
774             case Bidirectional:
775                 String lcp =
776                     PortMappingUtils.createXpdrLogicalConnectionPort(xponderNb, line, StringConstants.NETWORK_TOKEN);
777                 lcpMap.put(circuitPackName + '+' + port.getPortName(), lcp);
778                 mappingMap.put(lcp,
779                     createXpdrMappingObject(nodeId, port, circuitPackName, lcp, null, null, null));
780                 line++;
781                 break;
782
783             case Rx:
784             case Tx:
785                 StringBuilder circuitPackName2 = new StringBuilder();
786                 Ports port2 = getPort2(port, nodeId, circuitPackName, circuitPackName2,
787                         circuitPackList, lcpMap);
788
789                 if (port2 == null) {
790                      //key already present or an error occured and was logged
791                     return line;
792                 }
793
794                 putXpdrLcpsInMaps(line, nodeId, xponderNb,
795                         circuitPackName, circuitPackName2.toString(), port, port2,
796                         lcpMap, mappingMap);
797
798                 line += 2;
799                 break;
800
801             default:
802                 LOG.error(PortMappingUtils.UNSUPPORTED_DIR_LOGMSG,
803                      nodeId, port.getPortName(), circuitPackName, port.getPortDirection());
804         }
805
806         return line;
807     }
808
809     private boolean createTtpPortMapping(String nodeId, Info deviceInfo, List<Mapping> portMapList) {
810         // Creating mapping data for degree TTP's
811         Map<Integer, Degree> degrees = getDegreesMap(nodeId, deviceInfo);
812         Map<String, String> interfaceList = getEthInterfaceList(nodeId);
813         List<CpToDegree> cpToDegreeList = getCpToDegreeList(degrees, interfaceList);
814         LOG.info(PortMappingUtils.MAP_LOOKS_LOGMSG, nodeId, interfaceList);
815         postPortMapping(nodeId, null, null, cpToDegreeList);
816
817         Map<Integer, List<ConnectionPorts>> connectionPortMap = getPerDegreePorts(nodeId, deviceInfo);
818         for (Entry<Integer, List<ConnectionPorts>> cpMapEntry : connectionPortMap.entrySet()) {
819             List<ConnectionPorts> cpMapValue = cpMapEntry.getValue();
820             ConnectionPorts cp1 = cpMapValue.get(0);
821             String cp1Name = cp1.getCircuitPackName();
822             switch (cpMapValue.size()) {
823                 case 1:
824                     // port is bidirectional
825                     InstanceIdentifier<Ports> portID = InstanceIdentifier.create(OrgOpenroadmDevice.class)
826                         .child(CircuitPacks.class, new CircuitPacksKey(cp1Name))
827                         .child(Ports.class, new PortsKey(cp1.getPortName()));
828                     LOG.debug(PortMappingUtils.FETCH_CONNECTIONPORT_LOGMSG, nodeId, cp1.getPortName(), cp1Name);
829                     Optional<Ports> portObject = this.deviceTransactionManager.getDataFromDevice(nodeId,
830                         LogicalDatastoreType.OPERATIONAL, portID, Timeouts.DEVICE_READ_TIMEOUT,
831                         Timeouts.DEVICE_READ_TIMEOUT_UNIT);
832                     if (portObject.isEmpty()) {
833                         LOG.error(PortMappingUtils.NO_PORT_ON_CP_LOGMSG, nodeId, cp1.getPortName(), cp1Name);
834                         return false;
835                     }
836                     Ports port = portObject.get();
837                     if (port.getPortQual() == null) {
838                         continue;
839                     }
840                     if (Port.PortQual.RoadmExternal.getIntValue() != port.getPortQual().getIntValue()) {
841                         LOG.error(PortMappingUtils.CANNOT_CREATE_LCP_LOGMSG + PortMappingUtils.PORTQUAL_ERROR_LOGMSG,
842                             nodeId, port.getPortName(), cp1Name);
843                         continue;
844                     }
845                     if (Direction.Bidirectional.getIntValue() != port.getPortDirection().getIntValue()) {
846                         LOG.error(PortMappingUtils.CANNOT_CREATE_LCP_LOGMSG + PortMappingUtils.PORTDIR_ERROR_LOGMSG,
847                             nodeId, port.getPortName(), cp1Name);
848                         continue;
849                     }
850
851                     String logicalConnectionPoint =
852                             PortMappingUtils.degreeTtpNodeName(cpMapEntry.getKey().toString(), "TXRX");
853                     LOG.info(PortMappingUtils.ASSOCIATED_LCP_LOGMSG,
854                         nodeId, port.getPortName(), cp1Name, logicalConnectionPoint);
855                     portMapList.add(createMappingObject(nodeId, port, cp1Name, logicalConnectionPoint));
856                     break;
857                 case 2:
858                     // ports are unidirectionals
859                     ConnectionPorts cp2 = cpMapValue.get(1);
860                     String cp2Name = cp2.getCircuitPackName();
861                     InstanceIdentifier<Ports> port1ID = InstanceIdentifier.create(OrgOpenroadmDevice.class)
862                         .child(CircuitPacks.class, new CircuitPacksKey(cp1Name))
863                         .child(Ports.class, new PortsKey(cp1.getPortName()));
864                     LOG.debug(PortMappingUtils.FETCH_CONNECTIONPORT_LOGMSG, nodeId, cp1.getPortName(), cp1Name);
865                     Optional<Ports> port1Object = this.deviceTransactionManager.getDataFromDevice(nodeId,
866                         LogicalDatastoreType.OPERATIONAL, port1ID, Timeouts.DEVICE_READ_TIMEOUT,
867                         Timeouts.DEVICE_READ_TIMEOUT_UNIT);
868                     InstanceIdentifier<Ports> port2ID = InstanceIdentifier.create(OrgOpenroadmDevice.class)
869                         .child(CircuitPacks.class, new CircuitPacksKey(cp2Name))
870                         .child(Ports.class, new PortsKey(cp2.getPortName()));
871                     LOG.debug(PortMappingUtils.FETCH_CONNECTIONPORT_LOGMSG,
872                         nodeId, cp2.getPortName(), cp2Name);
873                     Optional<Ports> port2Object = this.deviceTransactionManager.getDataFromDevice(nodeId,
874                         LogicalDatastoreType.OPERATIONAL, port2ID, Timeouts.DEVICE_READ_TIMEOUT,
875                         Timeouts.DEVICE_READ_TIMEOUT_UNIT);
876                     if (port1Object.isEmpty()) {
877                         LOG.error(PortMappingUtils.NO_PORT_ON_CP_LOGMSG, nodeId, cp1.getPortName(), cp1Name);
878                         return false;
879                     }
880                     if (port2Object.isEmpty()) {
881                         LOG.error(PortMappingUtils.NO_PORT_ON_CP_LOGMSG, nodeId, cp2.getPortName(), cp2Name);
882                         return false;
883                     }
884
885                     Ports port1 = port1Object.get();
886                     Ports port2 = port2Object.get();
887                     if (port1.getPortQual() == null || port2.getPortQual() == null) {
888                         continue;
889                     }
890                     if (Port.PortQual.RoadmExternal.getIntValue() != port1.getPortQual().getIntValue()) {
891                         LOG.error(PortMappingUtils.CANNOT_CREATE_LCP_LOGMSG + PortMappingUtils.PORTQUAL_ERROR_LOGMSG,
892                             nodeId, port1.getPortName(), cp1Name);
893                         continue;
894                     }
895                     if (Port.PortQual.RoadmExternal.getIntValue() != port2.getPortQual().getIntValue()) {
896                         LOG.error(PortMappingUtils.CANNOT_CREATE_LCP_LOGMSG + PortMappingUtils.PORTQUAL_ERROR_LOGMSG,
897                             nodeId, port2.getPortName(), cp2Name);
898                         continue;
899                     }
900
901                     if (!checkPartnerPort(cp1Name, port1, port2)) {
902                         LOG.error(PortMappingUtils.NOT_CORRECT_PARTNERPORT_LOGMSG,
903                             nodeId, port2.getPortName(), cp2Name, port1.getPortName(), cp1Name);
904                         continue;
905                     }
906                     // Directions checks are the same for cp1 and cp2, no need to check them twice.
907                     if (!checkPartnerPortNoDir(cp2Name, port2, port1)) {
908                         LOG.error(PortMappingUtils.NOT_CORRECT_PARTNERPORT_LOGMSG,
909                             nodeId, port1.getPortName(), cp1Name, port2.getPortName(), cp2Name);
910                         continue;
911                     }
912
913                     String logicalConnectionPoint1 = PortMappingUtils.degreeTtpNodeName(cpMapEntry.getKey().toString(),
914                             port1.getPortDirection().getName().toUpperCase(Locale.getDefault()));
915                     LOG.info(PortMappingUtils.ASSOCIATED_LCP_LOGMSG,
916                         nodeId, port1.getPortName(), cp1Name, logicalConnectionPoint1);
917                     portMapList.add(createMappingObject(nodeId, port1, cp1Name, logicalConnectionPoint1));
918                     String logicalConnectionPoint2 = PortMappingUtils.degreeTtpNodeName(cpMapEntry.getKey().toString(),
919                             port2.getPortDirection().getName().toUpperCase(Locale.getDefault()));
920                     LOG.info(PortMappingUtils.ASSOCIATED_LCP_LOGMSG,
921                         nodeId, port2.getPortName(), cp2Name, logicalConnectionPoint2);
922                     portMapList.add(createMappingObject(nodeId, port2, cp2Name, logicalConnectionPoint2));
923                     break;
924                 default:
925                     LOG.error(PortMappingUtils.NOT_CORRECT_CONPORT_LOGMSG, nodeId, cpMapEntry.getKey());
926                     continue;
927             }
928         }
929         return true;
930     }
931
932     private NodeInfo createNodeInfo(Info deviceInfo) {
933
934         if (deviceInfo.getNodeType() == null) {
935             // TODO make mandatory in yang
936             LOG.error(PortMappingUtils.NODE_TYPE_LOGMSG, deviceInfo.getNodeId(), "field missing");
937             return null;
938         }
939
940         NodeInfoBuilder nodeInfoBldr = new NodeInfoBuilder()
941                 .setOpenroadmVersion(OpenroadmNodeVersion._121)
942                 .setNodeClli(
943                     deviceInfo.getClli() == null || deviceInfo.getClli().isEmpty()
944                         ? "defaultCLLI"
945                         : deviceInfo.getClli());
946         // TODO check if we can use here .setNodeType(NodeTypes.forValue(..) such as with 221
947         switch (deviceInfo.getNodeType().getIntValue()) {
948             case 1:
949             case 2:
950                 nodeInfoBldr.setNodeType(NodeTypes.forValue(deviceInfo.getNodeType().getIntValue()));
951                 break;
952             default:
953                 LOG.error(PortMappingUtils.NODE_TYPE_LOGMSG, deviceInfo.getNodeId(), "value not supported");
954                 // TODO: is this protection useful ? it is not present in Portmapping 221
955         }
956         if (deviceInfo.getModel() != null) {
957             nodeInfoBldr.setNodeModel(deviceInfo.getModel());
958         }
959         if (deviceInfo.getVendor() != null) {
960             nodeInfoBldr.setNodeVendor(deviceInfo.getVendor());
961         }
962         if (deviceInfo.getIpAddress() != null) {
963             nodeInfoBldr.setNodeIpAddress(deviceInfo.getIpAddress());
964         }
965
966         return nodeInfoBldr.build();
967     }
968
969 }