summaryrefslogtreecommitdiffstats
path: root/cps-service
diff options
context:
space:
mode:
Diffstat (limited to 'cps-service')
-rw-r--r--cps-service/pom.xml4
-rwxr-xr-xcps-service/src/main/java/org/onap/cps/api/impl/CpsDataServiceImpl.java12
-rw-r--r--cps-service/src/main/java/org/onap/cps/utils/YangUtils.java2
-rw-r--r--cps-service/src/test/groovy/org/onap/cps/api/impl/CpsDataServiceImplSpec.groovy22
-rw-r--r--cps-service/src/test/resources/bookstore.json8
-rw-r--r--cps-service/src/test/resources/bookstore.yang28
6 files changed, 71 insertions, 5 deletions
diff --git a/cps-service/pom.xml b/cps-service/pom.xml
index dffc38da4c..c97623f2a1 100644
--- a/cps-service/pom.xml
+++ b/cps-service/pom.xml
@@ -29,14 +29,14 @@
<parent>
<groupId>org.onap.cps</groupId>
<artifactId>cps-parent</artifactId>
- <version>3.3.4-SNAPSHOT</version>
+ <version>3.3.6-SNAPSHOT</version>
<relativePath>../cps-parent/pom.xml</relativePath>
</parent>
<artifactId>cps-service</artifactId>
<properties>
- <minimum-coverage>0.94</minimum-coverage>
+ <minimum-coverage>0.95</minimum-coverage>
</properties>
<dependencies>
diff --git a/cps-service/src/main/java/org/onap/cps/api/impl/CpsDataServiceImpl.java b/cps-service/src/main/java/org/onap/cps/api/impl/CpsDataServiceImpl.java
index 6e7c1649d7..7db87e87ea 100755
--- a/cps-service/src/main/java/org/onap/cps/api/impl/CpsDataServiceImpl.java
+++ b/cps-service/src/main/java/org/onap/cps/api/impl/CpsDataServiceImpl.java
@@ -116,8 +116,12 @@ public class CpsDataServiceImpl implements CpsDataService {
final Anchor anchor = cpsAdminService.getAnchor(dataspaceName, anchorName);
final Collection<DataNode> listElementDataNodeCollection =
buildDataNodes(anchor, parentNodeXpath, jsonData, ContentType.JSON);
- cpsDataPersistenceService.addListElements(dataspaceName, anchorName, parentNodeXpath,
- listElementDataNodeCollection);
+ if (isRootNodeXpath(parentNodeXpath)) {
+ cpsDataPersistenceService.storeDataNodes(dataspaceName, anchorName, listElementDataNodeCollection);
+ } else {
+ cpsDataPersistenceService.addListElements(dataspaceName, anchorName, parentNodeXpath,
+ listElementDataNodeCollection);
+ }
processDataUpdatedEventAsync(anchor, parentNodeXpath, UPDATE, observedTimestamp);
}
@@ -391,6 +395,10 @@ public class CpsDataServiceImpl implements CpsDataService {
.get(anchor.getDataspaceName(), anchor.getSchemaSetName()).getSchemaContext();
}
+ private static boolean isRootNodeXpath(final String xpath) {
+ return ROOT_NODE_XPATH.equals(xpath);
+ }
+
private void processDataNodeUpdate(final Anchor anchor, final DataNode dataNodeUpdate) {
cpsDataPersistenceService.batchUpdateDataLeaves(anchor.getDataspaceName(), anchor.getName(),
Collections.singletonMap(dataNodeUpdate.getXpath(), dataNodeUpdate.getLeaves()));
diff --git a/cps-service/src/main/java/org/onap/cps/utils/YangUtils.java b/cps-service/src/main/java/org/onap/cps/utils/YangUtils.java
index 7da4024156..f00f9442ce 100644
--- a/cps-service/src/main/java/org/onap/cps/utils/YangUtils.java
+++ b/cps-service/src/main/java/org/onap/cps/utils/YangUtils.java
@@ -253,7 +253,7 @@ public class YangUtils {
final List<String> keyAttributes = nodeIdentifier.entrySet().stream().map(
entry -> {
final String name = entry.getKey().getLocalName();
- final String value = String.valueOf(entry.getValue()).replace("'", "\\'");
+ final String value = String.valueOf(entry.getValue()).replace("'", "''");
return String.format("@%s='%s'", name, value);
}
).collect(Collectors.toList());
diff --git a/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsDataServiceImplSpec.groovy b/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsDataServiceImplSpec.groovy
index db8664042a..ba438496fd 100644
--- a/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsDataServiceImplSpec.groovy
+++ b/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsDataServiceImplSpec.groovy
@@ -110,6 +110,28 @@ class CpsDataServiceImplSpec extends Specification {
noExceptionThrown()
}
+ def 'Saving list element data fragment under Root node.'() {
+ given: 'schema set for given anchor and dataspace references bookstore model'
+ setupSchemaSetMocks('bookstore.yang')
+ when: 'save data method is invoked with list element json data'
+ def jsonData = '{"multiple-data-tree:invoice": [{"ProductID": "2","ProductName": "Banana","price": "100","stock": True}]}'
+ objectUnderTest.saveListElements(dataspaceName, anchorName, '/', jsonData, observedTimestamp)
+ then: 'the persistence service method is invoked with correct parameters'
+ 1 * mockCpsDataPersistenceService.storeDataNodes(dataspaceName, anchorName,
+ { dataNodeCollection ->
+ {
+ assert dataNodeCollection.size() == 1
+ assert dataNodeCollection.collect { it.getXpath() }
+ .containsAll(['/invoice[@ProductID=\'2\']'])
+ }
+ }
+ )
+ and: 'the CpsValidator is called on the dataspaceName and AnchorName'
+ 1 * mockCpsValidator.validateNameCharacters(dataspaceName, anchorName)
+ and: 'data updated event is sent to notification service'
+ 1 * mockNotificationService.processDataUpdatedEvent(anchor, '/', Operation.UPDATE, observedTimestamp)
+ }
+
def 'Saving child data fragment under existing node.'() {
given: 'schema set for given anchor and dataspace references test-tree model'
setupSchemaSetMocks('test-tree.yang')
diff --git a/cps-service/src/test/resources/bookstore.json b/cps-service/src/test/resources/bookstore.json
index 459908bd63..4b8ed3dab1 100644
--- a/cps-service/src/test/resources/bookstore.json
+++ b/cps-service/src/test/resources/bookstore.json
@@ -1,4 +1,12 @@
{
+ "multiple-data-tree:invoice": [
+ {
+ "ProductID": "1",
+ "ProductName": "Apple",
+ "price": "100",
+ "stock": false
+ }
+ ],
"test:bookstore":{
"bookstore-name": "Chapters/Easons",
"categories": [
diff --git a/cps-service/src/test/resources/bookstore.yang b/cps-service/src/test/resources/bookstore.yang
index 2179fb93d9..b7a52e2c8c 100644
--- a/cps-service/src/test/resources/bookstore.yang
+++ b/cps-service/src/test/resources/bookstore.yang
@@ -15,6 +15,34 @@ module stores {
}
}
+ list invoice {
+ key "ProductID";
+ leaf ProductID {
+ type uint64;
+ mandatory "true";
+ description
+ "Unique product ID. Example: 001";
+ }
+ leaf ProductName {
+ type string;
+ mandatory "true";
+ description
+ "Name of the Product";
+ }
+ leaf price {
+ type uint64;
+ mandatory "true";
+ description
+ "Price of book";
+ }
+ leaf stock {
+ type boolean;
+ default "false";
+ description
+ "Book in stock or not. Example value: true";
+ }
+ }
+
container bookstore {
leaf bookstore-name {