clean some compilation warnings
[transportpce.git] / tests / stubpce / src / main / java / org / opendaylight / transportpce / stubpce / topology / SuperNodePath.java
1 /*
2  * Copyright © 2017 Orange, 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.stubpce.topology;
10
11 import com.google.common.collect.Lists;
12 import java.util.ArrayList;
13 import java.util.List;
14 import java.util.ListIterator;
15 import java.util.SortedSet;
16 import java.util.TreeSet;
17 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubpce.rev170426.path.description.list.PathDescriptionsBuilder;
18 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.AToZDirection;
19 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.AToZDirectionBuilder;
20 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.ZToADirection;
21 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.ZToADirectionBuilder;
22 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.atoz.direction.AToZ;
23 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.atoz.direction.AToZBuilder;
24 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.atoz.direction.AToZKey;
25 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.ztoa.direction.ZToA;
26 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.ztoa.direction.ZToABuilder;
27 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.ztoa.direction.ZToAKey;
28 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.pce.resource.Resource;
29 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.pce.resource.ResourceBuilder;
30 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.pce.resource.resource.resource.Link;
31 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.pce.resource.resource.resource.LinkBuilder;
32 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.pce.resource.resource.resource.link.LinkIdentifierBuilder;
33 import org.slf4j.Logger;
34 import org.slf4j.LoggerFactory;
35
36
37 /**
38  * Class to build Path between
39  * two Supernode.
40  *
41  * @author <a href="mailto:martial.coulibaly@gfi.com">Martial Coulibaly</a> on
42  *         behalf of Orange
43  */
44 public class SuperNodePath {
45     /** Logging. */
46     private static final Logger LOG = LoggerFactory.getLogger(SuperNodePath.class);
47     /** List of NodeLinkNode. */
48     private List<NodeLinkNode> paths;
49     /** Supernode topology. */
50     private Network network;
51
52     /**
53      * SuperNodePath constructor.
54      *
55      * @param network Supernode topology
56      */
57     public SuperNodePath(Network network) {
58         setPaths(new ArrayList<NodeLinkNode>());
59         this.network = network;
60     }
61
62     /**
63      * test if Supernode is an
64      * extremity of path to build.
65      *
66      * @param end extremity node Id
67      * @param supernodes Supernodes list to build path
68      * @return true if link extremity, false else
69      */
70     private Boolean endNode(String end, List<String> supernodes) {
71         Boolean result = false;
72         if ((end != null) && (end.compareTo(" ") != 0)) {
73             for (String node : supernodes) {
74                 if (node.compareTo(end) == 0) {
75                     result = true;
76                     break;
77                 }
78             }
79         }
80         return result;
81     }
82
83     /**
84      * get Supernode
85      * with supernode Id.
86      *
87      * @param nodeId supernode id to get
88      * @return SuperNode supernode gets
89      */
90     public SuperNode getSuperNode(String nodeId) {
91         SuperNode result = null;
92         if (this.network != null) {
93             for (SuperNode tmp : this.network.getSuperNodes()) {
94                 if (tmp.getSuperNodeId().compareTo(nodeId) == 0) {
95                     result = tmp;
96                     break;
97                 }
98             }
99         }
100         return result;
101     }
102
103     /**
104      *find links between
105      *two Supernodes.
106      *
107      * @param aend begin extremity
108      * @param zend end extremity
109      * @param links Roadm to Roadm links
110      * @param direct determine if link is direct or not
111      * @return String list of links name
112      */
113     private List<String> findLinks(String aend, String zend, List<String> links, boolean direct) {
114         List<String> result = new ArrayList<String>();
115         if (links.size() > 0) {
116             aend = aend.replace("Node", "ROADM");
117             zend = zend.replace("Node", "ROADM");
118             String atozlink = null;
119             String ztoalink = null;
120             for (String tmp : links) {
121                 if (tmp.contains(aend)
122                         && tmp.contains(zend)) {
123                     LOG.info("direct path found for : {} / {}", aend, zend);
124                     if (tmp.startsWith(aend)) {
125                         atozlink = tmp;
126                     }
127                     if (tmp.startsWith(zend)) {
128                         ztoalink = tmp;
129                     }
130                     if ((atozlink != null) && (ztoalink != null)) {
131                         result.add(atozlink.concat("/").concat(ztoalink));
132                         atozlink = null;
133                         ztoalink = null;
134                     }
135                 }
136             }
137         } else {
138             LOG.info("no roadm-to-roadm links !");
139         }
140         return result;
141     }
142
143     /**
144      *find next Supernode hop.
145      *
146      * @param link roadm to roadm link
147      * @param aend begin supernode
148      * @param node list of supernode id
149      * @return String  supernodeId next hop
150      */
151     private String findHop(String link, String aend, List<String> node) {
152         String result = null;
153         aend = aend.replace("Node", "ROADM");
154         for (String tmp : node) {
155             tmp = tmp.replace("Node", "ROADM");
156             if (tmp.compareTo(aend) != 0) {
157                 if (link.contains(aend) && link.contains(tmp)) {
158                     LOG.info("hop : {}", tmp);
159                     result = tmp;
160                 }
161             }
162         }
163         return result;
164     }
165
166     /**
167      *get all Supernode in
168      *topology.
169      *
170      * @return String list of Supernode Id
171      */
172     private List<String> getSuperNodeId() {
173         List<String> result = new ArrayList<String>();
174         if (this.network.getSuperNodes().size() > 0) {
175             for (SuperNode tmp : this.network.getSuperNodes()) {
176                 result.add(tmp.getSuperNodeId());
177             }
178         }
179         return result;
180     }
181
182     /**
183      * get all roadm to roadm
184      * links in topology.
185      *
186      * @return String list of roadm to roadm links
187      */
188     private List<String> getRoadmLinks() {
189         List<String> result = new ArrayList<String>();
190         if (this.network.getRoadmToroadm().getLinks().size() > 0) {
191             for (String tmp : this.network.getRoadmToroadm().getLinks()) {
192                 result.add(tmp);
193             }
194         }
195         return result;
196     }
197
198     /**
199      * create NodeLinkNode
200      * structure.
201      *
202      * @param links String list of roadm to roadm links
203      * @param aend beginning Supernode
204      * @param zend ending Supernode
205      * @param direct determine if link is direct or not
206      */
207     private void fill(List<String> links,String aend, String zend, boolean direct) {
208         String term = "indirect";
209         if (direct) {
210             term = "direct";
211         }
212         if (!links.isEmpty()) {
213             List<String> atoz = new ArrayList<String>();
214             List<String> ztoa = new ArrayList<String>();
215             for (String tmp : links) {
216                 String [] split = tmp.split("/");
217                 if (split.length == 2) {
218                     atoz.add(split[0]);
219                     ztoa.add(split[1]);
220                 }
221             }
222             if (!atoz.isEmpty() && (atoz.size() == ztoa.size())) {
223                 NodeLinkNode node = new NodeLinkNode(aend, zend, atoz,ztoa,direct);
224                 this.paths.add(node);
225             }
226
227         } else {
228             LOG.info("{} links not found !", term);
229         }
230     }
231
232     /**
233      * launch SupernodePath process
234      * to build NodeLinkNode.
235      *
236      * @param aend beginning extremity path
237      * @param zend ending extremity path
238      */
239     public void run(String aend, String zend) {
240         if (this.network != null) {
241             List<String> supernodes = getSuperNodeId();
242             List<String> roadmLinks = getRoadmLinks();
243             if ((aend != null) && (zend != null)) {
244                 int size = supernodes.size();
245                 String hop = null;
246                 List<String> links = null;
247                 if (size > 0) {
248                     if (endNode(aend, supernodes) && endNode(zend, supernodes)) {
249                         LOG.info("Getting direct links ...");
250                         links = new ArrayList<String>();
251                         links = findLinks(aend,zend,roadmLinks,true);
252                         fill(links, aend, zend, true);
253                         LOG.info("Getting indirect links ..");
254                         links = new ArrayList<String>();
255                         for (String tmp : roadmLinks) {
256                             hop = findHop(tmp, aend, supernodes);
257                             if (hop != null) {
258                                 if (hop.compareTo(zend.replace("Node", "ROADM")) != 0) {
259                                     LOG.info("next hop found : {}", hop);
260                                     links.addAll(findLinks(aend,hop,roadmLinks,false));
261                                     links.addAll(findLinks(hop,zend,roadmLinks,false));
262                                 } else {
263                                     break;
264                                 }
265                             }
266                         }
267                         fill(links, aend, zend, false);
268                     } else {
269                         LOG.info("aend or/and zend not exists !");
270                     }
271                 }
272             } else {
273                 LOG.info("aend or/and is null !");
274             }
275         } else {
276             LOG.info("network is null !!");
277         }
278     }
279
280     /**
281      * modify all AToZ Id
282      * in AToZ List containing
283      * in AToZdirection.
284      *
285      * @param order beginning order
286      * @param atozDirection AToZdirection List
287      * @return AToZdirection List
288      */
289     public List<AToZDirection> modifyOrder(int order, List<AToZDirection> atozDirection) {
290         List<AToZDirection> result = new ArrayList<AToZDirection>();
291         for (AToZDirection tmp : atozDirection) {
292             List<AToZ> atozList = tmp.getAToZ();
293             int size = atozList.size();
294             if (size > 0) {
295                 for (ListIterator<AToZ> it = atozList.listIterator(); it.hasNext();) {
296                     AToZ atoz = it.next();
297                     org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription
298                         .rev170426.pce.resource.resource.Resource res = atoz.getResource().getResource();
299                     int tmpkey = order + Integer.parseInt(atoz.key().getId());
300                     AToZKey atozKey = new AToZKey(Integer.toString(tmpkey));
301                     org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface
302                         .pathdescription.rev170426.pce.resource.Resource resource = new ResourceBuilder()
303                         .setResource(res).build();
304                     AToZ hop = new AToZBuilder().setId(atozKey.getId()).withKey(atozKey).setResource(resource).build();
305                     it.remove();
306                     it.add(hop);
307                     tmpkey++;
308                 }
309                 result.add(tmp);
310             }
311         }
312         return result;
313     }
314
315     /**
316      * merge two AToZdirection List.
317      *
318      * @param cleanInterA first AToZdirection List
319      * @param cleanInterZ second AToZdirection List
320      * @param first boolean to determine if it is the first time merge is done
321      * @return AToZDirection List
322      */
323     public List<AToZDirection> merge(List<AToZDirection> cleanInterA, List<AToZDirection> cleanInterZ,
324             boolean first) {
325         List<AToZDirection> result = new ArrayList<AToZDirection>();
326         if (!cleanInterA.isEmpty()) {
327             int order  = cleanInterA.get(0).getAToZ().size();
328             if (order > 0) {
329                 List<AToZDirection> modify = modifyOrder(order, cleanInterZ);
330                 if (!modify.isEmpty()) {
331                     for (AToZDirection tmp : cleanInterA) {
332                         List<AToZ> atozList = new ArrayList<AToZ>(tmp.getAToZ());
333                         for (AToZDirection add : modify) {
334                             ListIterator<AToZ> it = atozList.listIterator();
335                             /** on va a la fin de la liste */
336                             while (it.hasNext()) {
337                                 it.next();
338                             }
339                             List<AToZ> addList = add.getAToZ();
340                             for (AToZ atoz : addList) {
341                                 it.add(atoz);
342                             }
343                             AToZDirectionBuilder newDirection = new AToZDirectionBuilder();
344                             newDirection.setRate((long) 100).setAToZWavelengthNumber((long) 200).setAToZ(atozList);
345                             result.add(newDirection.build());
346                             atozList = new ArrayList<AToZ>(tmp.getAToZ());
347                         }
348                     }
349                 } else {
350                     LOG.info("modify List is empty ! ");
351                 }
352             } else {
353                 LOG.info("order is not superior to 0");
354             }
355         } else {
356             if (first && !cleanInterZ.isEmpty()) {
357                 LOG.info("first merge so result is a copy of second AToZDirection List !");
358                 result = new ArrayList<AToZDirection>(cleanInterZ);
359             } else {
360                 LOG.info("cleanInterA is empty !");
361             }
362         }
363         return result;
364     }
365
366     /**
367      * gets Degree number
368      * for roadm links.
369      *
370      * @param atozLink atoz roadm link
371      * @param ztoaLink ztoa roadm link
372      * @return String list of degree
373      */
374     public List<String> getDeg(String atozLink, String ztoaLink) {
375         List<String> result = new ArrayList<String>();
376         if ((atozLink != null) && (ztoaLink != null)) {
377             String [] split = atozLink.split("-", 4);
378             if (split.length == 4) {
379                 result = Lists.newArrayList(split[1],split[3]);
380             }
381         } else {
382             LOG.info("atozlink and/or ztoalink is null !");
383         }
384         return result;
385     }
386
387     /**
388      * reverse link name
389      * (ROADMA-DEG1-ROADMZ-DEG2
390      * to
391      * ROADMZ-DEG2-ROADMA-DEG1).
392      *
393      * @param linkId Link name
394      * @return String link name reversed
395      */
396     public String reverseLinkId(String linkId) {
397         StringBuilder builder = new StringBuilder();
398         String [] split = linkId.split("-");
399         int size = split.length;
400         switch (size) {
401             case 3:
402                 if (linkId.contains("XPDR")) {
403                     if (linkId.startsWith("XPDR")) {
404                         builder.append(split[1]).append("-")
405                         .append(split[2]).append("-")
406                         .append(split[0]);
407                     } else {
408                         builder.append(split[2]).append("-")
409                         .append(split[0]).append("-")
410                         .append(split[1]);
411                     }
412                 }
413                 break;
414
415             case 4:
416                 builder.append(split[2]).append("-")
417                 .append(split[3]).append("-")
418                 .append(split[0]).append("-")
419                 .append(split[1]);
420                 break;
421
422             default:
423                 break;
424         }
425         return builder.toString();
426     }
427
428     /**
429      * convert AToAdirection to
430      * ZToAdirection.
431      *
432      * @param atozDirection AToZdirection to convert
433      * @return ZToAdirection
434      */
435     public ZToADirection convertToZtoaDirection(AToZDirection atozDirection) {
436         ZToADirectionBuilder ztoaDirection = new ZToADirectionBuilder();
437         if (atozDirection != null) {
438             List<AToZ> atozList = atozDirection.getAToZ();
439             List<ZToA> ztoaList = new ArrayList<ZToA>();
440             if (!atozList.isEmpty()) {
441                 List<AToZ> reverse = Lists.reverse(atozList);
442                 /** Building path. */
443                 ZToAKey ztoaKey = null;
444                 Resource resource = null;
445                 org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription
446                     .rev170426.pce.resource.resource.Resource resLink = null;
447                 ZToA hop = null;
448                 int odr = 0;
449                 for (AToZ atoz : reverse) {
450                     ztoaKey = new ZToAKey(Integer.toString(odr));
451                     resLink = atoz.getResource().getResource();
452                     if (resLink != null) {
453                         if (resLink instanceof Link) {
454                             Link link = (Link) resLink;
455                             String newLinkId = reverseLinkId(link.getLinkIdentifier().getLinkId());
456                             if (newLinkId != null) {
457                                 resource = new ResourceBuilder().setResource(new LinkBuilder()
458                                         .setLinkIdentifier(new LinkIdentifierBuilder()
459                                                 .setLinkId(newLinkId)
460                                                 .build())
461                                         .build())
462                                     .build();
463                             }
464
465                         } else {
466                             resource = new ResourceBuilder().setResource(resLink).build();
467                         }
468                     }
469                     if (resource != null) {
470                         hop = new ZToABuilder()
471                                 .withKey(ztoaKey)
472                                 .setResource(resource)
473                                 .build();
474                         ztoaList.add(hop);
475                         odr++;
476                     } else {
477                         LOG.info("resource is null ");
478                     }
479                 }
480                 if (!ztoaList.isEmpty()) {
481                     ztoaDirection.setRate((long) 100).setZToAWavelengthNumber((long) 200).setZToA(ztoaList);
482                 } else {
483                     LOG.info("ztoaList is empty !");
484                 }
485             }
486         }
487         return ztoaDirection.build();
488     }
489
490     /**
491      *build Pathdescritions ordered List
492      *to be loaded in Pathdescriptions
493      *datastore.
494      *
495      * @param atozDirection AToZdirection List
496      * @param term direct ou indirect
497      * @return PathDescriptionsOrdered List
498      */
499     private SortedSet<PathDescriptionsOrdered> buildPathDescription(List<AToZDirection> atozDirection, String term) {
500         SortedSet<PathDescriptionsOrdered> result = new TreeSet<PathDescriptionsOrdered>();
501         PathDescriptionsBuilder pathDescr = new PathDescriptionsBuilder();
502         int size = atozDirection.size();
503         if (!atozDirection.isEmpty()) {
504             LOG.info("result list AToZDirection size  : {}", atozDirection.size());
505             List<ZToADirection> ztoadirList = new ArrayList<ZToADirection>();
506             for (AToZDirection atozdir : atozDirection) {
507                 ZToADirection ztodir = convertToZtoaDirection(atozdir);
508                 if (ztodir != null) {
509                     ztoadirList.add(ztodir);
510                 }
511             }
512             if (!ztoadirList.isEmpty() && (size == ztoadirList.size())) {
513                 LOG.info("building PathDescriptions ...");
514                 int index = 1;
515                 String pathName = null;
516                 for (int indexPath = 0 ; indexPath < size ; indexPath++) {
517                     pathName = term.concat(Integer.toString(index));
518                     LOG.info("pathName : {}", pathName);
519                     pathDescr.setAToZDirection(atozDirection.get(indexPath))
520                     .setZToADirection(ztoadirList.get(indexPath)).setPathName(pathName);
521                     LOG.info("pathdesciption : {}", pathDescr.build().toString());
522                     result.add(new PathDescriptionsOrdered(pathDescr.build(),index));
523                     index++;
524                 }
525             } else {
526                 LOG.info("Something wrong happen during atodir conversion...");
527             }
528
529         } else {
530             LOG.info("atozDirection is empty");
531         }
532         return result;
533     }
534
535     /**
536      * gets link extremity.
537      *
538      * @param link link
539      * @return Supernode List of extremities
540      */
541     public List<SuperNode> getSuperNodeEndLink(String link) {
542         List<SuperNode> result = new ArrayList<SuperNode>();
543         if (link != null) {
544             String [] split = link.split("-");
545             if (split.length == 4) {
546                 String aend = split[0].replaceAll("ROADM", "Node");
547                 String zend = split[2].replaceAll("ROADM", "Node");
548                 if ((aend != null) && (zend != null)) {
549                     LOG.info("getting super node for : {} and {}", aend, zend);
550                     SuperNode aendSp = getSuperNode(aend);
551                     SuperNode zendSp = getSuperNode(zend);
552                     if ((aendSp != null) && (zendSp != null)) {
553                         result.add(aendSp);
554                         result.add(zendSp);
555                     }
556                 }
557             }
558         }
559         return result;
560     }
561
562     /**
563      * build all direct paths.
564      *
565      * @param aend beginning extremity path
566      * @param zend ending extremity path
567      * @param paths NodeLinkNode list paths
568      * @return PathDescriptionsOrdered List of direct paths
569      */
570     public SortedSet<PathDescriptionsOrdered> getDirectPathDesc(String aend, String zend,
571             List<NodeLinkNode> nodeLinkNodes) {
572         List<AToZDirection> atozdirectionPaths = new ArrayList<AToZDirection>();
573         SortedSet<PathDescriptionsOrdered> result = new TreeSet<PathDescriptionsOrdered>();
574         SuperNode aendSp = getSuperNode(aend);
575         SuperNode zendSp = getSuperNode(zend);
576         if (!nodeLinkNodes.isEmpty()) {
577             for (NodeLinkNode tmp : nodeLinkNodes) {
578                 if (tmp.getDirect()) {
579                     LOG.info("Direct NodeLinkNode : {}", tmp.toString());
580                     String atozLink = null;
581                     String ztoaLink = null;
582                     atozLink = tmp.getAtozLink().get(0);
583                     ztoaLink = tmp.getZtoaLink().get(0);
584                     if ((atozLink != null) && (ztoaLink != null)) {
585                         LOG.info("atozlink : {}", atozLink);
586                         LOG.info("ztoalink : {}", ztoaLink);
587                         InterNodePath interAend = new InterNodePath(aendSp);
588                         interAend.buildPath(zend);
589                         InterNodePath interZend = new InterNodePath(zendSp);
590                         interZend.buildPath(zend);
591                         List<String> deg = getDeg(atozLink,ztoaLink);
592                         LOG.info("deg : {}", deg.toString());
593                         if (deg.size() == 2) {
594                             List<AToZDirection> cleanInterA =
595                                     interAend.replaceOrRemoveAToZDirectionEndLink(deg.get(0),"",atozLink,
596                                             interAend.getAtoz(),false);
597                             List<AToZDirection> cleanInterZ =
598                                     interZend.replaceOrRemoveAToZDirectionEndLink("TAIL-LINKS",deg.get(1),"",
599                                             interZend.getAtoz(),true);
600                             if (!cleanInterA.isEmpty() && !cleanInterZ.isEmpty()) {
601                                 atozdirectionPaths.addAll(merge(cleanInterA,cleanInterZ,false));
602                             } else {
603                                 LOG.info("cleanInterA ad/or cleanInterZ is empty !");
604                             }
605                         } else {
606                             LOG.info("deg size is not correct, must be 2 ! ");
607                         }
608                     } else {
609                         LOG.info("atozlink and / or ztoalink is null");
610                     }
611                 }
612             }
613
614         } else {
615             LOG.info("List of direct path is empty !");
616         }
617         if (!atozdirectionPaths.isEmpty()) {
618             LOG.info("result size : {}", result.size());
619             result = buildPathDescription(atozdirectionPaths,aend.concat("To").concat(zend).concat("_direct_"));
620         } else {
621             LOG.info("result is empty");
622         }
623         return result;
624     }
625
626     /**
627      * build all indirect paths.
628      *
629      * @param aend beginning extremity path
630      * @param zend ending extremity path
631      * @param paths NodeLinkNode list paths
632      * @return PathDescriptionsOrdered List of indirect paths
633      */
634     public SortedSet<PathDescriptionsOrdered> getIndirectPathDesc(String aend, String zend,
635             List<NodeLinkNode> nodeLinkNodes) {
636         List<AToZDirection> atozdirectionPaths = new ArrayList<AToZDirection>();
637         SortedSet<PathDescriptionsOrdered> result = new TreeSet<PathDescriptionsOrdered>();
638         SuperNode aendSp = getSuperNode(aend);
639         SuperNode zendSp = getSuperNode(zend);
640         if (!nodeLinkNodes.isEmpty()) {
641             for (NodeLinkNode tmp : nodeLinkNodes) {
642                 if (!tmp.getDirect()) {
643                     LOG.info("Indirect NodeLinkNode : {}", tmp.toString());
644                     int size = tmp.getAtozLink().size();
645                     /** must be two for now just one hop. */
646                     LOG.info("number of links  : {}", size);
647                     boolean first = true;
648                     if (size == 2) {
649                         List<String> atozLinks = tmp.getAtozLink();
650                         List<String> ztoaLinks = tmp.getZtoaLink();
651                         if (!atozLinks.isEmpty() && !ztoaLinks.isEmpty()) {
652                             LOG.info("atozlink : {}", atozLinks.toString());
653                             LOG.info("ztoalink : {}", ztoaLinks.toString());
654                             int loop = 0;
655                             while (loop < 2) {
656                                 List<SuperNode> hop = getSuperNodeEndLink(atozLinks.get(loop));
657                                 if (!hop.isEmpty() && (hop.size() == 2)) {
658                                     aendSp = hop.get(0);
659                                     zendSp = hop.get(1);
660                                     InterNodePath interAend = new InterNodePath(aendSp);
661                                     interAend.buildPath(zend);
662                                     LOG.info("interAend : {}", interAend.getAtoz().toString());
663                                     InterNodePath interZend = new InterNodePath(zendSp);
664                                     interZend.buildPath(zend);
665                                     LOG.info("interZend : {}", interZend.getAtoz().toString());
666                                     List<String> deg1 = getDeg(atozLinks.get(loop),ztoaLinks.get(loop));
667                                     LOG.info("deg1 : {}", deg1.toString());
668                                     if (!deg1.isEmpty() && (deg1.size() == 2)) {
669                                         List<AToZDirection> cleanInterA = null;
670                                         List<AToZDirection> cleanInterZ = null;
671                                         if (zendSp.getSuperNodeId().compareTo(zend) == 0) {
672                                             cleanInterA = interAend.replaceOrRemoveAToZDirectionEndLink(deg1.get(0),
673                                                     "",atozLinks.get(loop),interAend.getAtoz(),false);
674                                             LOG.info("next hop is zend");
675                                             cleanInterZ = interZend.replaceOrRemoveAToZDirectionEndLink("TAIL-LINKS",
676                                                     deg1.get(1),"",interZend.getAtoz(),true);
677                                         } else if (loop < 1) {
678                                             cleanInterA = interAend.replaceOrRemoveAToZDirectionEndLink(deg1.get(0),
679                                                     "",atozLinks.get(loop),interAend.getAtoz(),false);
680                                             cleanInterZ = interZend.getAToZDirectionEndBy(deg1.get(1),
681                                                     interZend.getAtoz(), 1);
682                                         }
683                                         if (!cleanInterA.isEmpty() && !cleanInterZ.isEmpty()) {
684                                             atozdirectionPaths = merge(atozdirectionPaths,cleanInterA,first);
685                                             atozdirectionPaths = merge(atozdirectionPaths, cleanInterZ,false);
686                                             first = false;
687                                         } else {
688                                             LOG.info("cleanInterA ad/or cleanInterZ is empty !");
689                                             break;
690                                         }
691                                     }
692                                 } else {
693                                     LOG.info("Hop list is empty");
694                                 }
695                                 loop++;
696                             }
697                         }
698                     } else {
699                         LOG.info("Link size is not supported , must be two !");
700                     }
701                 }
702             }
703         } else {
704             LOG.info("List of indirect path is empty !");
705         }
706         if (!atozdirectionPaths.isEmpty()) {
707             LOG.info("result size : {}", result.size());
708             result = buildPathDescription(atozdirectionPaths,aend.concat("To").concat(zend).concat("_indirect_"));
709         } else {
710             LOG.info("result is empty");
711         }
712         return result;
713     }
714
715     public static void main(String[] args) {
716         Topology topo = new Topology();
717         topo.start();
718         SuperNodePath path = new SuperNodePath(topo.getNetwork());
719         String aend = "NodeA";
720         String zend = "NodeZ";
721         path.run(aend, zend);
722         path.getDirectPathDesc(aend, zend, path.getPaths());
723         path.getIndirectPathDesc(aend, zend, path.getPaths());
724     }
725
726     public List<NodeLinkNode> getPaths() {
727         return this.paths;
728     }
729
730     public void setPaths(List<NodeLinkNode> paths) {
731         this.paths = paths;
732     }
733 }