Integration of end-to-end otn services
[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.getNode().stream().sorted((n1, n2) -> n1.getNodeId().getValue().compareTo(n2.getNodeId()
212             .getValue())).collect(Collectors.toList());
213         Network1 nw1 = nw.augmentation(Network1.class);
214         if (nw1 != null) {
215             allLinks = nw1.getLink().stream().sorted((l1, l2) -> l1.getSource().getSourceTp().toString().compareTo(l2
216                 .getSource().getSourceTp().toString())).collect(Collectors.toList());
217         } else {
218             LOG.warn("no otn links in otn-topology");
219         }
220         if (allNodes == null || allNodes.isEmpty()) {
221             LOG.error("readMdSal: no nodes ");
222             return false;
223         }
224         LOG.info("readMdSal: network nodes: {} nodes added", allNodes.size());
225         LOG.debug("readMdSal: network nodes: {} nodes added", allNodes);
226
227         if (allLinks == null || allLinks.isEmpty()) {
228             LOG.error("readMdSal: no links ");
229             return false;
230         }
231         LOG.info("readMdSal: network links: {} links added", allLinks.size());
232         LOG.debug("readMdSal: network links: {} links added", allLinks);
233
234         return true;
235     }
236
237     private boolean analyzeNw() {
238
239         LOG.debug("analyzeNw: allNodes size {}, allLinks size {}", allNodes.size(), allLinks.size());
240
241         if (("100GE".equals(serviceType)) || ("OTU4".equals(serviceType))) {
242             // 100GE service and OTU4 service are handled at the openroadm-topology layer
243             for (Node node : allNodes) {
244                 validateNode(node);
245             }
246
247             LOG.debug("analyzeNw: allPceNodes size {}", allPceNodes.size());
248
249             if (aendPceNode == null || zendPceNode == null) {
250                 LOG.error("analyzeNw: Error in reading nodes: A or Z do not present in the network");
251                 return false;
252             }
253             for (Link link : allLinks) {
254                 validateLink(link);
255             }
256             // debug prints
257             LOG.debug("analyzeNw: addLinks size {}, dropLinks size {}", addLinks.size(), dropLinks.size());
258             // debug prints
259             LOG.debug("analyzeNw: azSrgs size = {}", azSrgs.size());
260             for (NodeId srg : azSrgs) {
261                 LOG.debug("analyzeNw: A/Z Srgs SRG = {}", srg.getValue());
262             }
263             // debug prints
264             for (PceLink link : addLinks) {
265                 filteraddLinks(link);
266             }
267             for (PceLink link : dropLinks) {
268                 filterdropLinks(link);
269             }
270
271         } else {
272             // ODU4, 10GE/ODU2e or 1GE/ODU0 services are handled at openroadm-otn layer
273
274             for (Node node : allNodes) {
275                 validateOtnNode(node);
276             }
277
278             LOG.info("analyzeNw: allPceNodes {}", allPceNodes);
279
280             if (aendPceNode == null || zendPceNode == null) {
281                 LOG.error("analyzeNw: Error in reading nodes: A or Z do not present in the network");
282                 return false;
283             }
284             for (Link link : allLinks) {
285                 validateLink(link);
286             }
287         }
288
289         LOG.info("analyzeNw: allPceNodes size {}, allPceLinks size {}", allPceNodes.size(), allPceLinks.size());
290
291         if ((allPceNodes.size() == 0) || (allPceLinks.size() == 0)) {
292             return false;
293         }
294
295         LOG.debug("analyzeNw: allPceNodes {}", allPceNodes);
296         LOG.debug("analyzeNw: allPceLinks {}", allPceLinks);
297
298         return true;
299     }
300
301     private boolean filteraddLinks(PceLink pcelink) {
302
303         NodeId nodeId = pcelink.getSourceId();
304
305         if (azSrgs.contains(nodeId)) {
306             allPceLinks.put(pcelink.getLinkId(), pcelink);
307             allPceNodes.get(nodeId).addOutgoingLink(pcelink);
308             LOG.debug("analyzeNw: Add_LINK added to source and to allPceLinks {}", pcelink.getLinkId());
309             return true;
310         }
311
312         // remove the SRG from PceNodes, as it is not directly connected to A/Z
313         allPceNodes.remove(nodeId);
314         LOG.debug("analyzeNw: SRG removed {}", nodeId.getValue());
315
316         return false;
317     }
318
319     private boolean filterdropLinks(PceLink pcelink) {
320
321         NodeId nodeId = pcelink.getDestId();
322
323         if (azSrgs.contains(nodeId)) {
324             allPceLinks.put(pcelink.getLinkId(), pcelink);
325             allPceNodes.get(nodeId).addOutgoingLink(pcelink);
326             LOG.debug("analyzeNw: Drop_LINK added to dest and to allPceLinks {}", pcelink.getLinkId());
327             return true;
328         }
329
330         // remove the SRG from PceNodes, as it is not directly connected to A/Z
331         allPceNodes.remove(pcelink.getDestId());
332         LOG.debug("analyzeNw: SRG removed {}", nodeId.getValue());
333
334         return false;
335     }
336
337     private boolean validateLink(Link link) {
338         LOG.info("validateLink: link {} ", link);
339
340         NodeId sourceId = link.getSource().getSourceNode();
341         NodeId destId = link.getDestination().getDestNode();
342         PceNode source = allPceNodes.get(sourceId);
343         PceNode dest = allPceNodes.get(destId);
344
345         if (source == null) {
346             LOG.debug("validateLink: Link is ignored due source node is rejected by node validation - {}",
347                 link.getSource().getSourceNode().getValue());
348             return false;
349         }
350         if (dest == null) {
351             LOG.debug("validateLink: Link is ignored due dest node is rejected by node validation - {}",
352                 link.getDestination().getDestNode().getValue());
353             return false;
354         }
355
356         if (("100GE".equals(serviceType)) || ("OTU4".equals(serviceType))) {
357             // 100GE or OTU4 services are handled at WDM Layer
358             PceLink pcelink = new PceLink(link, source, dest);
359             if (!pcelink.isValid()) {
360                 dropOppositeLink(link);
361                 LOG.error(" validateLink: Link is ignored due errors in network data or in opposite link");
362                 return false;
363             }
364             LinkId linkId = pcelink.getLinkId();
365             if (validateLinkConstraints(pcelink).equals(ConstraintTypes.HARD_EXCLUDE)) {
366                 dropOppositeLink(link);
367                 LOG.debug("validateLink: constraints : link is ignored == {}", linkId.getValue());
368                 return false;
369             }
370             switch (pcelink.getlinkType()) {
371                 case ROADMTOROADM:
372                 case EXPRESSLINK:
373                     allPceLinks.put(linkId, pcelink);
374                     source.addOutgoingLink(pcelink);
375                     LOG.debug("validateLink: {}-LINK added to allPceLinks {}",
376                         pcelink.getlinkType(), pcelink);
377                     break;
378                 case ADDLINK:
379                     pcelink.setClient(source.getRdmSrgClient(pcelink.getSourceTP().toString()));
380                     addLinks.add(pcelink);
381                     LOG.debug("validateLink: ADD-LINK saved  {}", pcelink);
382                     break;
383                 case DROPLINK:
384                     pcelink.setClient(dest.getRdmSrgClient(pcelink.getDestTP().toString()));
385                     dropLinks.add(pcelink);
386                     LOG.debug("validateLink: DROP-LINK saved  {}", pcelink);
387                     break;
388                 case XPONDERINPUT:
389                     // store separately all SRG links directly
390                     azSrgs.add(sourceId);
391                     // connected to A/Z
392                     if (!dest.checkTP(pcelink.getDestTP().toString())) {
393                         LOG.debug(
394                             "validateLink: XPONDER-INPUT is rejected as NW port is busy - {} ", pcelink);
395                         return false;
396                     }
397                     if (dest.getXpdrClient(pcelink.getDestTP().toString()) != null) {
398                         pcelink.setClient(dest.getXpdrClient(pcelink.getDestTP().toString()));
399                     }
400                     allPceLinks.put(linkId, pcelink);
401                     source.addOutgoingLink(pcelink);
402                     LOG.debug("validateLink: XPONDER-INPUT link added to allPceLinks {}", pcelink);
403                     break;
404                 // does it mean XPONDER==>>SRG ?
405                 case XPONDEROUTPUT:
406                     // store separately all SRG links directly
407                     azSrgs.add(destId);
408                     // connected to A/Z
409                     if (!source.checkTP(pcelink.getSourceTP().toString())) {
410                         LOG.debug(
411                             "validateLink: XPONDER-OUTPUT is rejected as NW port is busy - {} ", pcelink);
412                         return false;
413                     }
414                     if (source.getXpdrClient(pcelink.getSourceTP().toString()) != null) {
415                         pcelink.setClient(source.getXpdrClient(pcelink.getSourceTP().toString()));
416                     }
417                     allPceLinks.put(linkId, pcelink);
418                     source.addOutgoingLink(pcelink);
419                     LOG.debug("validateLink: XPONDER-OUTPUT link added to allPceLinks {}", pcelink);
420                     break;
421                 default:
422                     LOG.warn("validateLink: link type is not supported {}", pcelink);
423             }
424             return true;
425
426         } else if (("ODU4".equals(serviceType)) || ("10GE".equals(serviceType)) || ("1GE".equals(serviceType))) {
427             // ODU4, 1GE and 10GE services relying on ODU2, ODU2e or ODU0 services are handled at OTN layer
428             PceLink pceOtnLink = new PceLink(link, source, dest);
429
430             if (!pceOtnLink.isOtnValid(link, serviceType)) {
431                 dropOppositeLink(link);
432                 LOG.error(" validateLink: Link is ignored due errors in network data or in opposite link");
433                 return false;
434             }
435
436             LinkId linkId = pceOtnLink.getLinkId();
437             if (validateLinkConstraints(pceOtnLink).equals(ConstraintTypes.HARD_EXCLUDE)) {
438                 dropOppositeLink(link);
439                 LOG.debug("validateLink: constraints : link is ignored == {}", linkId.getValue());
440                 return false;
441             }
442
443             switch (pceOtnLink.getlinkType()) {
444                 case OTNLINK:
445                     if (dest.getXpdrClient(pceOtnLink.getDestTP().toString()) != null) {
446                         pceOtnLink.setClient(dest.getXpdrClient(pceOtnLink.getDestTP().toString()));
447                     }
448
449                     allPceLinks.put(linkId, pceOtnLink);
450                     source.addOutgoingLink(pceOtnLink);
451                     LOG.info("validateLink: OTN-LINK added to allPceLinks {}", pceOtnLink);
452                     break;
453                 default:
454                     LOG.warn("validateLink: link type is not supported {}", pceOtnLink);
455             }
456             return true;
457
458         } else {
459             LOG.error(" validateLink: Unmanaged service type {}", serviceType);
460             return false;
461         }
462
463     }
464
465     private boolean validateNode(Node node) {
466         LOG.debug("validateNode: node {} ", node);
467
468         // PceNode will be used in Graph algorithm
469         Node1 node1 = node.augmentation(Node1.class);
470         if (node1 == null) {
471             LOG.error("getNodeType: no Node1 (type) Augmentation for node: [{}]. Node is ignored", node.getNodeId());
472             return false;
473         }
474         OpenroadmNodeType nodeType = node1.getNodeType();
475
476         PceOpticalNode pceNode = new PceOpticalNode(node, nodeType, node.getNodeId(),
477             input.getServiceAEnd().getServiceFormat(), "optical");
478         pceNode.validateAZxponder(anodeId, znodeId);
479         pceNode.initWLlist();
480
481         if (!pceNode.isValid()) {
482             LOG.warn(" validateNode: Node is ignored");
483             return false;
484         }
485
486         if (validateNodeConstraints(pceNode).equals(ConstraintTypes.HARD_EXCLUDE)) {
487             return false;
488         }
489         if ((pceNode.getSupNetworkNodeId().equals(anodeId) && (this.aendPceNode == null))
490             && (Boolean.TRUE.equals(endPceNode(nodeType, pceNode.getNodeId(), pceNode)))) {
491             this.aendPceNode = pceNode;
492         }
493         if ((pceNode.getSupNetworkNodeId().equals(znodeId) && (this.zendPceNode == null))
494             && (Boolean.TRUE.equals(endPceNode(nodeType, pceNode.getNodeId(), pceNode)))) {
495             this.zendPceNode = pceNode;
496         }
497
498         allPceNodes.put(pceNode.getNodeId(), pceNode);
499         LOG.debug("validateNode: node is saved {}", pceNode.getNodeId().getValue());
500         return true;
501     }
502
503     private boolean validateOtnNode(Node node) {
504
505         LOG.info("validateOtnNode: {} ", node.getNodeId().getValue());
506         // PceOtnNode will be used in Graph algorithm
507         if (node.augmentation(Node1.class) != null) {
508             OpenroadmNodeType nodeType = node.augmentation(Node1.class).getNodeType();
509
510             PceOtnNode pceOtnNode = new PceOtnNode(node, nodeType, node.getNodeId(), "otn", serviceType);
511             pceOtnNode.validateXponder(anodeId, znodeId);
512
513             if (!pceOtnNode.isValid()) {
514                 LOG.warn(" validateOtnNode: Node {} is ignored", node.getNodeId().getValue());
515                 return false;
516             }
517             if (validateNodeConstraints(pceOtnNode).equals(ConstraintTypes.HARD_EXCLUDE)) {
518                 return false;
519             }
520             if (pceOtnNode.getNodeId().getValue().equals(anodeId) && this.aendPceNode == null) {
521                 this.aendPceNode = pceOtnNode;
522             }
523             if (pceOtnNode.getNodeId().getValue().equals(znodeId) && this.zendPceNode == null) {
524                 this.zendPceNode = pceOtnNode;
525             }
526             allPceNodes.put(pceOtnNode.getNodeId(), pceOtnNode);
527             LOG.info("validateOtnNode: node {} is saved", node.getNodeId().getValue());
528             return true;
529         } else {
530             LOG.error("ValidateOtnNode: no node-type augmentation. Node {} is ignored", node.getNodeId().getValue());
531             return false;
532         }
533
534 //        if (mode == "AZ") {
535 //            pceOtnNode.validateAZxponder(anodeId, znodeId);
536 //        } else if (mode == "intermediate") {
537 //            pceOtnNode.validateIntermediateSwitch();
538 //        } else {
539 //            LOG.error("validateOtnNode: unproper mode passed to the method : {} not supported", mode);
540 //            return null;
541 //        }
542     }
543
544     private ConstraintTypes validateNodeConstraints(PceNode pcenode) {
545         if (pceHardConstraints.getExcludeSupNodes().isEmpty() && pceHardConstraints.getExcludeCLLI().isEmpty()) {
546             return ConstraintTypes.NONE;
547         }
548         if (pceHardConstraints.getExcludeSupNodes().contains(pcenode.getSupNetworkNodeId())) {
549             LOG.info("validateNodeConstraints: {}", pcenode.getNodeId().getValue());
550             return ConstraintTypes.HARD_EXCLUDE;
551         }
552         if (pceHardConstraints.getExcludeCLLI().contains(pcenode.getSupClliNodeId())) {
553             LOG.info("validateNodeConstraints: {}", pcenode.getNodeId().getValue());
554             return ConstraintTypes.HARD_EXCLUDE;
555         }
556         return ConstraintTypes.NONE;
557     }
558
559     private ConstraintTypes validateLinkConstraints(PceLink link) {
560         if (pceHardConstraints.getExcludeSRLG().isEmpty()) {
561             return ConstraintTypes.NONE;
562         }
563
564         // for now SRLG is the only constraint for link
565         if (link.getlinkType() != OpenroadmLinkType.ROADMTOROADM) {
566             return ConstraintTypes.NONE;
567         }
568
569         List<Long> constraints = new ArrayList<>(pceHardConstraints.getExcludeSRLG());
570         constraints.retainAll(link.getsrlgList());
571         if (!constraints.isEmpty()) {
572             LOG.info("validateLinkConstraints: {}", link.getLinkId().getValue());
573             return ConstraintTypes.HARD_EXCLUDE;
574         }
575
576         return ConstraintTypes.NONE;
577     }
578
579     private void dropOppositeLink(Link link) {
580         LinkId opplink = MapUtils.extractOppositeLink(link);
581
582         if (allPceLinks.containsKey(opplink)) {
583             allPceLinks.remove(opplink);
584         } else {
585             linksToExclude.add(opplink);
586         }
587     }
588
589     private Boolean endPceNode(OpenroadmNodeType openroadmNodeType, NodeId nodeId, PceOpticalNode pceNode) {
590         switch (openroadmNodeType) {
591             case SRG:
592                 pceNode.initSrgTps();
593                 this.azSrgs.add(nodeId);
594                 break;
595             case XPONDER:
596                 pceNode.initXndrTps();
597                 break;
598             default:
599                 LOG.warn("endPceNode: Node {} is not SRG or XPONDER !", nodeId);
600                 return false;
601         }
602
603         if (!pceNode.isValid()) {
604             LOG.error("validateNode : there are no availaible wavelengths in node {}", pceNode.getNodeId().getValue());
605             return false;
606         }
607         return true;
608     }
609
610     public PceNode getaendPceNode() {
611         return aendPceNode;
612     }
613
614     public PceNode getzendPceNode() {
615         return zendPceNode;
616     }
617
618     public Map<NodeId, PceNode> getAllPceNodes() {
619         return this.allPceNodes;
620     }
621
622     public Map<LinkId, PceLink> getAllPceLinks() {
623         return this.allPceLinks;
624     }
625
626     public String getServiceType() {
627         return serviceType;
628     }
629
630     public PceResult getReturnStructure() {
631         return returnStructure;
632     }
633
634     private static void printNodesInfo(Map<NodeId, PceNode> allPceNodes) {
635         allPceNodes.forEach(((nodeId, pceNode) -> {
636             LOG.info("In printNodes in node {} : outgoing links {} ", pceNode.getNodeId().getValue(),
637                     pceNode.getOutgoingLinks());
638         }));
639     }
640 }