Pathdescription Update
[transportpce.git] / tests / stubpce / src / main / java / org / opendaylight / transportpce / stubpce / SendingPceRPCs.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
10 package org.opendaylight.transportpce.stubpce;
11
12 import com.google.common.base.Optional;
13 import com.google.common.util.concurrent.Futures;
14 import com.google.common.util.concurrent.ListenableFuture;
15 import com.google.common.util.concurrent.ListeningExecutorService;
16
17 import java.util.ArrayList;
18 import java.util.Iterator;
19 import java.util.List;
20 import java.util.ListIterator;
21 import java.util.SortedSet;
22 import java.util.TreeSet;
23 import java.util.concurrent.Callable;
24 import java.util.concurrent.ExecutionException;
25 import java.util.concurrent.Future;
26 import java.util.concurrent.TimeUnit;
27
28 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
29 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
30 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
31 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
32 import org.opendaylight.transportpce.stubpce.topology.PathDescriptionsOrdered;
33 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubpce.rev170426.CancelResourceReserveInput;
34 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubpce.rev170426.PathComputationRequestInput;
35 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubpce.rev170426.PathDescriptionList;
36 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubpce.rev170426.ServicePathList;
37 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubpce.rev170426.path.description.list.PathDescriptions;
38 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubpce.rev170426.service.path.list.ServicePaths;
39 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubpce.rev170426.service.path.list.ServicePathsBuilder;
40 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubpce.rev170426.service.path.list.ServicePathsKey;
41 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubpce.rev170426.service.path.rpc.result.PathDescriptionBuilder;
42 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.AToZDirection;
43 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.ZToADirection;
44 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.atoz.direction.AToZ;
45 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.pce.resource.resource.Resource;
46 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.pce.resource.resource.resource.Link;
47 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.pce.resource.resource.resource.Node;
48 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.pce.resource.resource.resource.TerminationPoint;
49 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev170426.constraints.sp.co.routing.or.general.General;
50 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev170426.constraints.sp.co.routing.or.general.general.Diversity;
51 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev170426.constraints.sp.co.routing.or.general.general.Exclude;
52 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev170426.routing.constraints.sp.HardConstraints;
53 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev170426.routing.constraints.sp.SoftConstraints;
54 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev170426.service.handler.header.ServiceHandlerHeaderBuilder;
55 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev170426.service.path.ServiceAEnd;
56 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev170426.service.path.ServiceZEnd;
57 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
58 import org.slf4j.Logger;
59 import org.slf4j.LoggerFactory;
60
61 /**
62  * Class for Sending
63  * PCE requests :
64  * - path-computation-request
65  * - cancel-resource-reserve.
66  * @author <a href="mailto:martial.coulibaly@gfi.com">Martial Coulibaly</a> on behalf of Orange
67  *
68  */
69 public class SendingPceRPCs {
70     /** Logging. */
71     private static final Logger LOG = LoggerFactory.getLogger(SendingPceRPCs.class);
72     private Boolean success;
73     private PathComputationRequestInput input;
74     private CancelResourceReserveInput cancelInput;
75     private PathDescriptionBuilder pathDescription;
76     private DataBroker db;
77     private String error;
78     private final ListeningExecutorService executor;
79     private List<ServicePaths> servicePathList;
80
81     public SendingPceRPCs() {
82         success = true;
83         setPathDescription(null);
84         setError("");
85         executor = null;
86         setServicePathList(new ArrayList<ServicePaths>());
87     }
88
89     public SendingPceRPCs(PathComputationRequestInput input,DataBroker databroker,ListeningExecutorService executor) {
90         success = true;
91         setPathDescription(null);
92         setInput(input);
93         setCancelInput(null);
94         setDb(databroker);
95         setError("");
96         servicePathList = readServicePathList();
97         this.executor = executor;
98     }
99
100     public SendingPceRPCs(CancelResourceReserveInput input,DataBroker databroker,ListeningExecutorService executor) {
101         success = true;
102         setPathDescription(null);
103         setInput(null);
104         setCancelInput(input);
105         setDb(databroker);
106         setError("");
107         servicePathList = readServicePathList();
108         this.executor = executor;
109     }
110
111     /**
112      * Compare AEnd and ZEnd resource Node to
113      * AEnd and ZEnd String.
114      *
115      * @param pathAend AEnd resource Node
116      * @param pathZend ZEnd resource Node
117      * @param inputAend AEnd String Node
118      * @param inputZend ZEnd String Node
119      * @return Boolean result true if equal, false if not
120      */
121     private Boolean comp(Resource pathAend, Resource pathZend, String inputAend, String inputZend) {
122         Boolean result = false;
123         if (pathAend != null && pathZend != null && inputAend != null && inputZend != null) {
124             if (pathAend instanceof Node && pathZend instanceof Node) {
125                 Node aend = (Node) pathAend;
126                 Node zend = (Node) pathZend;
127                 if (aend.getNodeIdentifier().getNodeId().compareToIgnoreCase(inputAend) == 0) {
128                     if (zend.getNodeIdentifier().getNodeId().compareToIgnoreCase(inputZend) == 0) {
129                         result = true;
130                     }
131                 }
132             }
133         }
134         return result;
135     }
136
137     /**
138      * Compare two resource.
139      *
140      * @param res1 first resource
141      * @param res2 second resource
142      * @return Boolean result true if equal, false if not
143      */
144     private Boolean egalResource(Resource res1, Resource res2) {
145         LOG.info("comparing resource ...");
146         Boolean result = false;
147         LOG.info("{} - {}", res1.getClass().getName(), res2.getClass().getName());
148         if (res1.getClass().getName().compareToIgnoreCase(res2.getClass().getName()) == 0) {
149             if (res1 instanceof Node && res2 instanceof Node) {
150                 Node node1 = (Node)res1;
151                 Node node2 = (Node)res2;
152                 if (node1.getNodeIdentifier().getNodeId()
153                         .compareTo(node2.getNodeIdentifier().getNodeId()) == 0) {
154                     result = true;
155                 }
156             }
157             if (res1 instanceof TerminationPoint && res2 instanceof TerminationPoint) {
158                 TerminationPoint tp1 = (TerminationPoint)res1;
159                 TerminationPoint tp2 = (TerminationPoint)res2;
160                 if (tp1.getTerminationPointIdentifier().getNodeId()
161                         .compareTo(tp2.getTerminationPointIdentifier().getNodeId()) == 0) {
162                     if (tp1.getTerminationPointIdentifier().getTpId()
163                             .compareTo(tp2.getTerminationPointIdentifier().getTpId()) == 0) {
164                         result = true;
165                     }
166                 }
167             }
168             if (res1 instanceof Link && res2 instanceof Link) {
169                 Link link1 = (Link)res1;
170                 Link link2 = (Link)res2;
171                 if (link1.getLinkIdentifier().getLinkId().compareTo(link2.getLinkIdentifier().getLinkId()) == 0) {
172                     result = true;
173                 }
174
175             }
176         }
177         return result;
178     }
179
180     /**
181      *  compare two AtoZDirection.
182      *
183      * @param atoz1 first AToZDirection
184      * @param atoz2 second AToZDirection
185      * @return Boolean result true if equal, false if not
186      */
187     private Boolean egalAtoZDirection(AToZDirection atoz1, AToZDirection atoz2) {
188         LOG.info("comparing AtoZDirection ...");
189         Boolean result = true;
190         if (atoz1.getAToZ().size() == atoz2.getAToZ().size()) {
191             int index = 0;
192             int size = atoz1.getAToZ().size();
193             LOG.info("size : {}", size);
194             String id1 = null;
195             String id2 = null;
196             while (index < size) {
197                 id1 = atoz1.getAToZ().get(index).getId();
198                 LOG.info("id : {}", id1);
199                 Resource res1 = atoz1.getAToZ().get(index).getResource().getResource();
200                 LOG.info("res1 : {}", res1.toString());
201                 Resource res2 = null;
202                 if (id1 != null) {
203                     Boolean trouve = false;
204                     for (int loop = 0;loop < size;loop++) {
205                         id2 = atoz2.getAToZ().get(loop).getId();
206                         if (id2 != null && id2.compareTo(id1) == 0) {
207                             res2 = atoz2.getAToZ().get(loop).getResource().getResource();
208                             LOG.info("res2 : {}", res2.toString());
209                             trouve = true;
210                             break;
211                         }
212                     }
213                     if (trouve) {
214                         if (!egalResource(res1, res2)) {
215                             result = false;
216                             break;
217                         }
218                     }
219                 } else {
220                     result = false;
221                     break;
222                 }
223                 index++;
224             }
225         } else {
226             LOG.info("AToZDirection size is not equal !");
227             result = false;
228         }
229         return result;
230     }
231
232     /**
233      *  compare two ZtoZDirection.
234      *
235      * @param ztoa1 first ZToZDirection
236      * @param ztoa2 second ZToZDirection
237      * @return Boolean result true if equal, false if not
238      */
239     private Boolean egalZtoADirection(ZToADirection ztoa1, ZToADirection ztoa2) {
240         LOG.info("comparing ZtoADirection ...");
241         Boolean result = true;
242         if (ztoa1.getZToA().size() == ztoa2.getZToA().size()) {
243             int index = 0;
244             int size = ztoa1.getZToA().size();
245             LOG.info("size : {}", size);
246             String id1 = null;
247             String id2 = null;
248             while (index < size) {
249                 id1 = ztoa1.getZToA().get(index).getId();
250                 LOG.info("id : {}", id1);
251                 Resource res1 = ztoa1.getZToA().get(index).getResource().getResource();
252                 LOG.info("res1 : {}", res1.toString());
253                 Resource res2 = null;
254                 if (id1 != null) {
255                     Boolean trouve = false;
256                     for (int loop = 0;loop < size;loop++) {
257                         id2 = ztoa2.getZToA().get(loop).getId();
258                         if (id2 != null && id2.compareTo(id1) == 0) {
259                             res2 = ztoa2.getZToA().get(loop).getResource().getResource();
260                             LOG.info("res2 : {}", res2.toString());
261                             trouve = true;
262                             break;
263                         }
264                     }
265                     if (trouve) {
266                         if (!egalResource(res1, res2)) {
267                             result = false;
268                             break;
269                         }
270                     }
271                 } else {
272                     result = false;
273                     break;
274                 }
275                 index++;
276             }
277         } else {
278             result = false;
279         }
280         return result;
281     }
282
283     /**
284      * Test if resources Nodes
285      * not include in PathDescriptions.
286      *
287      * @param path PathDescriptions
288      * @param nodes Nodes List
289      * @return Boolean result true if found, false if not
290      */
291     private Boolean excludeNode(PathDescriptions path, List<String> nodes) {
292         LOG.info("Testing exclude Nodes ...");
293         Boolean result = false;
294         if (path != null && !nodes.isEmpty()) {
295             List<AToZ> list = path.getAToZDirection().getAToZ();
296             if (!list.isEmpty()) {
297                 int index = 0;
298                 boolean found = false;
299                 while (index < list.size() && !found) {
300                     Resource res = list.get(index).getResource().getResource();
301                     if (res != null && res instanceof Node) {
302                         Node node = (Node) res;
303                         for (String exclude : nodes) {
304                             if (exclude.compareToIgnoreCase(node.getNodeIdentifier().getNodeId()) == 0) {
305                                 LOG.info("Node not excluded !");
306                                 found = true;
307                                 break;
308                             }
309                         }
310                     }
311                     index++;
312                 }
313                 if (!found) {
314                     result = true;
315                 }
316             }
317         } else {
318             LOG.info("exclude parameters not corrrect !");
319         }
320         return result;
321     }
322
323     /**
324      * check if existing services not
325      * in pathDescriptions.
326      *
327      *
328      * @param existingService existing service list
329      * @param path PathDescriptions
330      * @param choice 0:Nodes, 1:Clli, 2:Srlg
331      * @return Boolean result true if found, false if not
332      */
333     private Boolean diversityService(List<String> existingService, PathDescriptions path, int choice) {
334         LOG.info("Testing diversity ...");
335         Boolean result = false;
336         if (path != null && choice >= 0 && !existingService.isEmpty()) {
337             int index = 0;
338             while (index < existingService.size()) {
339                 String tmp = existingService.get(index);
340                 if (tmp != null) {
341                     org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service
342                         .types.rev170426.service.path.PathDescription pathDesc = null;
343                     if (servicePathList != null && !servicePathList.isEmpty()) {
344                         for (ServicePaths service : servicePathList) {
345                             if (service.getServicePathName().compareTo(tmp) == 0) {
346                                 LOG.info("Existing Service '{}' found in ServicePathList ...", tmp);
347                                 pathDesc = service.getPathDescription();
348                             }
349                         }
350                     }
351                     if (pathDesc != null) {
352                         switch (choice) {
353                             case 0: //Nodes
354                                 LOG.info("Checking Node existing-service-applicability ...");
355                                 if (!egalAtoZDirection(path.getAToZDirection(), pathDesc.getAToZDirection())) {
356                                     result = true;
357                                     break;
358                                 }
359                                 break;
360                             case 1: //Clli
361                                 LOG.info("Checking clli existing-service-applicability ...");
362                                 break;
363
364                             case 2: //Srlg
365                                 LOG.info("Checking srlg existing-service-applicability ...");
366
367                                 break;
368                             default:
369                                 break;
370                         }
371                     } else {
372                         LOG.info("Existing Service '{}' not found in ServicePathList !", tmp);
373                         result = true;
374                     }
375                     if (!result) {
376                         break;
377                     }
378                 }
379                 index++;
380             }
381         } else {
382             LOG.info("Diversity parameters not coherent !");
383         }
384         return result;
385     }
386
387     /**
388      * test if pathDescription
389      * already exists in ServicePathList.
390      *
391      * @param path PathDescriptions
392      * @return <code>Boolean</code> result
393      */
394     private Boolean testPathDescription(PathDescriptions path) {
395         LOG.info("Testing pathDescription ...");
396         Boolean result = false;
397         if (path != null) {
398             LOG.info("retrieving path from servicePath List ...");
399             try {
400                 if (!servicePathList.isEmpty()) {
401                     LOG.info("ServicePathList not empty, contains {} paths.", servicePathList.size());
402                     for (ServicePaths service : servicePathList) {
403                         org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service
404                             .types.rev170426.service.path.PathDescription tmp = service.getPathDescription();
405                         if (tmp != null) {
406                             if (path.getAToZDirection() != null && tmp.getAToZDirection() != null
407                                     && egalAtoZDirection(path.getAToZDirection(), tmp.getAToZDirection())) {
408                                 if (path.getZToADirection() != null && tmp.getZToADirection() != null
409                                         && egalZtoADirection(path.getZToADirection(), tmp.getZToADirection())) {
410                                     result = true;
411                                     LOG.info("Path already present in servicePath List");
412                                     break;
413                                 } else {
414                                     LOG.info("ZtoADirection not equal or one of ZtoADirection is null!");
415                                     break;
416                                 }
417                             } else {
418                                 LOG.info("AtoZDirection not equal !");
419                                 break;
420                             }
421
422                         }
423                     }
424                 } else {
425                     LOG.info("ServicePathList is empty");
426                 }
427             } catch (NullPointerException e) {
428                 LOG.error("ServicePathList is empty");
429             }
430         } else {
431             LOG.info("PathDescriptions is null !");
432             result = true;
433         }
434         LOG.info("testPathDescription result : {}", result);
435         return result;
436     }
437
438     /**
439      * function to retrieve Paths based on
440      * AEnd and ZEnd.
441      *
442      * @param aendNodeId Aend Node Id
443      * @param zendNodeId Zend Node Id
444      * @return result PathDescriptions List
445      */
446     private List<PathDescriptions> retrievePath(String aendNodeId, String zendNodeId) {
447         List<PathDescriptions> result = new ArrayList<PathDescriptions>();
448         List<PathDescriptions> paths = readPathDescriptionList();
449         if (!paths.isEmpty() && aendNodeId != null && zendNodeId != null) {
450             LOG.info("retrieving paths from pathDescription List for {} / {}", aendNodeId, zendNodeId);
451             for (PathDescriptions tmp : paths) {
452                 Resource pathAend = null;
453                 Resource pathZend = null;
454                 String id = null;
455                 if (tmp != null) {
456                     LOG.info("Getting Aend & ZEnd from path '{}'...",tmp.getPathName());
457                     int index = 0;
458                     int size = tmp.getAToZDirection().getAToZ().size();
459                     while (index < size) {
460                         id = tmp.getAToZDirection().getAToZ().get(index).getId();
461                         if (id.compareToIgnoreCase("1") == 0) {
462                             Resource resource = tmp.getAToZDirection().getAToZ().get(index).getResource()
463                                     .getResource();
464                             LOG.info("{} : {}", resource.getClass().toString(), resource.toString());
465                             pathAend = resource;
466                             break;
467                         }
468                         index++;
469                     }
470                     index = 0;
471                     while (index < size) {
472                         id = tmp.getZToADirection().getZToA().get(index).getId();
473                         if (id.compareToIgnoreCase("1") == 0) {
474                             Resource resource = tmp.getZToADirection().getZToA().get(index).getResource()
475                                     .getResource();
476                             LOG.info(resource.toString());
477                             pathZend = resource;
478                             break;
479                         }
480                         index++;
481                     }
482                     if (pathAend != null && pathZend != null) {
483                         LOG.info("pathAend : {} - pathZend: {}",pathAend, pathZend);
484                         LOG.info("aendNodeId : {} - zendNodeId : {}", aendNodeId, zendNodeId);
485                         if (comp(pathAend, pathZend, aendNodeId, zendNodeId)) {
486                             LOG.info("PathDescription found !");
487                             result.add(tmp);
488                         }
489                     }
490                 }
491             }
492         }
493         return result;
494     }
495
496
497     /**
498      * found Pathdescriptions with
499      * name containing an expression.
500      *
501      * @param pathdescr PathDescriptions List
502      * @param contain String expression
503      * @return PathDescriptionsOrdered List
504      */
505     private SortedSet<PathDescriptionsOrdered> foundpath(List<PathDescriptions> pathdescr, String contain) {
506         SortedSet<PathDescriptionsOrdered> result = new TreeSet<PathDescriptionsOrdered>();
507         ListIterator<PathDescriptions> it = pathdescr.listIterator();
508         int odr = 0;
509         while (it.hasNext()) {
510             PathDescriptions path = it.next();
511             String name = path.getPathName();
512             LOG.info("path  : {}", name);
513             if (name != null && name.contains(contain)) {
514                 LOG.info("    path gets : {}", name);
515                 String [] split = name.split("_");
516                 if (split.length == 3) {
517                     odr = Integer.parseInt(split[2]);
518                     result.add(new PathDescriptionsOrdered(path, odr));
519                 }
520             }
521         }
522         return result;
523     }
524
525     /**
526      * order PathDescriptions List
527      * with first, ordered direct links
528      * and secondly ordered indirect
529      * links.
530      *
531      * @param pathdescr PathDescriptions List
532      * @return PathDescriptions List ordered
533      */
534     private List<PathDescriptions> orderPathdescriptionsList(List<PathDescriptions> pathdescr) {
535         SortedSet<PathDescriptionsOrdered> direct = new TreeSet<PathDescriptionsOrdered>();
536         SortedSet<PathDescriptionsOrdered> indirect = new TreeSet<PathDescriptionsOrdered>();
537         List<PathDescriptions> result = new ArrayList<PathDescriptions>();
538         int size = pathdescr.size();
539         if (size > 0) {
540             LOG.info("getting direct path first ...");
541             direct = foundpath(pathdescr, "_direct_");
542             LOG.info("getting indirect path first ...");
543             indirect = foundpath(pathdescr, "_indirect_");
544         }
545         if (direct.size() > 0) {
546             Iterator<PathDescriptionsOrdered> itset = direct.iterator();
547             while (itset.hasNext()) {
548                 result.add(itset.next().getPathDescriptions());
549             }
550             if (indirect.size() > 0) {
551                 Iterator<PathDescriptionsOrdered> itset2 = indirect.iterator();
552                 while (itset2.hasNext()) {
553                     result.add(itset2.next().getPathDescriptions());
554                 }
555             }
556
557         } else if (indirect.size() > 0) {
558             Iterator<PathDescriptionsOrdered> itset2 = indirect.iterator();
559             while (itset2.hasNext()) {
560                 result.add(itset2.next().getPathDescriptions());
561             }
562         }
563         if (result.size() == pathdescr.size()) {
564             return result;
565         } else {
566             return null;
567         }
568     }
569
570     public ListenableFuture<Boolean> cancelResourceReserve() {
571         LOG.info("In cancelResourceReserve request ...");
572         setSuccess(false);
573         return executor.submit(new Callable<Boolean>() {
574             @Override
575             public Boolean call() throws Exception {
576                 Boolean output = false;
577                 if (cancelInput != null) {
578                     Boolean found = false;
579                     String name = cancelInput.getServiceName();
580                     if (name != null && !servicePathList.isEmpty()) {
581                         for (ServicePaths service : servicePathList) {
582                             if (name.compareTo(service.getServicePathName()) == 0) {
583                                 LOG.info("ServicePaths found in ServicePathList !!!");
584                                 found = true;
585                                 break;
586                             }
587                         }
588                         if (found) {
589                             LOG.info("removing servicePaths from datastore ...");
590                             if (writeOrDeleteServicePathList(name,1)) {
591                                 LOG.info("Service deleted !");
592                                 setSuccess(true);
593                                 output = true;
594                             } else {
595                                 LOG.info("service deletion failed !");
596                             }
597                         }
598                     } else {
599                         LOG.info("serviceName is null or servicePathList is empty !");
600                     }
601                 } else {
602                     LOG.info("cancelresourcereserveinput parameter not valid !");
603                 }
604                 return output;
605             }
606         });
607     }
608
609     public ListenableFuture<Boolean> pathComputation() {
610         LOG.info("In pathComputation request ...");
611         setSuccess(false);
612         return executor.submit(new Callable<Boolean>() {
613             @Override
614             public Boolean call() throws Exception {
615                 Boolean output = false;
616                 List<PathDescriptions> pathsList = new ArrayList<PathDescriptions>();
617                 PathDescriptions path = null;
618                 int index ;
619                 Boolean constraints = false;
620                 if (input != null) {
621                     HardConstraints inputHard = input.getHardConstraints();
622                     SoftConstraints inputSoft = input.getSoftConstraints();
623                     if (inputHard != null || inputSoft != null) {
624                         constraints = true;
625                     }
626                     path = null;
627                     pathsList =  retrievePath(input.getServiceAEnd().getNodeId(), input.getServiceZEnd()
628                             .getNodeId());
629                     index = 0;
630                     output = false;
631                     /** get pathList ordered. */
632                     pathsList = orderPathdescriptionsList(pathsList);
633                     if (!pathsList.isEmpty()) {
634                         LOG.info("{} Paths get from Pathdescription List", pathsList.size());
635                         index = 0;
636                         output = false;
637                         while (index < pathsList.size()) {
638                             path = pathsList.get(index);
639                             LOG.info("path n°{} gets : '{}'!", index, path.getPathName());
640                             if (constraints) {
641                                 LOG.info("Calculating path with constraints ...");
642                                 if (inputHard.getCoRoutingOrGeneral() instanceof General) {
643                                     General general = (General)inputHard.getCoRoutingOrGeneral();
644                                     if (general != null) {
645                                         Diversity diversity = general.getDiversity();
646                                         if (diversity != null) {
647                                             LOG.info("Getting diversity ...");
648                                             List<String> existingService = diversity.getExistingService();
649                                             if (existingService.size() > 0) {
650                                                 LOG.info("Getting existing service applicability ...");
651                                                 int choice = -1;
652                                                 if (choice < 0
653                                                         && diversity.getExistingServiceApplicability().isNode()) {
654                                                     LOG.info("existing-service-applicability : Node");
655                                                     choice = 0;
656                                                 }
657                                                 if (choice < 0
658                                                         && diversity.getExistingServiceApplicability().isClli()) {
659                                                     LOG.info("existing-service-applicability : Clli");
660                                                     choice = 1;
661                                                 }
662                                                 if (choice < 0
663                                                         && diversity.getExistingServiceApplicability().isSrlg()) {
664                                                     LOG.info("existing-service-applicability : Srlg");
665                                                     choice = 2;
666                                                 }
667                                                 if (!diversityService(existingService, path, choice)) {
668                                                     error = "existing service applicability not satisfied";
669                                                     LOG.info(error);
670                                                     path = null;
671                                                 }
672                                             }
673                                         }
674                                         Exclude exclude = general.getExclude();
675                                         if (exclude != null) {
676                                             LOG.info("Getting exclude ...");
677                                             if (!excludeNode(path, exclude.getNodeId())) {
678                                                 error = "Exclude node constraints not satisfied !";
679                                                 LOG.info(error);
680                                                 path = null;
681                                             }
682                                         }
683                                     }
684                                 }
685                             }
686                             if (!testPathDescription(path)) {
687                                 LOG.info("Process finish !");
688                                 output = true;
689                                 break;
690                             }
691                             index++;
692                         }
693                     } else {
694                         LOG.info("failed to retrieve path from PathDescription List !");
695                     }
696                 } else {
697                     LOG.info("pathComputationRequestInput parameter not valid !");
698                 }
699                 if (path != null) {
700                     LOG.info("Path ok !");
701                     pathDescription = new PathDescriptionBuilder()
702                             .setAToZDirection(path.getAToZDirection())
703                             .setZToADirection(path.getZToADirection());
704                     if (input.isResourceReserve()) {
705                         LOG.info("reserving pce resource ...");
706                         setPathDescription(pathDescription);
707                         if (writeOrDeleteServicePathList(input.getServiceName(), 0)) {
708                             LOG.info("write ServicePaths to datastore");
709                             setSuccess(true);
710                         } else {
711                             LOG.error("writing ServicePaths to datastore failed ! ");
712                         }
713                     } else {
714                         LOG.info("no pce resource reserve !");
715                         setSuccess(true);
716                     }
717                 }
718                 return output;
719             }
720         });
721     }
722
723
724     /**
725      * get all ServicePaths in ServicePathlist.
726      *
727      * @return <code>ServicePaths List</code>
728      */
729     private List<ServicePaths> readServicePathList() {
730         LOG.info("Reading ServicePathList ...");
731         List<ServicePaths> result = null;
732         ReadOnlyTransaction readTx = db.newReadOnlyTransaction();
733         InstanceIdentifier<ServicePathList> iid = InstanceIdentifier.create(ServicePathList.class);
734         Future<Optional<ServicePathList>> future = readTx.read(LogicalDatastoreType.OPERATIONAL,iid);
735         Optional<ServicePathList> optional = Optional.absent();
736         try {
737             optional = Futures.getChecked(future, ExecutionException.class, 60, TimeUnit.SECONDS);
738         } catch (ExecutionException e) {
739             LOG.error("Reading service failed:", e);
740         }
741         if (optional.isPresent()) {
742             LOG.info("ServicePath List present !");
743             result = optional.get().getServicePaths();
744         }
745         return result;
746     }
747
748
749     private List<PathDescriptions> readPathDescriptionList() {
750         LOG.info("Reading PathDescriptionsList ...");
751         List<PathDescriptions> result = null;
752         ReadOnlyTransaction readTx = db.newReadOnlyTransaction();
753         InstanceIdentifier<PathDescriptionList> iid = InstanceIdentifier.create(PathDescriptionList.class);
754         Future<Optional<PathDescriptionList>> future = readTx.read(LogicalDatastoreType.OPERATIONAL,iid);
755         Optional<PathDescriptionList> optional = Optional.absent();
756         try {
757             optional = Futures.getChecked(future, ExecutionException.class, 60, TimeUnit.SECONDS);
758         } catch (ExecutionException e) {
759             LOG.error("Reading service failed:", e);
760         }
761         if (optional.isPresent()) {
762             LOG.info("ServicePath List present !");
763             result = optional.get().getPathDescriptions();
764         }
765         return result;
766
767     }
768
769     /**
770      * Write or Delete ServicePaths
771      * for ServicePathList.
772      *
773      * @param serviceName Service Name
774      * @param choice 0 : write or 1 : delete
775      * @return Boolean result true if deleted, false if not
776      */
777     private Boolean writeOrDeleteServicePathList(String serviceName, int choice) {
778         Boolean result = null;
779         if (serviceName != null && serviceName.compareTo(" ") != 0 && choice >= 0 && choice < 2) {
780             LOG.info("WriteOrDeleting '{}' ServicePaths", serviceName);
781             WriteTransaction writeTx = db.newWriteOnlyTransaction();
782             result = true;
783             String action = null;
784             InstanceIdentifier<ServicePaths> iid = InstanceIdentifier.create(ServicePathList.class)
785                     .child(ServicePaths.class,new ServicePathsKey(serviceName));
786             Future<Void> future = null;
787             switch (choice) {
788                 case 0: /** Write. */
789                     LOG.info("Writing '{}' Service", serviceName);
790                     org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev170426.service
791                         .path.PathDescriptionBuilder path = new org.opendaylight.yang.gen.v1.http.org.transportpce.b.c
792                         ._interface.service.types.rev170426.service.path.PathDescriptionBuilder();
793                     if (pathDescription != null) {
794                         if (pathDescription.getAToZDirection() != null) {
795                             path.setAToZDirection(pathDescription.getAToZDirection());
796                         }
797                         if (pathDescription.getZToADirection() != null) {
798                             path.setZToADirection(pathDescription.getZToADirection());
799                         }
800                         LOG.info("pathdescription gets");
801                     }
802                     ServiceAEnd aend = new org.opendaylight.yang.gen.v1.http.org.transportpce.b.c
803                             ._interface.service.types.rev170426.service.path.ServiceAEndBuilder(input.getServiceAEnd())
804                             .build();
805                     ServiceZEnd zend = new org.opendaylight.yang.gen.v1.http.org.transportpce.b.c
806                             ._interface.service.types.rev170426.service.path.ServiceZEndBuilder(input.getServiceZEnd())
807                             .build();
808                     ServicePaths service = new ServicePathsBuilder()
809                             .setServicePathName(serviceName)
810                             .setServiceHandlerHeader(new ServiceHandlerHeaderBuilder()
811                                     .setRequestId(input.getServiceHandlerHeader().getRequestId()).build())
812                             .setServiceAEnd(aend)
813                             .setServiceZEnd(zend)
814                             .setHardConstraints(input.getHardConstraints())
815                             .setSoftConstraints(input.getSoftConstraints())
816                             .setPathDescription(path.build())
817                             .build();
818                     LOG.info("Servicepath build");
819                     writeTx.put(LogicalDatastoreType.OPERATIONAL, iid, service);
820                     action = "write";
821                     //CheckedFuture<Void, OperationFailedException> future = transaction.submit();
822                     future = writeTx.submit();
823                     try {
824                         LOG.info("Sending '{}' command to datastore !", action);
825                         Futures.getChecked(future, ExecutionException.class);
826                     } catch (ExecutionException e) {
827                         LOG.error("Failed to {} service from Service List", action);
828                         result = false;
829                     }
830                     break;
831
832                 case 1: /** Delete */
833                     LOG.info("Deleting '{}' Service", serviceName);
834                     writeTx.delete(LogicalDatastoreType.OPERATIONAL, iid);
835                     action = "delete";
836                     future = writeTx.submit();
837                     try {
838                         LOG.info("Sending '{}' command to datastore !", serviceName);
839                         Futures.getChecked(future, ExecutionException.class);
840                     } catch (ExecutionException e) {
841                         LOG.error("Failed to {} service from Service List", serviceName);
842                         result = false;
843                     }
844                     break;
845
846                 default:
847                     LOG.info("No choice found");
848                     break;
849
850             }
851
852         } else {
853             LOG.info("Parameters not correct !");
854         }
855         return result;
856     }
857
858     public PathDescriptionBuilder getPathDescription() {
859         return pathDescription;
860     }
861
862     public void setPathDescription(PathDescriptionBuilder pathDescription) {
863         this.pathDescription = pathDescription;
864     }
865
866     public Boolean getSuccess() {
867         return success;
868     }
869
870     public void setSuccess(Boolean success) {
871         this.success = success;
872     }
873
874     public PathComputationRequestInput getInput() {
875         return input;
876     }
877
878     public void setInput(PathComputationRequestInput input) {
879         this.input = input;
880     }
881
882     public CancelResourceReserveInput getCancelInput() {
883         return cancelInput;
884     }
885
886     public void setCancelInput(CancelResourceReserveInput input) {
887         this.cancelInput = input;
888     }
889
890     public DataBroker getDb() {
891         return db;
892     }
893
894     public void setDb(DataBroker db) {
895         this.db = db;
896     }
897
898     public String getError() {
899         return error;
900     }
901
902     public void setError(String error) {
903         this.error = error;
904     }
905
906     public List<ServicePaths> getServicePathList() {
907         return servicePathList;
908     }
909
910     public void setServicePathList(List<ServicePaths> servicePathList) {
911         this.servicePathList = servicePathList;
912     }
913 }