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