89d3404f7d2a20b31fd44e87aed4b0a901d4555d
[transportpce.git] / tests / stubpce / src / main / java / org / opendaylight / transportpce / stubpce / impl / StubpceImpl.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.impl;
10
11 import com.google.common.base.Optional;
12 import com.google.common.util.concurrent.FutureCallback;
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 import com.google.common.util.concurrent.MoreExecutors;
17
18 import java.util.Iterator;
19 import java.util.SortedSet;
20 import java.util.concurrent.ExecutionException;
21 import java.util.concurrent.Executors;
22 import java.util.concurrent.Future;
23
24 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
25 import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService;
26 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
27 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
28 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
29 import org.opendaylight.transportpce.stubpce.CheckCoherencyHardSoft;
30 import org.opendaylight.transportpce.stubpce.SendingPceRPCs;
31 import org.opendaylight.transportpce.stubpce.StubpceCompliancyCheck;
32 import org.opendaylight.transportpce.stubpce.StubpceTxRxCheck;
33 import org.opendaylight.transportpce.stubpce.topology.PathDescriptionsOrdered;
34 import org.opendaylight.transportpce.stubpce.topology.SuperNodePath;
35 import org.opendaylight.transportpce.stubpce.topology.Topology;
36 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev161014.configuration.response.common.ConfigurationResponseCommonBuilder;
37 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev161014.ServiceList;
38 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev161014.service.list.Services;
39 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev161014.service.list.ServicesBuilder;
40 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev161014.service.list.ServicesKey;
41 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev170426.RpcStatusEx;
42 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev170426.ServicePathNotificationTypes;
43 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev170426.response.parameters.sp.response.parameters.PathDescriptionBuilder;
44 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.CancelResourceReserveInput;
45 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.CancelResourceReserveOutput;
46 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.CancelResourceReserveOutputBuilder;
47 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.PathComputationRequestInput;
48 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.PathComputationRequestOutput;
49 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.PathComputationRequestOutputBuilder;
50 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.PathDescriptionList;
51 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.PathDescriptionListBuilder;
52 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.ServiceDeleteInput;
53 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.ServiceDeleteOutput;
54 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.ServiceImplementationRequestInput;
55 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.ServiceImplementationRequestOutput;
56 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.ServicePathList;
57 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.ServicePathListBuilder;
58 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.ServicePathRpcResult;
59 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.ServicePathRpcResultBuilder;
60 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.TransportpceServicepathService;
61 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.path.description.list.PathDescriptions;
62 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.path.description.list.PathDescriptionsBuilder;
63 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.path.description.list.PathDescriptionsKey;
64 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.service.path.list.ServicePaths;
65 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.service.path.list.ServicePathsBuilder;
66 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.service.path.list.ServicePathsKey;
67 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.service.path.rpc.result.PathDescription;
68 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
69 import org.opendaylight.yangtools.yang.common.RpcResult;
70 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
71 import org.slf4j.Logger;
72 import org.slf4j.LoggerFactory;
73
74 /**
75  * Class to implement StubpceService StubpceListener.
76  * @author <a href="mailto:martial.coulibaly@gfi.com">Martial Coulibaly</a> on
77  *         behalf of Orange
78  */
79
80 public class StubpceImpl implements TransportpceServicepathService {
81     /** Logging. */
82     private static final Logger LOG = LoggerFactory.getLogger(StubpceImpl.class);
83     /** Permit to access database. */
84     private DataBroker db;
85     /** check service sdnc-request-header compliancy. */
86     private StubpceCompliancyCheck compliancyCheck;
87     /** check missing info on Tx/Rx for A/Z end. */
88     private StubpceTxRxCheck txrxCheck;
89     /** check coherency between hard and soft constraints. */
90     private CheckCoherencyHardSoft checkCoherencyHardSoft;
91     private NotificationPublishService notificationPublishService;
92     private ServicePathRpcResult notification;
93     private PathDescriptionBuilder pathDescriptionBuilder;
94     private SendingPceRPCs sendingPCE;
95     private final ListeningExecutorService executor = MoreExecutors
96             .listeningDecorator(Executors.newFixedThreadPool(10));
97
98     public StubpceImpl(NotificationPublishService notificationPublishService, DataBroker databroker) {
99         this.notificationPublishService = notificationPublishService;
100         this.db = databroker;
101         pathDescriptionBuilder = null;
102         if (initializePathDescriptionList(databroker)) {
103             fillPathDesciptionList();
104         }
105         initializeServicePathList(databroker);
106         /*if (initializeServicePathList(databroker)) {
107             fillServicePathList();
108         }*/
109     }
110
111     @Override
112     public Future<RpcResult<CancelResourceReserveOutput>> cancelResourceReserve(CancelResourceReserveInput input) {
113         LOG.info("RPC cancelResourceReserve  request received");
114         String message = "";
115         String responseCode = "";
116         ConfigurationResponseCommonBuilder configurationResponseCommon = null;
117         String serviceName = input.getServiceName();
118         LOG.info("serviceName : " + serviceName);
119         if (serviceName != null) {
120             sendingPCE = new SendingPceRPCs(input,db,executor);
121             FutureCallback<Boolean> pceCallback = new FutureCallback<Boolean>() {
122                 String message = "";
123                 ServicePathRpcResult notification = null;
124
125                 @Override
126                 public void onFailure(Throwable arg0) {
127                     LOG.error(arg0.toString());
128                     LOG.error("Cancel resource failed !");
129                     notification = new ServicePathRpcResultBuilder()
130                             .setNotificationType(ServicePathNotificationTypes.CancelResourceReserve)
131                             .setServiceName(input.getServiceName()).setStatus(RpcStatusEx.Failed)
132                             .setStatusMessage("Cancel resource request failed  : " + arg0.getMessage()).build();
133                     try {
134                         notificationPublishService.putNotification(notification);
135                     } catch (InterruptedException e) {
136                         LOG.info("notification offer rejected : " + e);
137                     }
138                 }
139
140                 @Override
141                 public void onSuccess(Boolean response) {
142                     LOG.info("response : " + response);
143                     if (response) {
144                         message = "Resource cancelled !";
145                         notification = new ServicePathRpcResultBuilder()
146                                 .setNotificationType(ServicePathNotificationTypes.CancelResourceReserve)
147                                 .setServiceName(input.getServiceName()).setStatus(RpcStatusEx.Successful)
148                                 .setStatusMessage(message)
149                                 .build();
150                     } else {
151                         message = sendingPCE.getError();
152                         notification = new ServicePathRpcResultBuilder()
153                                 .setNotificationType(ServicePathNotificationTypes.CancelResourceReserve)
154                                 .setServiceName("")
155                                 .setStatus(RpcStatusEx.Failed).setStatusMessage(message)
156                                 .build();
157                         message = "Cancel request failed !";
158                     }
159                     LOG.info(notification.toString());
160                     try {
161                         notificationPublishService.putNotification(notification);
162                     } catch (InterruptedException e) {
163                         LOG.info("notification offer rejected : " + e);
164                     }
165                     LOG.info(message);
166                 }
167             };
168             ListenableFuture<Boolean> pce = sendingPCE.cancelResourceReserve();
169             Futures.addCallback(pce, pceCallback, executor);
170             LOG.info("Cancel Resource Request in progress ...");
171             configurationResponseCommon = new ConfigurationResponseCommonBuilder()
172                     .setAckFinalIndicator("No")
173                     .setRequestId(input.getServiceHandlerHeader().getRequestId())
174                     .setResponseMessage("Service compliant, Cancel resource request in progress...")
175                     .setResponseCode("200");
176
177             CancelResourceReserveOutputBuilder output = new CancelResourceReserveOutputBuilder()
178                     .setConfigurationResponseCommon(configurationResponseCommon.build());
179
180             return RpcResultBuilder.success(output.build()).buildFuture();
181         } else {
182             message = "serviceName / requestId is not correct !";
183             responseCode = "500";
184             notification = new ServicePathRpcResultBuilder()
185                     .setNotificationType(ServicePathNotificationTypes.CancelResourceReserve)
186                     .setServiceName(input.getServiceName()).setStatus(RpcStatusEx.Failed)
187                     .setStatusMessage(message).build();
188             try {
189                 notificationPublishService.putNotification(notification);
190             } catch (InterruptedException e) {
191                 LOG.info("notification offer rejected : " + e);
192             }
193         }
194         configurationResponseCommon = new ConfigurationResponseCommonBuilder();
195         configurationResponseCommon.setAckFinalIndicator("Yes")
196         .setRequestId(input.getServiceHandlerHeader().getRequestId())
197         .setResponseMessage(message)
198         .setResponseCode(responseCode).build();
199         CancelResourceReserveOutputBuilder output = new CancelResourceReserveOutputBuilder();
200         output.setConfigurationResponseCommon(configurationResponseCommon.build());
201         return RpcResultBuilder.success(output.build()).buildFuture();
202     }
203
204     @Override
205     public Future<RpcResult<PathComputationRequestOutput>> pathComputationRequest(PathComputationRequestInput input) {
206         LOG.info("RPC pathcomputation request received");
207         String message = "";
208         String responseCode = "";
209         boolean coherencyHardSoft = false;
210         boolean commonId = true;
211         ConfigurationResponseCommonBuilder configurationResponseCommon = null;
212         compliancyCheck = new StubpceCompliancyCheck(input.getServiceName(), input.getServiceHandlerHeader());
213         if (compliancyCheck.check(false, true)) {
214             LOG.info("Service compliant !");
215             /**
216              * If compliant, service-request parameters are verified in order to
217              * check if there is no missing parameter that prevents calculating
218              * a path and implement a service.
219              */
220             LOG.info("checking Tx/Rx Info for AEnd ...");
221             txrxCheck = new StubpceTxRxCheck(input.getServiceAEnd(), 1);
222             if (txrxCheck.check()) {
223                 LOG.info("Tx/Rx Info for AEnd checked !");
224                 LOG.info("checking Tx/Rx Info for ZEnd ...");
225                 txrxCheck = new StubpceTxRxCheck(input.getServiceZEnd(), 2);
226                 if (txrxCheck.check()) {
227                     LOG.info("Tx/Rx Info for ZEnd checked !");
228                     /**
229                      * If OK, common-id is verified in order to see if there is
230                      * no routing policy provided. If yes, the routing
231                      * constraints of the policy are recovered and coherency
232                      * with hard/soft constraints provided in the input of the
233                      * RPC.
234                      */
235                     if (input.getHardConstraints() != null || input.getSoftConstraints() != null) {
236                         LOG.info("Constraints specified !");
237                         checkCoherencyHardSoft = new CheckCoherencyHardSoft(input.getHardConstraints(),
238                                 input.getSoftConstraints());
239                         if (checkCoherencyHardSoft.check()) {
240                             LOG.info("hard/soft constraints coherent !");
241                             coherencyHardSoft = true;
242                         } else {
243                             LOG.info("hard/soft constraints are not coherent !");
244                             message = "hard/soft constraints are not coherent !";
245                             responseCode = "500";
246                         }
247                     } else {
248                         commonId = false;
249                     }
250                     if (!commonId || (commonId && coherencyHardSoft)) {
251                         notification = new ServicePathRpcResultBuilder()
252                                 .setNotificationType(ServicePathNotificationTypes.PathComputationRequest)
253                                 .setServiceName(input.getServiceName()).setStatus(RpcStatusEx.Pending)
254                                 .setStatusMessage("Service compliant, submitting pathComputation Request ...").build();
255                         try {
256                             notificationPublishService.putNotification(notification);
257                         } catch (InterruptedException e) {
258                             LOG.info("notification offer rejected : " + e);
259                         }
260                         sendingPCE = new SendingPceRPCs(input,db,executor);
261                         FutureCallback<Boolean> pceCallback = new FutureCallback<Boolean>() {
262                             String message = "";
263                             ServicePathRpcResult notification = null;
264
265                             @Override
266                             public void onFailure(Throwable arg0) {
267                                 LOG.error("Failure message : " + arg0.toString());
268                                 LOG.error("Path calculation failed !");
269                                 notification = new ServicePathRpcResultBuilder()
270                                         .setServiceName(input.getServiceName()).setStatus(RpcStatusEx.Failed)
271                                         .setStatusMessage("PCR Request failed  : " + arg0.getMessage()).build();
272                                 try {
273                                     notificationPublishService.putNotification(notification);
274                                 } catch (InterruptedException e) {
275                                     LOG.info("notification offer rejected : " + e);
276                                 }
277                             }
278
279                             @Override
280                             public void onSuccess(Boolean response) {
281                                 LOG.info("response : " + response);
282                                 if (response) {
283                                     message = "Path Computated !";
284                                     ServicePathRpcResultBuilder tmp = new ServicePathRpcResultBuilder()
285                                             .setNotificationType(ServicePathNotificationTypes.PathComputationRequest)
286                                             .setServiceName(input.getServiceName()).setStatus(RpcStatusEx.Successful)
287                                             .setStatusMessage(message);
288                                     pathDescriptionBuilder = sendingPCE.getPathDescription();
289                                     if (pathDescriptionBuilder != null) {
290                                         PathDescription pathDescription = new org.opendaylight.yang.gen.v1.http.org
291                                                 .transportpce.b.c._interface.servicepath.rev170426.service.path
292                                                 .rpc.result.PathDescriptionBuilder()
293                                                 .setAToZDirection(pathDescriptionBuilder.getAToZDirection())
294                                                 .setZToADirection(pathDescriptionBuilder.getZToADirection())
295                                                 .build();
296                                         tmp.setPathDescription(pathDescription);
297                                     }
298                                     notification = tmp.build();
299                                 } else {
300                                     message = sendingPCE.getError();
301                                     notification = new ServicePathRpcResultBuilder()
302                                             .setNotificationType(ServicePathNotificationTypes.PathComputationRequest)
303                                             .setServiceName("")
304                                             .setStatus(RpcStatusEx.Failed).setStatusMessage(message)
305                                             .build();
306                                     message = "Path not calculated!";
307                                 }
308                                 try {
309                                     notificationPublishService.putNotification(notification);
310                                 } catch (InterruptedException e) {
311                                     LOG.info("notification offer rejected : " + e);
312                                 }
313                                 LOG.info(message);
314                             }
315                         };
316                         ListenableFuture<Boolean> pce = sendingPCE.pathComputation();
317                         Futures.addCallback(pce, pceCallback, executor);
318                         LOG.info("PathComputation Request in progress ...");
319                         configurationResponseCommon = new ConfigurationResponseCommonBuilder()
320                                 .setAckFinalIndicator("No")
321                                 .setRequestId(input.getServiceHandlerHeader().getRequestId())
322                                 .setResponseMessage("Service compliant, Path calculating in progress...")
323                                 .setResponseCode("200");
324
325                         PathComputationRequestOutputBuilder output = new PathComputationRequestOutputBuilder()
326                                 .setConfigurationResponseCommon(configurationResponseCommon.build());
327                         return RpcResultBuilder.success(output.build()).buildFuture();
328                     }
329
330                 } else {
331                     message = txrxCheck.getMessage();
332                     responseCode = "500";
333                 }
334             } else {
335                 message = txrxCheck.getMessage();
336                 responseCode = "500";
337             }
338         } else {
339             message = compliancyCheck.getMessage();
340             responseCode = "500";
341             notification = new ServicePathRpcResultBuilder()
342                     .setNotificationType(ServicePathNotificationTypes.PathComputationRequest)
343                     .setServiceName(input.getServiceName()).setStatus(RpcStatusEx.Failed)
344                     .setStatusMessage("Service not compliant : " + message).build();
345             try {
346                 notificationPublishService.putNotification(notification);
347             } catch (InterruptedException e) {
348                 LOG.info("notification offer rejected : " + e);
349             }
350         }
351         configurationResponseCommon = new ConfigurationResponseCommonBuilder();
352         configurationResponseCommon.setAckFinalIndicator("Yes")
353         .setRequestId(input.getServiceHandlerHeader().getRequestId())
354         .setResponseMessage(message)
355         .setResponseCode(responseCode).build();
356         PathComputationRequestOutputBuilder output = new PathComputationRequestOutputBuilder();
357         output.setConfigurationResponseCommon(configurationResponseCommon.build());
358         return RpcResultBuilder.success(output.build()).buildFuture();
359
360     }
361
362     /**
363      * Initialize PathDescriptionList Structure on DataStore.
364      *
365      * @param DataBroker
366      *            Access DataStore
367      */
368     private boolean initializePathDescriptionList(DataBroker db) {
369         Boolean result = true;
370         LOG.info("Preparing to initialize the PathDescription List");
371         WriteTransaction transaction = db.newWriteOnlyTransaction();
372         InstanceIdentifier<PathDescriptionList> iid = InstanceIdentifier.create(PathDescriptionList.class);
373         PathDescriptionList pathDescriptionList = new PathDescriptionListBuilder().build();
374         transaction.put(LogicalDatastoreType.OPERATIONAL, iid, pathDescriptionList);
375         Future<Void> future = transaction.submit();
376         try {
377             Futures.getChecked(future, ExecutionException.class);
378         } catch (ExecutionException e) {
379             LOG.error("Failed to create PathDescription List");
380             result = false;
381         }
382         return result;
383     }
384
385     /**
386      * Initialize ServicePathList Structure on DataStore.
387      *
388      * @param DataBroker
389      *            Access DataStore
390      * @return <code>true</code> if ok, <code>false</code> else
391      */
392     private boolean initializeServicePathList(DataBroker db) {
393         Boolean result = true;
394         LOG.info("Preparing to initialize the ServicePathList registry");
395         WriteTransaction transaction = db.newWriteOnlyTransaction();
396         InstanceIdentifier<ServicePathList> iid = InstanceIdentifier.create(ServicePathList.class);
397         ServicePathList servicePathList = new ServicePathListBuilder().build();
398         transaction.put(LogicalDatastoreType.OPERATIONAL, iid, servicePathList);
399         Future<Void> future = transaction.submit();
400         try {
401             Futures.getChecked(future, ExecutionException.class);
402         } catch (ExecutionException e) {
403             LOG.error("Failed to create ServicePathList List : " + e.toString());
404             result = false;
405         }
406         return result;
407     }
408
409     /**
410      * fill PathDescriptionList
411      * with direct paths and
412      * indirect paths.
413      */
414     private void fillPathDesciptionList() {
415         LOG.info("filling PathDescription List...");
416         Topology topo = new Topology();
417         topo.start();
418         LOG.info("Network : " + topo.getNetwork());
419         SuperNodePath superNodePath = new SuperNodePath(topo.getNetwork());
420         String aend = "NodeA";
421         String zend = "NodeZ";
422         superNodePath.run(aend, zend);
423         fill(superNodePath.getDirectPathDesc(aend, zend, superNodePath.getPaths()));
424         fill(superNodePath.getIndirectPathDesc(aend, zend, superNodePath.getPaths()));
425     }
426
427     /**
428      * fill datastore with
429      * Pathdescriptions List.
430      *
431      * @param sortedSet PathDescriptionsOrdered List
432      */
433     private void fill(SortedSet<PathDescriptionsOrdered> sortedSet) {
434         InstanceIdentifier<PathDescriptions> iid;
435         WriteTransaction writeTx;
436         Future<Void> future;
437         if (!sortedSet.isEmpty()) {
438             Iterator<PathDescriptionsOrdered> it = sortedSet.iterator();
439             while (it.hasNext()) {
440                 PathDescriptions pathDesc = it.next().getPathDescriptions();
441                 if (pathDesc != null) {
442                     iid = InstanceIdentifier.create(PathDescriptionList.class)
443                             .child(PathDescriptions.class, new PathDescriptionsKey(pathDesc.getPathName()));
444                     writeTx = db.newWriteOnlyTransaction();
445                     writeTx.put(LogicalDatastoreType.OPERATIONAL, iid, pathDesc);
446                     future = writeTx.submit();
447                     try {
448                         Futures.getChecked(future, ExecutionException.class);
449                     } catch (ExecutionException e) {
450                         LOG.error("Failed to write PathDescriptions to PathDescriptionsList : " + e.toString());
451                     }
452                 } else {
453                     LOG.error("PathDescriptions gets is null !");
454                 }
455             }
456         } else {
457             LOG.info("PathDescriptions List is empty !");
458         }
459     }
460
461     /**
462      * read Service from ServiceList DataStore.
463      *
464      * @param serviceName
465      *            Name of Service
466      *
467      * @return <code>Services</code>
468      */
469     @SuppressWarnings("unused")
470     private Services readServiceList(String serviceName) {
471         Services result = null;
472         ReadOnlyTransaction readTx = db.newReadOnlyTransaction();
473         InstanceIdentifier<Services> iid = InstanceIdentifier.create(ServiceList.class).child(Services.class,
474                 new ServicesKey(serviceName));
475         Future<Optional<Services>> future = readTx.read(LogicalDatastoreType.OPERATIONAL,iid);
476         Optional<Services> optional = Optional.absent();
477         try {
478             optional = Futures.getChecked(future, ExecutionException.class);
479         } catch (ExecutionException e) {
480             LOG.error("Reading service failed:", e);
481         }
482         if (optional.isPresent()) {
483             LOG.debug("Service '" + serviceName + "' present !");
484             result = new ServicesBuilder(optional.get()).build();
485         }
486         return result;
487     }
488
489     /**
490      * read ServicePath Service from ServicePathList DataStore.
491      *
492      * @param serviceName
493      *            Name of ServicePath
494      *
495      * @return <code>Services</code>
496      */
497     @SuppressWarnings("unused")
498     private ServicePaths readServicePathList(String serviceName) {
499         ServicePaths result = null;
500         ReadOnlyTransaction readTx = db.newReadOnlyTransaction();
501         InstanceIdentifier<ServicePaths> iid = InstanceIdentifier.create(ServicePathList.class)
502                 .child(ServicePaths.class, new ServicePathsKey(serviceName));
503         Future<Optional<ServicePaths>> future = readTx.read(LogicalDatastoreType.OPERATIONAL,iid);
504         Optional<ServicePaths> optional = Optional.absent();
505         try {
506             optional = Futures.getChecked(future, ExecutionException.class);
507         } catch (ExecutionException e) {
508             LOG.error("Reading service failed:", e);
509         }
510         if (optional.isPresent()) {
511             LOG.debug("Service '" + serviceName + "' present !");
512             result = new ServicePathsBuilder(optional.get()).build();
513         }
514         return result;
515     }
516
517     /**
518      * read PathDescription information from PathDescriptionList.
519      *
520      * @param pathName
521      *            Name of PathDescription
522      *
523      * @return <code>PathDescriptions</code>
524      */
525     @SuppressWarnings("unused")
526     private PathDescriptions readPathDescriptionList(String pathName) {
527         PathDescriptions result = null;
528         ReadOnlyTransaction readTx = db.newReadOnlyTransaction();
529         InstanceIdentifier<PathDescriptions> iid = InstanceIdentifier.create(PathDescriptionList.class)
530                 .child(PathDescriptions.class, new PathDescriptionsKey(pathName));
531         Future<Optional<PathDescriptions>> future = readTx.read(LogicalDatastoreType.OPERATIONAL,iid);
532         Optional<PathDescriptions> optional = Optional.absent();
533         try {
534             optional = Futures.getChecked(future, ExecutionException.class);
535         } catch (ExecutionException e) {
536             LOG.error("Reading service failed:", e);
537         }
538         if (optional.isPresent()) {
539             LOG.debug("PathDescritions '" + pathName + "' present !");
540             result = new PathDescriptionsBuilder(optional.get()).build();
541         }
542         return result;
543     }
544
545     /**
546      * register ServicePath Service to ServicePathList with PathDescription
547      * information.
548      *
549      * @param input
550      *            PathComputationRequestInput
551      * @return String operations result, null if ok or not otherwise
552      */
553     @SuppressWarnings("unused")
554     private String writeServicePathList(PathComputationRequestInput input) {
555         String serviceName = input.getServiceName();
556         LOG.debug("Write ServicePath '" + serviceName + "' Service");
557         String result = null;
558         LOG.debug("Writing '" + serviceName + "' ServicePath");
559         InstanceIdentifier<ServicePaths> iid = InstanceIdentifier.create(ServicePathList.class)
560                 .child(ServicePaths.class, new ServicePathsKey(serviceName));
561
562         org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev170426.service
563             .path.PathDescriptionBuilder path = new org.opendaylight.yang.gen.v1.http.org.transportpce
564             .b.c._interface.service.types.rev170426.service.path.PathDescriptionBuilder();
565         path.setAToZDirection(pathDescriptionBuilder.getAToZDirection());
566         path.setZToADirection(pathDescriptionBuilder.getZToADirection());
567         ServicePaths service = new ServicePathsBuilder().setServicePathName(input.getServiceName())
568                 .setSoftConstraints(input.getSoftConstraints()).setHardConstraints(input.getHardConstraints())
569                 .setPathDescription(path.build()).build();
570         WriteTransaction writeTx = db.newWriteOnlyTransaction();
571         writeTx.put(LogicalDatastoreType.OPERATIONAL, iid, service);
572         Future<Void> future = writeTx.submit();
573         try {
574             Futures.getChecked(future, ExecutionException.class);
575             result = null;
576         } catch (ExecutionException e) {
577             LOG.error("Failed to write service to Service List");
578             result = "Failed to write service to Service List";
579         }
580         return result;
581     }
582
583     public PathDescriptionBuilder getPathDescriptionBuilder() {
584         return pathDescriptionBuilder;
585     }
586
587     public void setPathDescriptionBuilder(PathDescriptionBuilder pathDescriptionBuilder) {
588         this.pathDescriptionBuilder = pathDescriptionBuilder;
589     }
590
591     @Override
592     public Future<RpcResult<ServiceImplementationRequestOutput>> serviceImplementationRequest(
593             ServiceImplementationRequestInput input) {
594         // TODO Auto-generated method stub
595         return null;
596     }
597
598     @Override
599     public Future<RpcResult<ServiceDeleteOutput>> serviceDelete(ServiceDeleteInput input) {
600         // TODO Auto-generated method stub
601         return null;
602     }
603 }