e880d02b441e9e2cf61ffa77aec0fc9320d61ae7
[transportpce.git] / pce / src / main / java / org / opendaylight / transportpce / pce / networkanalyzer / PceCalculation.java
1 /*
2  * Copyright © 2017 AT&T, Inc. 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.pce.networkanalyzer;
10
11 import java.util.ArrayList;
12 import java.util.HashMap;
13 import java.util.HashSet;
14 import java.util.List;
15 import java.util.Map;
16 import java.util.Optional;
17 import java.util.Set;
18 import java.util.concurrent.ExecutionException;
19 import java.util.stream.Collectors;
20 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
21 import org.opendaylight.transportpce.common.NetworkUtils;
22 import org.opendaylight.transportpce.common.ResponseCodes;
23 import org.opendaylight.transportpce.common.network.NetworkTransactionService;
24 import org.opendaylight.transportpce.pce.constraints.PceConstraints;
25 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev200128.PathComputationRequestInput;
26 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev181130.Node1;
27 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.types.rev181130.OpenroadmLinkType;
28 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.types.rev181130.OpenroadmNodeType;
29 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.NetworkId;
30 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.Networks;
31 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.NodeId;
32 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.Network;
33 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.NetworkKey;
34 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.network.Node;
35 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.LinkId;
36 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.Network1;
37 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.Link;
38 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
39 //import org.opendaylight.yangtools.yang.common.Decimal64;
40 import org.slf4j.Logger;
41 import org.slf4j.LoggerFactory;
42
43 public class PceCalculation {
44     /* Logging. */
45     private static final Logger LOG = LoggerFactory.getLogger(PceCalculation.class);
46     private NetworkTransactionService networkTransactionService = null;
47
48     ///////////// data parsed from Input/////////////////
49     private PathComputationRequestInput input;
50     private String anodeId = "";
51     private String znodeId = "";
52     private String serviceFormatA = "";
53     private String serviceFormatZ = "";
54     private String serviceType = "";
55     private Long serviceRate = 0L;
56
57     private PceConstraints pceHardConstraints;
58
59     ///////////// Intermediate data/////////////////
60     private List<PceLink> addLinks = new ArrayList<>();
61     private List<PceLink> dropLinks = new ArrayList<>();
62     private HashSet<NodeId> azSrgs = new HashSet<>();
63
64     private PceNode aendPceNode = null;
65     private PceNode zendPceNode = null;
66
67     private List<Link> allLinks = null;
68     private List<Node> allNodes = null;
69
70     // this List serves graph calculation
71     private Map<NodeId, PceNode> allPceNodes = new HashMap<>();
72     // this List serves calculation of ZtoA path description
73     // TODO maybe better solution is possible
74     private Map<LinkId, PceLink> allPceLinks = new HashMap<>();
75     private Set<LinkId> linksToExclude = new HashSet<>();
76     private PceResult returnStructure;
77
78     private enum ConstraintTypes {
79         NONE, HARD_EXCLUDE, HARD_INCLUDE, HARD_DIVERSITY, SOFT_EXCLUDE, SOFT_INCLUDE, SOFT_DIVERSITY;
80     }
81
82     public PceCalculation(PathComputationRequestInput input, NetworkTransactionService networkTransactionService,
83             PceConstraints pceHardConstraints, PceConstraints pceSoftConstraints, PceResult rc) {
84         this.input = input;
85         this.networkTransactionService = networkTransactionService;
86         this.returnStructure = rc;
87
88         this.pceHardConstraints = pceHardConstraints;
89         parseInput();
90     }
91
92     public void retrievePceNetwork() {
93
94         LOG.info("In PceCalculation retrieveNetwork: ");
95
96         if (!readMdSal()) {
97             returnStructure.setRC(ResponseCodes.RESPONSE_FAILED);
98             return;
99         }
100         MapUtils.mapDiversityConstraints(allNodes, allLinks, pceHardConstraints);
101
102         if (!analyzeNw()) {
103             returnStructure.setRC(ResponseCodes.RESPONSE_FAILED);
104             return;
105         }
106         printNodesInfo(allPceNodes);
107
108         returnStructure.setRC(ResponseCodes.RESPONSE_OK);
109         return;
110     }
111
112     private boolean parseInput() {
113         if (input.getServiceAEnd().getServiceFormat() == null || input.getServiceZEnd().getServiceFormat() == null
114             || input.getServiceAEnd().getServiceRate() == null) {
115             LOG.error("Service Format and Service Rate are required for a path calculation");
116             return false;
117         }
118         serviceFormatA = input.getServiceAEnd().getServiceFormat().getName();
119         serviceFormatZ = input.getServiceZEnd().getServiceFormat().getName();
120         serviceRate = input.getServiceAEnd().getServiceRate().toJava();
121
122         LOG.info("parseInput: A and Z :[{}] and [{}]", anodeId, znodeId);
123         if (!(serviceFormatA.equals(serviceFormatZ))) {
124             LOG.info("parseInput: different service format for A and Z not handled, will use service format from Aend");
125         } else if (serviceRate == 100L) {
126             switch (serviceFormatA) {
127                 case "Ethernet":
128                 case "OC":
129                     serviceType = "100GE";
130                     break;
131                 case "OTU":
132                     serviceType = "OTU4";
133                     break;
134                 case "ODU":
135                     serviceType = "ODU4";
136                     break;
137                 default:
138                     LOG.debug("parseInput: unsupported service type: Format {} Rate 100L", serviceFormatA);
139                     break;
140             }
141             //switch(serviceRate) may seem a better option at first glance.
142             //But switching on Long or long is not directly possible in Java.
143             //And casting to int bumps the limit here.
144             //Passing by ENUM or String are possible alternatives.
145             //Maybe HashMap and similar options should also be considered here.
146         } else if ("Ethernet".equals(serviceFormatA)) {
147         //only rate 100L is currently supported except in Ethernet
148             if (serviceRate == 10L) {
149                 serviceType = "10GE";
150             } else if (serviceRate == 1L) {
151                 serviceType = "1GE";
152             } else {
153                 LOG.debug("parseInput: unsupported service type: Format Ethernet Rate {}", serviceRate);
154             }
155         } else {
156             LOG.debug("parseInput: unsupported service type: Format {} Rate {}",
157                 serviceFormatA, serviceRate);
158         }
159         if ("ODU4".equals(serviceType) || "10GE".equals(serviceType)  || "1GE".equals(serviceType)) {
160             anodeId = input.getServiceAEnd().getTxDirection().getPort().getPortDeviceName();
161             znodeId = input.getServiceZEnd().getTxDirection().getPort().getPortDeviceName();
162         } else {
163             anodeId = input.getServiceAEnd().getNodeId();
164             znodeId = input.getServiceZEnd().getNodeId();
165         }
166
167         returnStructure.setRate(input.getServiceAEnd().getServiceRate().toJava());
168         returnStructure.setServiceFormat(input.getServiceAEnd().getServiceFormat());
169         return true;
170     }
171
172     private boolean readMdSal() {
173         InstanceIdentifier<Network> nwInstanceIdentifier = null;
174         Network nw = null;
175         if (("OC".equals(serviceFormatA)) || ("OTU".equals(serviceFormatA)) || (("Ethernet".equals(serviceFormatA))
176             && (serviceRate == 100L))) {
177
178             LOG.info("readMdSal: network {}", NetworkUtils.OVERLAY_NETWORK_ID);
179             nwInstanceIdentifier = InstanceIdentifier.builder(Networks.class)
180                 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OVERLAY_NETWORK_ID))).build();
181         } else if ("ODU".equals(serviceFormatA) || ("Ethernet".equals(serviceFormatA) && serviceRate == 10L)
182             || ("Ethernet".equals(serviceFormatA) && serviceRate == 1L)) {
183             LOG.info("readMdSal: network {}", NetworkUtils.OTN_NETWORK_ID);
184             nwInstanceIdentifier = InstanceIdentifier.builder(Networks.class)
185                 .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OTN_NETWORK_ID))).build();
186         } else {
187             LOG.info("readMdSal: service-rate {} / service-format not handled {}", serviceRate, serviceFormatA);
188             return false;
189         }
190
191         try {
192             Optional<Network> nwOptional =
193                 networkTransactionService.read(LogicalDatastoreType.CONFIGURATION, nwInstanceIdentifier).get();
194             if (nwOptional.isPresent()) {
195                 nw = nwOptional.get();
196                 LOG.debug("readMdSal: network nodes: nwOptional.isPresent = true {}", nw);
197             }
198         } catch (InterruptedException | ExecutionException e) {
199             LOG.error("readMdSal: Error reading topology {}", nwInstanceIdentifier);
200             networkTransactionService.close();
201             returnStructure.setRC(ResponseCodes.RESPONSE_FAILED);
202             throw new RuntimeException(
203                 "readMdSal: Error reading from operational store, topology : " + nwInstanceIdentifier + " :" + e);
204         }
205         networkTransactionService.close();
206
207         if (nw == null) {
208             LOG.error("readMdSal: network is null: {}", nwInstanceIdentifier);
209             return false;
210         }
211         allNodes = nw.nonnullNode().values().stream().sorted((n1, n2)
212             -> n1.getNodeId().getValue().compareTo(n2.getNodeId().getValue())).collect(Collectors.toList());
213         Network1 nw1 = nw.augmentation(Network1.class);
214         if (nw1 != null) {
215             allLinks = nw1.nonnullLink().values().stream().sorted((l1, l2)
216                 -> l1.getSource().getSourceTp().toString().compareTo(l2.getSource().getSourceTp().toString()))
217                     .collect(Collectors.toList());
218         } else {
219             LOG.warn("no otn links in otn-topology");
220         }
221         if (allNodes == null || allNodes.isEmpty()) {
222             LOG.error("readMdSal: no nodes ");
223             return false;
224         }
225         LOG.info("readMdSal: network nodes: {} nodes added", allNodes.size());
226         LOG.debug("readMdSal: network nodes: {} nodes added", allNodes);
227
228         if (allLinks == null || allLinks.isEmpty()) {
229             LOG.error("readMdSal: no links ");
230             return false;
231         }
232         LOG.info("readMdSal: network links: {} links added", allLinks.size());
233         LOG.debug("readMdSal: network links: {} links added", allLinks);
234
235         return true;
236     }
237
238     private boolean analyzeNw() {
239
240         LOG.debug("analyzeNw: allNodes size {}, allLinks size {}", allNodes.size(), allLinks.size());
241
242         if (("100GE".equals(serviceType)) || ("OTU4".equals(serviceType))) {
243             // 100GE service and OTU4 service are handled at the openroadm-topology layer
244             for (Node node : allNodes) {
245                 validateNode(node);
246             }
247
248             LOG.debug("analyzeNw: allPceNodes size {}", allPceNodes.size());
249
250             if (aendPceNode == null || zendPceNode == null) {
251                 LOG.error("analyzeNw: Error in reading nodes: A or Z do not present in the network");
252                 return false;
253             }
254             for (Link link : allLinks) {
255                 validateLink(link);
256             }
257             // debug prints
258             LOG.debug("analyzeNw: addLinks size {}, dropLinks size {}", addLinks.size(), dropLinks.size());
259             // debug prints
260             LOG.debug("analyzeNw: azSrgs size = {}", azSrgs.size());
261             for (NodeId srg : azSrgs) {
262                 LOG.debug("analyzeNw: A/Z Srgs SRG = {}", srg.getValue());
263             }
264             // debug prints
265             for (PceLink link : addLinks) {
266                 filteraddLinks(link);
267             }
268             for (PceLink link : dropLinks) {
269                 filterdropLinks(link);
270             }
271
272         } else {
273             // ODU4, 10GE/ODU2e or 1GE/ODU0 services are handled at openroadm-otn layer
274
275             for (Node node : allNodes) {
276                 validateOtnNode(node);
277             }
278
279             LOG.info("analyzeNw: allPceNodes {}", allPceNodes);
280
281             if (aendPceNode == null || zendPceNode == null) {
282                 LOG.error("analyzeNw: Error in reading nodes: A or Z do not present in the network");
283                 return false;
284             }
285             for (Link link : allLinks) {
286                 validateLink(link);
287             }
288         }
289
290         LOG.info("analyzeNw: allPceNodes size {}, allPceLinks size {}", allPceNodes.size(), allPceLinks.size());
291
292         if ((allPceNodes.size() == 0) || (allPceLinks.size() == 0)) {
293             return false;
294         }
295
296         LOG.debug("analyzeNw: allPceNodes {}", allPceNodes);
297         LOG.debug("analyzeNw: allPceLinks {}", allPceLinks);
298
299         return true;
300     }
301
302     private boolean filteraddLinks(PceLink pcelink) {
303
304         NodeId nodeId = pcelink.getSourceId();
305
306         if (azSrgs.contains(nodeId)) {
307             allPceLinks.put(pcelink.getLinkId(), pcelink);
308             allPceNodes.get(nodeId).addOutgoingLink(pcelink);
309             LOG.debug("analyzeNw: Add_LINK added to source and to allPceLinks {}", pcelink.getLinkId());
310             return true;
311         }
312
313         // remove the SRG from PceNodes, as it is not directly connected to A/Z
314         allPceNodes.remove(nodeId);
315         LOG.debug("analyzeNw: SRG removed {}", nodeId.getValue());
316
317         return false;
318     }
319
320     private boolean filterdropLinks(PceLink pcelink) {
321
322         NodeId nodeId = pcelink.getDestId();
323
324         if (azSrgs.contains(nodeId)) {
325             allPceLinks.put(pcelink.getLinkId(), pcelink);
326             allPceNodes.get(nodeId).addOutgoingLink(pcelink);
327             LOG.debug("analyzeNw: Drop_LINK added to dest and to allPceLinks {}", pcelink.getLinkId());
328             return true;
329         }
330
331         // remove the SRG from PceNodes, as it is not directly connected to A/Z
332         allPceNodes.remove(pcelink.getDestId());
333         LOG.debug("analyzeNw: SRG removed {}", nodeId.getValue());
334
335         return false;
336     }
337
338     private boolean validateLink(Link link) {
339         LOG.info("validateLink: link {} ", link);
340
341         NodeId sourceId = link.getSource().getSourceNode();
342         NodeId destId = link.getDestination().getDestNode();
343         PceNode source = allPceNodes.get(sourceId);
344         PceNode dest = allPceNodes.get(destId);
345
346         if (source == null) {
347             LOG.debug("validateLink: Link is ignored due source node is rejected by node validation - {}",
348                 link.getSource().getSourceNode().getValue());
349             return false;
350         }
351         if (dest == null) {
352             LOG.debug("validateLink: Link is ignored due dest node is rejected by node validation - {}",
353                 link.getDestination().getDestNode().getValue());
354             return false;
355         }
356
357         if (("100GE".equals(serviceType)) || ("OTU4".equals(serviceType))) {
358             // 100GE or OTU4 services are handled at WDM Layer
359             PceLink pcelink = new PceLink(link, source, dest);
360             if (!pcelink.isValid()) {
361                 dropOppositeLink(link);
362                 LOG.error(" validateLink: Link is ignored due errors in network data or in opposite link");
363                 return false;
364             }
365             LinkId linkId = pcelink.getLinkId();
366             if (validateLinkConstraints(pcelink).equals(ConstraintTypes.HARD_EXCLUDE)) {
367                 dropOppositeLink(link);
368                 LOG.debug("validateLink: constraints : link is ignored == {}", linkId.getValue());
369                 return false;
370             }
371             switch (pcelink.getlinkType()) {
372                 case ROADMTOROADM:
373                 case EXPRESSLINK:
374                     allPceLinks.put(linkId, pcelink);
375                     source.addOutgoingLink(pcelink);
376                     LOG.debug("validateLink: {}-LINK added to allPceLinks {}",
377                         pcelink.getlinkType(), pcelink);
378                     break;
379                 case ADDLINK:
380                     pcelink.setClient(source.getRdmSrgClient(pcelink.getSourceTP().toString()));
381                     addLinks.add(pcelink);
382                     LOG.debug("validateLink: ADD-LINK saved  {}", pcelink);
383                     break;
384                 case DROPLINK:
385                     pcelink.setClient(dest.getRdmSrgClient(pcelink.getDestTP().toString()));
386                     dropLinks.add(pcelink);
387                     LOG.debug("validateLink: DROP-LINK saved  {}", pcelink);
388                     break;
389                 case XPONDERINPUT:
390                     // store separately all SRG links directly
391                     azSrgs.add(sourceId);
392                     // connected to A/Z
393                     if (!dest.checkTP(pcelink.getDestTP().toString())) {
394                         LOG.debug(
395                             "validateLink: XPONDER-INPUT is rejected as NW port is busy - {} ", pcelink);
396                         return false;
397                     }
398                     if (dest.getXpdrClient(pcelink.getDestTP().toString()) != null) {
399                         pcelink.setClient(dest.getXpdrClient(pcelink.getDestTP().toString()));
400                     }
401                     allPceLinks.put(linkId, pcelink);
402                     source.addOutgoingLink(pcelink);
403                     LOG.debug("validateLink: XPONDER-INPUT link added to allPceLinks {}", pcelink);
404                     break;
405                 // does it mean XPONDER==>>SRG ?
406                 case XPONDEROUTPUT:
407                     // store separately all SRG links directly
408                     azSrgs.add(destId);
409                     // connected to A/Z
410                     if (!source.checkTP(pcelink.getSourceTP().toString())) {
411                         LOG.debug(
412                             "validateLink: XPONDER-OUTPUT is rejected as NW port is busy - {} ", pcelink);
413                         return false;
414                     }
415                     if (source.getXpdrClient(pcelink.getSourceTP().toString()) != null) {
416                         pcelink.setClient(source.getXpdrClient(pcelink.getSourceTP().toString()));
417                     }
418                     allPceLinks.put(linkId, pcelink);
419                     source.addOutgoingLink(pcelink);
420                     LOG.debug("validateLink: XPONDER-OUTPUT link added to allPceLinks {}", pcelink);
421                     break;
422                 default:
423                     LOG.warn("validateLink: link type is not supported {}", pcelink);
424             }
425             return true;
426
427         } else if (("ODU4".equals(serviceType)) || ("10GE".equals(serviceType)) || ("1GE".equals(serviceType))) {
428             // ODU4, 1GE and 10GE services relying on ODU2, ODU2e or ODU0 services are handled at OTN layer
429             PceLink pceOtnLink = new PceLink(link, source, dest);
430
431             if (!pceOtnLink.isOtnValid(link, serviceType)) {
432                 dropOppositeLink(link);
433                 LOG.error(" validateLink: Link is ignored due errors in network data or in opposite link");
434                 return false;
435             }
436
437             LinkId linkId = pceOtnLink.getLinkId();
438             if (validateLinkConstraints(pceOtnLink).equals(ConstraintTypes.HARD_EXCLUDE)) {
439                 dropOppositeLink(link);
440                 LOG.debug("validateLink: constraints : link is ignored == {}", linkId.getValue());
441                 return false;
442             }
443
444             switch (pceOtnLink.getlinkType()) {
445                 case OTNLINK:
446                     if (dest.getXpdrClient(pceOtnLink.getDestTP().toString()) != null) {
447                         pceOtnLink.setClient(dest.getXpdrClient(pceOtnLink.getDestTP().toString()));
448                     }
449
450                     allPceLinks.put(linkId, pceOtnLink);
451                     source.addOutgoingLink(pceOtnLink);
452                     LOG.info("validateLink: OTN-LINK added to allPceLinks {}", pceOtnLink);
453                     break;
454                 default:
455                     LOG.warn("validateLink: link type is not supported {}", pceOtnLink);
456             }
457             return true;
458
459         } else {
460             LOG.error(" validateLink: Unmanaged service type {}", serviceType);
461             return false;
462         }
463
464     }
465
466     private boolean validateNode(Node node) {
467         LOG.debug("validateNode: node {} ", node);
468
469         // PceNode will be used in Graph algorithm
470         Node1 node1 = node.augmentation(Node1.class);
471         if (node1 == null) {
472             LOG.error("getNodeType: no Node1 (type) Augmentation for node: [{}]. Node is ignored", node.getNodeId());
473             return false;
474         }
475         OpenroadmNodeType nodeType = node1.getNodeType();
476
477         PceOpticalNode pceNode = new PceOpticalNode(node, nodeType, node.getNodeId(),
478             input.getServiceAEnd().getServiceFormat(), "optical");
479         pceNode.validateAZxponder(anodeId, znodeId);
480         pceNode.initWLlist();
481
482         if (!pceNode.isValid()) {
483             LOG.warn(" validateNode: Node is ignored");
484             return false;
485         }
486
487         if (validateNodeConstraints(pceNode).equals(ConstraintTypes.HARD_EXCLUDE)) {
488             return false;
489         }
490         if ((pceNode.getSupNetworkNodeId().equals(anodeId) && (this.aendPceNode == null))
491             && (Boolean.TRUE.equals(endPceNode(nodeType, pceNode.getNodeId(), pceNode)))) {
492             this.aendPceNode = pceNode;
493         }
494         if ((pceNode.getSupNetworkNodeId().equals(znodeId) && (this.zendPceNode == null))
495             && (Boolean.TRUE.equals(endPceNode(nodeType, pceNode.getNodeId(), pceNode)))) {
496             this.zendPceNode = pceNode;
497         }
498
499         allPceNodes.put(pceNode.getNodeId(), pceNode);
500         LOG.debug("validateNode: node is saved {}", pceNode.getNodeId().getValue());
501         return true;
502     }
503
504     private boolean validateOtnNode(Node node) {
505
506         LOG.info("validateOtnNode: {} ", node.getNodeId().getValue());
507         // PceOtnNode will be used in Graph algorithm
508         if (node.augmentation(Node1.class) != null) {
509             OpenroadmNodeType nodeType = node.augmentation(Node1.class).getNodeType();
510
511             PceOtnNode pceOtnNode = new PceOtnNode(node, nodeType, node.getNodeId(), "otn", serviceType);
512             pceOtnNode.validateXponder(anodeId, znodeId);
513
514             if (!pceOtnNode.isValid()) {
515                 LOG.warn(" validateOtnNode: Node {} is ignored", node.getNodeId().getValue());
516                 return false;
517             }
518             if (validateNodeConstraints(pceOtnNode).equals(ConstraintTypes.HARD_EXCLUDE)) {
519                 return false;
520             }
521             if (pceOtnNode.getNodeId().getValue().equals(anodeId) && this.aendPceNode == null) {
522                 this.aendPceNode = pceOtnNode;
523             }
524             if (pceOtnNode.getNodeId().getValue().equals(znodeId) && this.zendPceNode == null) {
525                 this.zendPceNode = pceOtnNode;
526             }
527             allPceNodes.put(pceOtnNode.getNodeId(), pceOtnNode);
528             LOG.info("validateOtnNode: node {} is saved", node.getNodeId().getValue());
529             return true;
530         } else {
531             LOG.error("ValidateOtnNode: no node-type augmentation. Node {} is ignored", node.getNodeId().getValue());
532             return false;
533         }
534
535 //        if (mode == "AZ") {
536 //            pceOtnNode.validateAZxponder(anodeId, znodeId);
537 //        } else if (mode == "intermediate") {
538 //            pceOtnNode.validateIntermediateSwitch();
539 //        } else {
540 //            LOG.error("validateOtnNode: unproper mode passed to the method : {} not supported", mode);
541 //            return null;
542 //        }
543     }
544
545     private ConstraintTypes validateNodeConstraints(PceNode pcenode) {
546         if (pceHardConstraints.getExcludeSupNodes().isEmpty() && pceHardConstraints.getExcludeCLLI().isEmpty()) {
547             return ConstraintTypes.NONE;
548         }
549         if (pceHardConstraints.getExcludeSupNodes().contains(pcenode.getSupNetworkNodeId())) {
550             LOG.info("validateNodeConstraints: {}", pcenode.getNodeId().getValue());
551             return ConstraintTypes.HARD_EXCLUDE;
552         }
553         if (pceHardConstraints.getExcludeCLLI().contains(pcenode.getSupClliNodeId())) {
554             LOG.info("validateNodeConstraints: {}", pcenode.getNodeId().getValue());
555             return ConstraintTypes.HARD_EXCLUDE;
556         }
557         return ConstraintTypes.NONE;
558     }
559
560     private ConstraintTypes validateLinkConstraints(PceLink link) {
561         if (pceHardConstraints.getExcludeSRLG().isEmpty()) {
562             return ConstraintTypes.NONE;
563         }
564
565         // for now SRLG is the only constraint for link
566         if (link.getlinkType() != OpenroadmLinkType.ROADMTOROADM) {
567             return ConstraintTypes.NONE;
568         }
569
570         List<Long> constraints = new ArrayList<>(pceHardConstraints.getExcludeSRLG());
571         constraints.retainAll(link.getsrlgList());
572         if (!constraints.isEmpty()) {
573             LOG.info("validateLinkConstraints: {}", link.getLinkId().getValue());
574             return ConstraintTypes.HARD_EXCLUDE;
575         }
576
577         return ConstraintTypes.NONE;
578     }
579
580     private void dropOppositeLink(Link link) {
581         LinkId opplink = MapUtils.extractOppositeLink(link);
582
583         if (allPceLinks.containsKey(opplink)) {
584             allPceLinks.remove(opplink);
585         } else {
586             linksToExclude.add(opplink);
587         }
588     }
589
590     private Boolean endPceNode(OpenroadmNodeType openroadmNodeType, NodeId nodeId, PceOpticalNode pceNode) {
591         switch (openroadmNodeType) {
592             case SRG:
593                 pceNode.initSrgTps();
594                 this.azSrgs.add(nodeId);
595                 break;
596             case XPONDER:
597                 pceNode.initXndrTps();
598                 break;
599             default:
600                 LOG.warn("endPceNode: Node {} is not SRG or XPONDER !", nodeId);
601                 return false;
602         }
603
604         if (!pceNode.isValid()) {
605             LOG.error("validateNode : there are no availaible wavelengths in node {}", pceNode.getNodeId().getValue());
606             return false;
607         }
608         return true;
609     }
610
611     public PceNode getaendPceNode() {
612         return aendPceNode;
613     }
614
615     public PceNode getzendPceNode() {
616         return zendPceNode;
617     }
618
619     public Map<NodeId, PceNode> getAllPceNodes() {
620         return this.allPceNodes;
621     }
622
623     public Map<LinkId, PceLink> getAllPceLinks() {
624         return this.allPceLinks;
625     }
626
627     public String getServiceType() {
628         return serviceType;
629     }
630
631     public PceResult getReturnStructure() {
632         return returnStructure;
633     }
634
635     private static void printNodesInfo(Map<NodeId, PceNode> allPceNodes) {
636         allPceNodes.forEach(((nodeId, pceNode) -> {
637             LOG.info("In printNodes in node {} : outgoing links {} ", pceNode.getNodeId().getValue(),
638                     pceNode.getOutgoingLinks());
639         }));
640     }
641 }