7db5941f8b3209f0c0d067b6e194e4702cdc2fbd
[ccsdk/sli/core.git] / sliapi / provider / src / main / java / org / onap / ccsdk / sli / core / sliapi / sliapiProvider.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP : CCSDK
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights
6  *                                              reserved.
7  * ================================================================================
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  * ============LICENSE_END=========================================================
20  */
21
22 package org.onap.ccsdk.sli.core.sliapi;
23
24 import java.io.BufferedReader;
25 import java.io.FileNotFoundException;
26 import java.io.FileReader;
27 import java.io.IOException;
28 import java.util.Enumeration;
29 import java.util.LinkedList;
30 import java.util.Properties;
31 import java.util.concurrent.Future;
32
33 import org.onap.ccsdk.sli.core.sli.provider.SvcLogicService;
34 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
35 import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService;
36 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
37 import org.opendaylight.controller.md.sal.binding.impl.AbstractForwardedDataBroker;
38 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
39 import org.opendaylight.controller.md.sal.common.api.data.OptimisticLockFailedException;
40 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
41 import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
42 import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
43 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
44 import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
45 import org.opendaylight.yang.gen.v1.org.onap.ccsdk.sli.core.sliapi.rev161110.ExecuteGraphInput;
46 import org.opendaylight.yang.gen.v1.org.onap.ccsdk.sli.core.sliapi.rev161110.ExecuteGraphInput.Mode;
47 import org.opendaylight.yang.gen.v1.org.onap.ccsdk.sli.core.sliapi.rev161110.ExecuteGraphInputBuilder;
48 import org.opendaylight.yang.gen.v1.org.onap.ccsdk.sli.core.sliapi.rev161110.ExecuteGraphOutput;
49 import org.opendaylight.yang.gen.v1.org.onap.ccsdk.sli.core.sliapi.rev161110.ExecuteGraphOutputBuilder;
50 import org.opendaylight.yang.gen.v1.org.onap.ccsdk.sli.core.sliapi.rev161110.HealthcheckInput;
51 import org.opendaylight.yang.gen.v1.org.onap.ccsdk.sli.core.sliapi.rev161110.HealthcheckOutput;
52 import org.opendaylight.yang.gen.v1.org.onap.ccsdk.sli.core.sliapi.rev161110.HealthcheckOutputBuilder;
53 import org.opendaylight.yang.gen.v1.org.onap.ccsdk.sli.core.sliapi.rev161110.SLIAPIService;
54 import org.opendaylight.yang.gen.v1.org.onap.ccsdk.sli.core.sliapi.rev161110.TestResults;
55 import org.opendaylight.yang.gen.v1.org.onap.ccsdk.sli.core.sliapi.rev161110.VlbcheckInput;
56 import org.opendaylight.yang.gen.v1.org.onap.ccsdk.sli.core.sliapi.rev161110.VlbcheckOutput;
57 import org.opendaylight.yang.gen.v1.org.onap.ccsdk.sli.core.sliapi.rev161110.VlbcheckOutputBuilder;
58 import org.opendaylight.yang.gen.v1.org.onap.ccsdk.sli.core.sliapi.rev161110.execute.graph.input.SliParameter;
59 import org.opendaylight.yang.gen.v1.org.onap.ccsdk.sli.core.sliapi.rev161110.test.results.TestResult;
60 import org.opendaylight.yang.gen.v1.org.onap.ccsdk.sli.core.sliapi.rev161110.test.results.TestResultBuilder;
61 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
62 import org.opendaylight.yangtools.yang.common.QName;
63 import org.opendaylight.yangtools.yang.common.RpcError.ErrorType;
64 import org.opendaylight.yangtools.yang.common.RpcResult;
65 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
66 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
67 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
68 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
69 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeWithValue;
70 import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
71 import org.opendaylight.yangtools.yang.data.api.schema.LeafSetNode;
72 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
73 import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
74 import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableLeafSetEntryNodeBuilder;
75 import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableLeafSetNodeBuilder;
76 import org.osgi.framework.BundleContext;
77 import org.osgi.framework.FrameworkUtil;
78 import org.osgi.framework.ServiceReference;
79 import org.slf4j.Logger;
80 import org.slf4j.LoggerFactory;
81
82 import com.google.common.util.concurrent.Futures;
83 import com.google.common.util.concurrent.ListenableFuture;
84
85
86 /**
87  * Defines a base implementation for your provider. This class extends from a helper class
88  * which provides storage for the most commonly used components of the MD-SAL. Additionally the
89  * base class provides some basic logging and initialization / clean up methods.
90  *
91  * To use this, copy and paste (overwrite) the following method into the TestApplicationProviderModule
92  * class which is auto generated under src/main/java in this project
93  * (created only once during first compilation):
94  *
95  * <pre>
96
97     @Override
98     public java.lang.AutoCloseable createInstance() {
99
100          final sliapiProvider provider = new sliapiProvider();
101          provider.setDataBroker( getDataBrokerDependency() );
102          provider.setNotificationService( getNotificationServiceDependency() );
103          provider.setRpcRegistry( getRpcRegistryDependency() );
104          provider.initialize();
105          return new AutoCloseable() {
106
107             @Override
108             public void close() throws Exception {
109                 //TODO: CLOSE ANY REGISTRATION OBJECTS CREATED USING ABOVE BROKER/NOTIFICATION
110                 //SERVIE/RPC REGISTRY
111                 provider.close();
112             }
113         };
114     }
115
116
117     </pre>
118  */
119 public class sliapiProvider implements AutoCloseable, SLIAPIService{
120
121     private static final Logger LOG = LoggerFactory.getLogger( sliapiProvider.class );
122     private static final String appName = "slitester";
123
124     protected DataBroker dataBroker;
125     protected DOMDataBroker domDataBroker;
126     protected NotificationPublishService notificationService;
127     protected RpcProviderRegistry rpcRegistry;
128
129     private SvcLogicService svcLogic;
130
131         protected BindingAwareBroker.RpcRegistration<SLIAPIService> rpcRegistration;
132
133         private static String SLIAPI_NAMESPACE = "org:onap:ccsdk:sli:core:sliapi";
134         private static String SLIAPI_REVISION = "2016-11-10";
135         private static String SDNC_STATUS_FILE = "SDNC_STATUS_FILE";
136         private static String sdncStatusFile = null;
137
138         private static QName TEST_RESULTS_QNAME = null;
139         private static QName TEST_RESULT_QNAME = null;
140         private static QName TEST_ID_QNAME = null;
141         private static QName RESULTS_QNAME = null;
142         private static final String NON_NULL= "non-null";
143
144         static {
145
146                 TEST_RESULTS_QNAME = QName.create(SLIAPI_NAMESPACE, SLIAPI_REVISION, "test-results");
147                 TEST_RESULT_QNAME = QName.create(TEST_RESULTS_QNAME, "test-result");
148                 TEST_ID_QNAME = QName.create(TEST_RESULT_QNAME, "test-identifier");
149                 RESULTS_QNAME = QName.create(TEST_RESULT_QNAME, "results");
150         }
151
152     public sliapiProvider(
153             DataBroker dataBroker,
154             NotificationPublishService notificationPublishService,
155             RpcProviderRegistry rpcProviderRegistry) {
156         this(dataBroker, notificationPublishService, rpcProviderRegistry, findSvcLogicService());
157     }
158
159     public sliapiProvider(
160                         DataBroker dataBroker,
161                         NotificationPublishService notificationPublishService,
162                         RpcProviderRegistry rpcProviderRegistry,
163                         SvcLogicService svcLogic) {
164         this.LOG.info( "Creating provider for " + appName );
165         this.dataBroker = dataBroker;
166         this.notificationService = notificationPublishService;
167         this.rpcRegistry = rpcProviderRegistry;
168         this.svcLogic = svcLogic;
169         initialize();
170     }
171
172
173
174     public void initialize(){
175         LOG.info( "Initializing provider for " + appName );
176         //initialization code goes here.
177         rpcRegistration = rpcRegistry.addRpcImplementation(SLIAPIService.class, this);
178
179         sdncStatusFile = System.getenv(SDNC_STATUS_FILE);
180         LOG.info( "SDNC STATUS FILE = " + sdncStatusFile );
181         LOG.info( "Initialization complete for " + appName );
182     }
183
184     protected void initializeChild() {
185         //Override if you have custom initialization intelligence
186     }
187
188     @Override
189     public void close() throws Exception {
190         LOG.info( "Closing provider for " + appName );
191         //closing code goes here
192
193             rpcRegistration.close();
194         LOG.info( "Successfully closed provider for " + appName );
195     }
196
197     public void setDataBroker(DataBroker dataBroker) {
198         this.dataBroker = dataBroker;
199                 if (dataBroker instanceof AbstractForwardedDataBroker) {
200                         domDataBroker = ((AbstractForwardedDataBroker) dataBroker).getDelegate();
201                 }
202         if( LOG.isDebugEnabled() ){
203             LOG.debug( "DataBroker set to " + (dataBroker==null?"null":NON_NULL) + "." );
204         }
205     }
206
207     public void setNotificationService(
208             NotificationPublishService notificationService) {
209         this.notificationService = notificationService;
210         if( LOG.isDebugEnabled() ){
211             LOG.debug( "Notification Service set to " + (notificationService==null?"null":NON_NULL) + "." );
212         }
213     }
214
215     public void setRpcRegistry(RpcProviderRegistry rpcRegistry) {
216         this.rpcRegistry = rpcRegistry;
217         if( LOG.isDebugEnabled() ){
218             LOG.debug( "RpcRegistry set to " + (rpcRegistry==null?"null":NON_NULL) + "." );
219         }
220     }
221
222         @Override
223         public ListenableFuture<RpcResult<ExecuteGraphOutput>> executeGraph(ExecuteGraphInput input) {
224                 RpcResult<ExecuteGraphOutput> rpcResult = null;
225
226                 SvcLogicService svcLogic = getSvcLogicService();
227                 ExecuteGraphOutputBuilder respBuilder = new ExecuteGraphOutputBuilder();
228
229                 String calledModule = input.getModuleName();
230                 String calledRpc = input.getRpcName();
231                 Mode calledMode = input.getMode();
232                 String modeStr = "sync";
233
234                 if (calledMode == Mode.Async) {
235                         modeStr = "async";
236                 }
237
238                 if (svcLogic == null) {
239                         respBuilder.setResponseCode("500");
240                         respBuilder.setResponseMessage("Could not locate OSGi SvcLogicService service");
241                         respBuilder.setAckFinalIndicator("Y");
242
243                     rpcResult = RpcResultBuilder.<ExecuteGraphOutput> status(true).withResult(respBuilder.build()).build();
244                     return(Futures.immediateFuture(rpcResult));
245                 }
246
247
248                 try {
249                         if (!svcLogic.hasGraph(calledModule, calledRpc, null, modeStr)) {
250                                 respBuilder.setResponseCode("404");
251                                 respBuilder.setResponseMessage("Directed graph for "+calledModule+"/"+calledRpc+"/"+modeStr+" not found");
252                                 respBuilder.setAckFinalIndicator("Y");
253
254                             rpcResult = RpcResultBuilder.<ExecuteGraphOutput> status(true).withResult(respBuilder.build()).build();
255                             return(Futures.immediateFuture(rpcResult));
256                         }
257                 } catch (Exception e) {
258                         LOG.error("Caught exception looking for directed graph for "+calledModule+"/"+calledRpc+"/"+modeStr, e);
259
260                         respBuilder.setResponseCode("500");
261                         respBuilder.setResponseMessage("Internal error : could not determine if target graph exists");
262                         respBuilder.setAckFinalIndicator("Y");
263
264                     rpcResult = RpcResultBuilder.<ExecuteGraphOutput> status(true).withResult(respBuilder.build()).build();
265                     return(Futures.immediateFuture(rpcResult));
266                 }
267
268                 // Load properties
269                 Properties parms = new Properties();
270
271                 // Pass properties using names from sli-parameters
272                 for (SliParameter sliParm : input.getSliParameter()) {
273
274                         String propValue = "";
275
276                         Boolean boolval = sliParm.isBooleanValue();
277
278                         if (boolval != null) {
279                                 propValue = boolval.toString();
280                         } else {
281                                 Integer intval = sliParm.getIntValue();
282                                 if (intval != null) {
283                                         propValue = intval.toString();
284                                 } else {
285                                         propValue = sliParm.getStringValue();
286                                         if (propValue == null) {
287                                                 propValue = "";
288                                         }
289                                 }
290                         }
291                         parms.setProperty(sliParm.getParameterName(), propValue);
292                 }
293
294                 // Also, pass "meta" properties (i.e. pass SliParameter objects themselves)
295                 ExecuteGraphInputBuilder inputBuilder = new ExecuteGraphInputBuilder(input);
296
297                 SliapiHelper.toProperties(parms, "input", inputBuilder);
298
299                 try {
300                         LOG.info("Calling directed graph for "+calledModule+"/"+calledRpc+"/"+modeStr);
301
302                         if (LOG.isTraceEnabled()) {
303                                 StringBuffer argList = new StringBuffer();
304                                 argList.append("Parameters : {");
305                                 Enumeration e = parms.propertyNames();
306                                 while (e.hasMoreElements()) {
307                                         String propName = (String) e.nextElement();
308                                         argList.append(" ("+propName+","+parms.getProperty(propName)+") ");
309                                 }
310                                 argList.append("}");
311                                 LOG.trace(argList.toString());
312                                 argList = null;
313                         }
314
315
316
317                         Properties respProps = svcLogic.execute(calledModule, calledRpc,
318                                         null, modeStr, parms, domDataBroker);
319
320                         StringBuilder sb = new StringBuilder("{");
321
322                         for (Object key : respProps.keySet()) {
323                                 String keyValue = (String) key;
324                                 if (keyValue != null && !"".equals(keyValue) && !keyValue.contains("input.sli-parameter")) {
325                                         sb.append("\"").append(keyValue).append("\": \"").append(respProps.getProperty(keyValue)).append("\",");
326                                 }
327                         }
328
329                         sb.setLength(sb.length() - 1);
330                         sb.append("}");
331
332                         respBuilder.setResponseCode(respProps.getProperty("error-code", "0"));
333                         respBuilder.setResponseMessage(respProps.getProperty("error-message", ""));// TODO change response-text to response-message to match other BVC APIs
334                         respBuilder.setAckFinalIndicator(respProps.getProperty("ack-final", "Y"));
335                         respBuilder.setContextMemoryJson(sb.toString());
336
337                         TestResultBuilder testResultBuilder = new TestResultBuilder();
338
339                         SliapiHelper.toBuilder(respProps, testResultBuilder);
340
341                         String testIdentifier = testResultBuilder.getTestIdentifier();
342
343                         if ((testIdentifier != null) && (testIdentifier.length() > 0)) {
344
345                                 // Add test results to config tree
346                                 LOG.debug("Saving test results for test id "+testIdentifier);
347
348                                 DomSaveTestResult(testResultBuilder.build(), true, LogicalDatastoreType.CONFIGURATION);
349
350                         }
351
352                 } catch (Exception e) {
353                         LOG.error("Caught exception executing directed graph for"
354                                         + calledModule + ":" + calledRpc + "," + modeStr + ">", e);
355
356                         respBuilder.setResponseCode("500");
357                         respBuilder
358                                         .setResponseMessage("Internal error : caught exception executing directed graph "
359                                                         + calledModule
360                                                         + "/"
361                                                         + calledRpc
362                                                         + "/"
363                                                         + modeStr);
364                         respBuilder.setAckFinalIndicator("Y");
365
366                 }
367
368                 rpcResult = RpcResultBuilder.<ExecuteGraphOutput> status(true)
369                                 .withResult(respBuilder.build()).build();
370                 return (Futures.immediateFuture(rpcResult));
371         }
372
373
374         private SvcLogicService getSvcLogicService() {
375             if (svcLogic == null) {
376                 svcLogic = findSvcLogicService();
377             }
378
379             return(svcLogic);
380         }
381         private static SvcLogicService findSvcLogicService() {
382                 BundleContext bctx = FrameworkUtil.getBundle(SvcLogicService.class).getBundleContext();
383
384                 SvcLogicService svcLogic = null;
385
386         // Get SvcLogicService reference
387                 ServiceReference sref = bctx.getServiceReference(SvcLogicService.NAME);
388                 if (sref  != null)
389                 {
390                         svcLogic =  (SvcLogicService) bctx.getService(sref);
391
392                 }
393                 else
394                 {
395                         LOG.warn("Cannot find service reference for "+SvcLogicService.NAME);
396
397                 }
398
399                 return(svcLogic);
400         }
401
402         @Override
403         public ListenableFuture<RpcResult<HealthcheckOutput>> healthcheck(HealthcheckInput healthcheckInput) {
404
405                 RpcResult<HealthcheckOutput> rpcResult = null;
406                 SvcLogicService svcLogic = getSvcLogicService();
407
408                 HealthcheckOutputBuilder respBuilder = new HealthcheckOutputBuilder();
409
410                 String calledModule = "sli";
411                 String calledRpc = "healthcheck";
412                 String modeStr = "sync";
413
414                 if (svcLogic == null) {
415                         respBuilder.setResponseCode("500");
416                         respBuilder.setResponseMessage("Could not locate OSGi SvcLogicService service");
417                         respBuilder.setAckFinalIndicator("Y");
418
419                     rpcResult = RpcResultBuilder.<HealthcheckOutput> failed().withResult(respBuilder.build()).build();
420                     return(Futures.immediateFuture(rpcResult));
421                 }
422
423                 try {
424                         if (!svcLogic.hasGraph(calledModule, calledRpc, null, modeStr)) {
425                                 respBuilder.setResponseCode("404");
426                                 respBuilder.setResponseMessage("Directed graph for "+calledModule+"/"+calledRpc+"/"+modeStr+" not found");
427
428                                 respBuilder.setAckFinalIndicator("Y");
429
430                             rpcResult = RpcResultBuilder.<HealthcheckOutput> status(true).withResult(respBuilder.build()).build();
431                             return(Futures.immediateFuture(rpcResult));
432                         }
433                 } catch (Exception e) {
434                         LOG.error("Caught exception looking for directed graph for "+calledModule+"/"+calledRpc+"/"+modeStr, e);
435
436                         respBuilder.setResponseCode("500");
437                         respBuilder.setResponseMessage("Internal error : could not determine if target graph exists");
438                         respBuilder.setAckFinalIndicator("Y");
439
440                     rpcResult = RpcResultBuilder.<HealthcheckOutput> failed().withResult(respBuilder.build()).build();
441                     return(Futures.immediateFuture(rpcResult));
442                 }
443
444                 try {
445                         LOG.info("Calling directed graph for "+calledModule+"/"+calledRpc+"/"+modeStr);
446
447                         Properties parms = new Properties();
448
449                         Properties respProps = svcLogic.execute(calledModule, calledRpc,
450                                         null, modeStr, parms);
451
452                         respBuilder.setResponseCode(respProps.getProperty("error-code", "0"));
453                         respBuilder.setResponseMessage(respProps.getProperty("error-message", ""));
454                         respBuilder.setAckFinalIndicator(respProps.getProperty("ack-final", "Y"));
455
456                 } catch (Exception e) {
457                         LOG.error("Caught exception executing directed graph for"
458                                         + calledModule + ":" + calledRpc + "," + modeStr + ">", e);
459
460                         respBuilder.setResponseCode("500");
461                         respBuilder
462                                         .setResponseMessage("Internal error : caught exception executing directed graph "
463                                                         + calledModule
464                                                         + "/"
465                                                         + calledRpc
466                                                         + "/"
467                                                         + modeStr);
468                         respBuilder.setAckFinalIndicator("Y");
469
470                 }
471
472                 rpcResult = RpcResultBuilder.<HealthcheckOutput> status(true)
473                                 .withResult(respBuilder.build()).build();
474                 return (Futures.immediateFuture(rpcResult));
475         }
476
477         public ListenableFuture<RpcResult<VlbcheckOutput>> vlbcheck(VlbcheckInput vlbInput) {
478
479                 RpcResult<VlbcheckOutput> rpcResult = null;
480                 SvcLogicService svcLogic = getSvcLogicService();
481
482                 VlbcheckOutputBuilder respBuilder = new VlbcheckOutputBuilder();
483
484                 String calledModule = "sli";
485                 String calledRpc = "vlbcheck";
486                 String modeStr = "sync";
487
488                 if (svcLogic == null) {
489                         respBuilder.setResponseCode("500");
490                         respBuilder.setResponseMessage("Could not locate OSGi SvcLogicService service");
491                         respBuilder.setAckFinalIndicator("Y");
492
493                     rpcResult = RpcResultBuilder.<VlbcheckOutput> failed().withResult(respBuilder.build()).build();
494                     return(Futures.immediateFuture(rpcResult));
495                 }
496
497                 try {
498                         if (!svcLogic.hasGraph(calledModule, calledRpc, null, modeStr)) {
499                                 respBuilder.setResponseCode("404");
500                                 respBuilder.setResponseMessage("Directed graph for "+calledModule+"/"+calledRpc+"/"+modeStr+" not found");
501
502                                 respBuilder.setAckFinalIndicator("Y");
503
504                             rpcResult = RpcResultBuilder.<VlbcheckOutput> status(true).withResult(respBuilder.build()).build();
505                             return(Futures.immediateFuture(rpcResult));
506                         }
507                 } catch (Exception e) {
508                         LOG.error("Caught exception looking for directed graph for "+calledModule+"/"+calledRpc+"/"+modeStr, e);
509
510                         respBuilder.setResponseCode("500");
511                         respBuilder.setResponseMessage("Internal error : could not determine if target graph exists");
512                         respBuilder.setAckFinalIndicator("Y");
513
514                     rpcResult = RpcResultBuilder.<VlbcheckOutput> failed().withResult(respBuilder.build()).build();
515                     return(Futures.immediateFuture(rpcResult));
516                 }
517
518                 try {
519                         LOG.info("Calling directed graph for "+calledModule+"/"+calledRpc+"/"+modeStr);
520
521                         Properties parms = new Properties();
522
523                         Properties respProps = svcLogic.execute(calledModule, calledRpc,
524                                         null, modeStr, parms);
525
526                         respBuilder.setResponseCode(respProps.getProperty("error-code", "0"));
527                         respBuilder.setResponseMessage(respProps.getProperty("error-message", ""));
528                         respBuilder.setAckFinalIndicator(respProps.getProperty("ack-final", "Y"));
529
530                 } catch (Exception e) {
531                         LOG.error("Caught exception executing directed graph for"
532                                         + calledModule + ":" + calledRpc + "," + modeStr + ">", e);
533
534                         respBuilder.setResponseCode("500");
535                         respBuilder
536                                         .setResponseMessage("Internal error : caught exception executing directed graph "
537                                                         + calledModule
538                                                         + "/"
539                                                         + calledRpc
540                                                         + "/"
541                                                         + modeStr);
542                         respBuilder.setAckFinalIndicator("Y");
543
544                 }
545
546                 rpcResult = RpcResultBuilder.<VlbcheckOutput> status(true)
547                                 .withResult(respBuilder.build()).build();
548                 return (Futures.immediateFuture(rpcResult));
549         }
550
551         private void DomSaveTestResult(final TestResult entry, boolean merge, LogicalDatastoreType storeType) {
552
553
554                 if (domDataBroker == null) {
555                         LOG.error("domDataBroker unset - cannot save test result using DOMDataBroker");
556                         return;
557                 }
558
559                 MapEntryNode resultNode = null;
560
561                 try {
562                         resultNode = toMapEntryNode(entry);
563                 } catch (Exception e) {
564                         LOG.error("Caught exception trying to create map entry node", e);
565                 }
566
567                 if (resultNode == null) {
568                         LOG.error("Could not convert entry to MapEntryNode");
569                         return;
570                 }
571
572
573                 YangInstanceIdentifier testResultsPid = YangInstanceIdentifier.builder().node(TEST_RESULTS_QNAME).node(QName.create(TEST_RESULTS_QNAME, "test-result")).build();
574                 YangInstanceIdentifier testResultPid = testResultsPid.node(new NodeIdentifierWithPredicates(TEST_RESULT_QNAME, resultNode.getIdentifier().getKeyValues()));
575
576
577
578                 int tries = 2;
579                 while(true) {
580                         try {
581                                 DOMDataWriteTransaction wtx = domDataBroker.newWriteOnlyTransaction();
582                                 if (merge) {
583                                         LOG.info("Merging test identifier "+entry.getTestIdentifier());
584                                         wtx.merge(storeType, testResultPid, resultNode);
585                                 } else {
586                                         LOG.info("Putting test identifier "+entry.getTestIdentifier());
587                                         wtx.put(storeType,  testResultPid, resultNode);
588                                 }
589                                 wtx.submit().checkedGet();
590                                 LOG.trace("Update DataStore succeeded");
591                                 break;
592                         } catch (final TransactionCommitFailedException e) {
593                                 if(e instanceof OptimisticLockFailedException) {
594                                         if(--tries <= 0) {
595                                                 LOG.trace("Got OptimisticLockFailedException on last try - failing ");
596                                                 throw new IllegalStateException(e);
597                                         }
598                                         LOG.trace("Got OptimisticLockFailedException - trying again ");
599                                 } else {
600                                         LOG.trace("Update DataStore failed");
601                                         throw new IllegalStateException(e);
602                                 }
603                         }
604                 }
605
606         }
607
608                 private void SaveTestResult(final TestResult entry, boolean merge, LogicalDatastoreType storeType) throws IllegalStateException
609                 {
610                         // Each entry will be identifiable by a unique key, we have to create that identifier
611                         
612                         InstanceIdentifier.InstanceIdentifierBuilder<TestResult> testResultIdBuilder =
613                                         InstanceIdentifier.<TestResults>builder(TestResults.class)
614                                         .child(TestResult.class, entry.key());
615                         InstanceIdentifier<TestResult> path = testResultIdBuilder.build();
616                         int tries = 2;
617                         while(true) {
618                                 try {
619                                         WriteTransaction tx = dataBroker.newWriteOnlyTransaction();
620                                         if (merge) {
621                                                 tx.merge(storeType, path, entry);
622                                         } else {
623                                                 tx.put(storeType, path, entry);
624                                         }
625                                         tx.submit().checkedGet();
626                                         LOG.trace("Update DataStore succeeded");
627                                         break;
628                                 } catch (final TransactionCommitFailedException e) {
629                                         if(e instanceof OptimisticLockFailedException) {
630                                                 if(--tries <= 0) {
631                                                         LOG.trace("Got OptimisticLockFailedException on last try - failing ");
632                                                         throw new IllegalStateException(e);
633                                                 }
634                                                 LOG.trace("Got OptimisticLockFailedException - trying again ");
635                                         } else {
636                                                 LOG.trace("Update DataStore failed");
637                                                 throw new IllegalStateException(e);
638                                         }
639                                 }
640                         }
641                 }
642
643                 private MapEntryNode toMapEntryNode(TestResult testResult) {
644
645
646                         YangInstanceIdentifier testResultId = YangInstanceIdentifier.builder().node(TEST_RESULTS_QNAME).node(TEST_RESULT_QNAME).build();
647
648                         // Construct results list
649                         LinkedList<LeafSetEntryNode<Object>> entryList = new LinkedList<>();
650                         for (String result : testResult.getResults()) {
651                                 LeafSetEntryNode<Object> leafSetEntryNode = ImmutableLeafSetEntryNodeBuilder.create()
652                                                                                                                                                                 .withNodeIdentifier(new NodeWithValue(RESULTS_QNAME, result))
653                                                                                                                                                                 .withValue(result)
654                                                                                                                                                                 .build();
655                                 entryList.add(leafSetEntryNode);
656                         }
657                         // Construct results LeafSetNode
658                         LeafSetNode<?> resultsNode = ImmutableLeafSetNodeBuilder.create().withNodeIdentifier(new NodeIdentifier(RESULTS_QNAME)).withValue(entryList).build();
659
660
661
662                         // Construct test result ContainerNode with 2 children - test-identifier leaf and results leaf-set
663                         MapEntryNode testResultNode = ImmutableNodes.mapEntryBuilder()
664                                         .withNodeIdentifier(new NodeIdentifierWithPredicates(TEST_RESULT_QNAME, TEST_ID_QNAME, testResult.getTestIdentifier()))
665                                         .withChild(ImmutableNodes.leafNode(TEST_ID_QNAME, testResult.getTestIdentifier()))
666                                         .withChild(resultsNode)
667                                         .build();
668
669                         return(testResultNode);
670
671                 }
672
673
674 }