2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 AT&T Intellectual Property. All rights
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
12 * http://www.apache.org/licenses/LICENSE-2.0
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=========================================================
22 package org.onap.ccsdk.sli.core.sliapi;
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;
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;
82 import com.google.common.util.concurrent.Futures;
83 import com.google.common.util.concurrent.ListenableFuture;
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.
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):
98 public java.lang.AutoCloseable createInstance() {
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() {
108 public void close() throws Exception {
109 //TODO: CLOSE ANY REGISTRATION OBJECTS CREATED USING ABOVE BROKER/NOTIFICATION
110 //SERVIE/RPC REGISTRY
119 public class sliapiProvider implements AutoCloseable, SLIAPIService{
121 private static final Logger LOG = LoggerFactory.getLogger( sliapiProvider.class );
122 private static final String appName = "slitester";
124 protected DataBroker dataBroker;
125 protected DOMDataBroker domDataBroker;
126 protected NotificationPublishService notificationService;
127 protected RpcProviderRegistry rpcRegistry;
129 private SvcLogicService svcLogic;
131 protected BindingAwareBroker.RpcRegistration<SLIAPIService> rpcRegistration;
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;
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";
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");
152 public sliapiProvider(
153 DataBroker dataBroker,
154 NotificationPublishService notificationPublishService,
155 RpcProviderRegistry rpcProviderRegistry) {
156 this(dataBroker, notificationPublishService, rpcProviderRegistry, findSvcLogicService());
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;
174 public void initialize(){
175 LOG.info( "Initializing provider for " + appName );
176 //initialization code goes here.
177 rpcRegistration = rpcRegistry.addRpcImplementation(SLIAPIService.class, this);
179 sdncStatusFile = System.getenv(SDNC_STATUS_FILE);
180 LOG.info( "SDNC STATUS FILE = " + sdncStatusFile );
181 LOG.info( "Initialization complete for " + appName );
184 protected void initializeChild() {
185 //Override if you have custom initialization intelligence
189 public void close() throws Exception {
190 LOG.info( "Closing provider for " + appName );
191 //closing code goes here
193 rpcRegistration.close();
194 LOG.info( "Successfully closed provider for " + appName );
197 public void setDataBroker(DataBroker dataBroker) {
198 this.dataBroker = dataBroker;
199 if (dataBroker instanceof AbstractForwardedDataBroker) {
200 domDataBroker = ((AbstractForwardedDataBroker) dataBroker).getDelegate();
202 if( LOG.isDebugEnabled() ){
203 LOG.debug( "DataBroker set to " + (dataBroker==null?"null":NON_NULL) + "." );
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) + "." );
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) + "." );
223 public ListenableFuture<RpcResult<ExecuteGraphOutput>> executeGraph(ExecuteGraphInput input) {
224 RpcResult<ExecuteGraphOutput> rpcResult = null;
226 SvcLogicService svcLogic = getSvcLogicService();
227 ExecuteGraphOutputBuilder respBuilder = new ExecuteGraphOutputBuilder();
229 String calledModule = input.getModuleName();
230 String calledRpc = input.getRpcName();
231 Mode calledMode = input.getMode();
232 String modeStr = "sync";
234 if (calledMode == Mode.Async) {
238 if (svcLogic == null) {
239 respBuilder.setResponseCode("500");
240 respBuilder.setResponseMessage("Could not locate OSGi SvcLogicService service");
241 respBuilder.setAckFinalIndicator("Y");
243 rpcResult = RpcResultBuilder.<ExecuteGraphOutput> status(true).withResult(respBuilder.build()).build();
244 return(Futures.immediateFuture(rpcResult));
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");
254 rpcResult = RpcResultBuilder.<ExecuteGraphOutput> status(true).withResult(respBuilder.build()).build();
255 return(Futures.immediateFuture(rpcResult));
257 } catch (Exception e) {
258 LOG.error("Caught exception looking for directed graph for "+calledModule+"/"+calledRpc+"/"+modeStr, e);
260 respBuilder.setResponseCode("500");
261 respBuilder.setResponseMessage("Internal error : could not determine if target graph exists");
262 respBuilder.setAckFinalIndicator("Y");
264 rpcResult = RpcResultBuilder.<ExecuteGraphOutput> status(true).withResult(respBuilder.build()).build();
265 return(Futures.immediateFuture(rpcResult));
269 Properties parms = new Properties();
271 // Pass properties using names from sli-parameters
272 for (SliParameter sliParm : input.getSliParameter()) {
274 String propValue = "";
276 Boolean boolval = sliParm.isBooleanValue();
278 if (boolval != null) {
279 propValue = boolval.toString();
281 Integer intval = sliParm.getIntValue();
282 if (intval != null) {
283 propValue = intval.toString();
285 propValue = sliParm.getStringValue();
286 if (propValue == null) {
291 parms.setProperty(sliParm.getParameterName(), propValue);
294 // Also, pass "meta" properties (i.e. pass SliParameter objects themselves)
295 ExecuteGraphInputBuilder inputBuilder = new ExecuteGraphInputBuilder(input);
297 SliapiHelper.toProperties(parms, "input", inputBuilder);
300 LOG.info("Calling directed graph for "+calledModule+"/"+calledRpc+"/"+modeStr);
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)+") ");
311 LOG.trace(argList.toString());
317 Properties respProps = svcLogic.execute(calledModule, calledRpc,
318 null, modeStr, parms, domDataBroker);
320 StringBuilder sb = new StringBuilder("{");
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("\",");
329 sb.setLength(sb.length() - 1);
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());
337 TestResultBuilder testResultBuilder = new TestResultBuilder();
339 SliapiHelper.toBuilder(respProps, testResultBuilder);
341 String testIdentifier = testResultBuilder.getTestIdentifier();
343 if ((testIdentifier != null) && (testIdentifier.length() > 0)) {
345 // Add test results to config tree
346 LOG.debug("Saving test results for test id "+testIdentifier);
348 DomSaveTestResult(testResultBuilder.build(), true, LogicalDatastoreType.CONFIGURATION);
352 } catch (Exception e) {
353 LOG.error("Caught exception executing directed graph for"
354 + calledModule + ":" + calledRpc + "," + modeStr + ">", e);
356 respBuilder.setResponseCode("500");
358 .setResponseMessage("Internal error : caught exception executing directed graph "
364 respBuilder.setAckFinalIndicator("Y");
368 rpcResult = RpcResultBuilder.<ExecuteGraphOutput> status(true)
369 .withResult(respBuilder.build()).build();
370 return (Futures.immediateFuture(rpcResult));
374 private SvcLogicService getSvcLogicService() {
375 if (svcLogic == null) {
376 svcLogic = findSvcLogicService();
381 private static SvcLogicService findSvcLogicService() {
382 BundleContext bctx = FrameworkUtil.getBundle(SvcLogicService.class).getBundleContext();
384 SvcLogicService svcLogic = null;
386 // Get SvcLogicService reference
387 ServiceReference sref = bctx.getServiceReference(SvcLogicService.NAME);
390 svcLogic = (SvcLogicService) bctx.getService(sref);
395 LOG.warn("Cannot find service reference for "+SvcLogicService.NAME);
403 public ListenableFuture<RpcResult<HealthcheckOutput>> healthcheck(HealthcheckInput healthcheckInput) {
405 RpcResult<HealthcheckOutput> rpcResult = null;
406 SvcLogicService svcLogic = getSvcLogicService();
408 HealthcheckOutputBuilder respBuilder = new HealthcheckOutputBuilder();
410 String calledModule = "sli";
411 String calledRpc = "healthcheck";
412 String modeStr = "sync";
414 if (svcLogic == null) {
415 respBuilder.setResponseCode("500");
416 respBuilder.setResponseMessage("Could not locate OSGi SvcLogicService service");
417 respBuilder.setAckFinalIndicator("Y");
419 rpcResult = RpcResultBuilder.<HealthcheckOutput> failed().withResult(respBuilder.build()).build();
420 return(Futures.immediateFuture(rpcResult));
424 if (!svcLogic.hasGraph(calledModule, calledRpc, null, modeStr)) {
425 respBuilder.setResponseCode("404");
426 respBuilder.setResponseMessage("Directed graph for "+calledModule+"/"+calledRpc+"/"+modeStr+" not found");
428 respBuilder.setAckFinalIndicator("Y");
430 rpcResult = RpcResultBuilder.<HealthcheckOutput> status(true).withResult(respBuilder.build()).build();
431 return(Futures.immediateFuture(rpcResult));
433 } catch (Exception e) {
434 LOG.error("Caught exception looking for directed graph for "+calledModule+"/"+calledRpc+"/"+modeStr, e);
436 respBuilder.setResponseCode("500");
437 respBuilder.setResponseMessage("Internal error : could not determine if target graph exists");
438 respBuilder.setAckFinalIndicator("Y");
440 rpcResult = RpcResultBuilder.<HealthcheckOutput> failed().withResult(respBuilder.build()).build();
441 return(Futures.immediateFuture(rpcResult));
445 LOG.info("Calling directed graph for "+calledModule+"/"+calledRpc+"/"+modeStr);
447 Properties parms = new Properties();
449 Properties respProps = svcLogic.execute(calledModule, calledRpc,
450 null, modeStr, parms);
452 respBuilder.setResponseCode(respProps.getProperty("error-code", "0"));
453 respBuilder.setResponseMessage(respProps.getProperty("error-message", ""));
454 respBuilder.setAckFinalIndicator(respProps.getProperty("ack-final", "Y"));
456 } catch (Exception e) {
457 LOG.error("Caught exception executing directed graph for"
458 + calledModule + ":" + calledRpc + "," + modeStr + ">", e);
460 respBuilder.setResponseCode("500");
462 .setResponseMessage("Internal error : caught exception executing directed graph "
468 respBuilder.setAckFinalIndicator("Y");
472 rpcResult = RpcResultBuilder.<HealthcheckOutput> status(true)
473 .withResult(respBuilder.build()).build();
474 return (Futures.immediateFuture(rpcResult));
477 public ListenableFuture<RpcResult<VlbcheckOutput>> vlbcheck(VlbcheckInput vlbInput) {
479 RpcResult<VlbcheckOutput> rpcResult = null;
480 SvcLogicService svcLogic = getSvcLogicService();
482 VlbcheckOutputBuilder respBuilder = new VlbcheckOutputBuilder();
484 String calledModule = "sli";
485 String calledRpc = "vlbcheck";
486 String modeStr = "sync";
488 if (svcLogic == null) {
489 respBuilder.setResponseCode("500");
490 respBuilder.setResponseMessage("Could not locate OSGi SvcLogicService service");
491 respBuilder.setAckFinalIndicator("Y");
493 rpcResult = RpcResultBuilder.<VlbcheckOutput> failed().withResult(respBuilder.build()).build();
494 return(Futures.immediateFuture(rpcResult));
498 if (!svcLogic.hasGraph(calledModule, calledRpc, null, modeStr)) {
499 respBuilder.setResponseCode("404");
500 respBuilder.setResponseMessage("Directed graph for "+calledModule+"/"+calledRpc+"/"+modeStr+" not found");
502 respBuilder.setAckFinalIndicator("Y");
504 rpcResult = RpcResultBuilder.<VlbcheckOutput> status(true).withResult(respBuilder.build()).build();
505 return(Futures.immediateFuture(rpcResult));
507 } catch (Exception e) {
508 LOG.error("Caught exception looking for directed graph for "+calledModule+"/"+calledRpc+"/"+modeStr, e);
510 respBuilder.setResponseCode("500");
511 respBuilder.setResponseMessage("Internal error : could not determine if target graph exists");
512 respBuilder.setAckFinalIndicator("Y");
514 rpcResult = RpcResultBuilder.<VlbcheckOutput> failed().withResult(respBuilder.build()).build();
515 return(Futures.immediateFuture(rpcResult));
519 LOG.info("Calling directed graph for "+calledModule+"/"+calledRpc+"/"+modeStr);
521 Properties parms = new Properties();
523 Properties respProps = svcLogic.execute(calledModule, calledRpc,
524 null, modeStr, parms);
526 respBuilder.setResponseCode(respProps.getProperty("error-code", "0"));
527 respBuilder.setResponseMessage(respProps.getProperty("error-message", ""));
528 respBuilder.setAckFinalIndicator(respProps.getProperty("ack-final", "Y"));
530 } catch (Exception e) {
531 LOG.error("Caught exception executing directed graph for"
532 + calledModule + ":" + calledRpc + "," + modeStr + ">", e);
534 respBuilder.setResponseCode("500");
536 .setResponseMessage("Internal error : caught exception executing directed graph "
542 respBuilder.setAckFinalIndicator("Y");
546 rpcResult = RpcResultBuilder.<VlbcheckOutput> status(true)
547 .withResult(respBuilder.build()).build();
548 return (Futures.immediateFuture(rpcResult));
551 private void DomSaveTestResult(final TestResult entry, boolean merge, LogicalDatastoreType storeType) {
554 if (domDataBroker == null) {
555 LOG.error("domDataBroker unset - cannot save test result using DOMDataBroker");
559 MapEntryNode resultNode = null;
562 resultNode = toMapEntryNode(entry);
563 } catch (Exception e) {
564 LOG.error("Caught exception trying to create map entry node", e);
567 if (resultNode == null) {
568 LOG.error("Could not convert entry to MapEntryNode");
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()));
581 DOMDataWriteTransaction wtx = domDataBroker.newWriteOnlyTransaction();
583 LOG.info("Merging test identifier "+entry.getTestIdentifier());
584 wtx.merge(storeType, testResultPid, resultNode);
586 LOG.info("Putting test identifier "+entry.getTestIdentifier());
587 wtx.put(storeType, testResultPid, resultNode);
589 wtx.submit().checkedGet();
590 LOG.trace("Update DataStore succeeded");
592 } catch (final TransactionCommitFailedException e) {
593 if(e instanceof OptimisticLockFailedException) {
595 LOG.trace("Got OptimisticLockFailedException on last try - failing ");
596 throw new IllegalStateException(e);
598 LOG.trace("Got OptimisticLockFailedException - trying again ");
600 LOG.trace("Update DataStore failed");
601 throw new IllegalStateException(e);
608 private void SaveTestResult(final TestResult entry, boolean merge, LogicalDatastoreType storeType) throws IllegalStateException
610 // Each entry will be identifiable by a unique key, we have to create that identifier
612 InstanceIdentifier.InstanceIdentifierBuilder<TestResult> testResultIdBuilder =
613 InstanceIdentifier.<TestResults>builder(TestResults.class)
614 .child(TestResult.class, entry.key());
615 InstanceIdentifier<TestResult> path = testResultIdBuilder.build();
619 WriteTransaction tx = dataBroker.newWriteOnlyTransaction();
621 tx.merge(storeType, path, entry);
623 tx.put(storeType, path, entry);
625 tx.submit().checkedGet();
626 LOG.trace("Update DataStore succeeded");
628 } catch (final TransactionCommitFailedException e) {
629 if(e instanceof OptimisticLockFailedException) {
631 LOG.trace("Got OptimisticLockFailedException on last try - failing ");
632 throw new IllegalStateException(e);
634 LOG.trace("Got OptimisticLockFailedException - trying again ");
636 LOG.trace("Update DataStore failed");
637 throw new IllegalStateException(e);
643 private MapEntryNode toMapEntryNode(TestResult testResult) {
646 YangInstanceIdentifier testResultId = YangInstanceIdentifier.builder().node(TEST_RESULTS_QNAME).node(TEST_RESULT_QNAME).build();
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))
655 entryList.add(leafSetEntryNode);
657 // Construct results LeafSetNode
658 LeafSetNode<?> resultsNode = ImmutableLeafSetNodeBuilder.create().withNodeIdentifier(new NodeIdentifier(RESULTS_QNAME)).withValue(entryList).build();
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)
669 return(testResultNode);