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