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