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