summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xcps-dependencies/pom.xml4
-rwxr-xr-xcps-parent/pom.xml1
-rw-r--r--cps-ri/pom.xml1
-rwxr-xr-xcps-ri/src/main/java/org/onap/cps/spi/impl/CpsModulePersistenceServiceImpl.java7
-rw-r--r--cps-ri/src/test/groovy/org/onap/cps/spi/performance/CpsToDataNodePerfTest.groovy60
-rw-r--r--cps-ri/src/test/resources/data/perf-test.sql28
-rwxr-xr-xcps-service/src/main/java/org/onap/cps/api/impl/CpsDataServiceImpl.java6
-rw-r--r--cps-service/src/main/java/org/onap/cps/spi/model/DataNodeBuilder.java31
-rw-r--r--cps-service/src/main/java/org/onap/cps/utils/YangUtils.java78
-rw-r--r--cps-service/src/main/java/org/onap/cps/yang/YangTextSchemaSourceSetBuilder.java8
-rw-r--r--cps-service/src/test/groovy/org/onap/cps/utils/JsonParserStreamSpec.groovy6
-rw-r--r--cps-service/src/test/groovy/org/onap/cps/utils/YangUtilsSpec.groovy8
-rwxr-xr-xcsit/prepare-csit.sh13
-rw-r--r--csit/pylibs.txt2
-rwxr-xr-xcsit/run-csit.sh2
15 files changed, 173 insertions, 82 deletions
diff --git a/cps-dependencies/pom.xml b/cps-dependencies/pom.xml
index e69e571e5e..5bdf793fce 100755
--- a/cps-dependencies/pom.xml
+++ b/cps-dependencies/pom.xml
@@ -73,7 +73,7 @@
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
- <version>2.6.9</version>
+ <version>2.6.14</version>
<type>pom</type>
<scope>import</scope>
</dependency>
@@ -87,7 +87,7 @@
<dependency>
<groupId>org.opendaylight.yangtools</groupId>
<artifactId>yangtools-artifacts</artifactId>
- <version>6.0.1</version>
+ <version>8.0.6</version>
<type>pom</type>
<scope>import</scope>
</dependency>
diff --git a/cps-parent/pom.xml b/cps-parent/pom.xml
index 0a8798a54a..d3fe0f3578 100755
--- a/cps-parent/pom.xml
+++ b/cps-parent/pom.xml
@@ -39,6 +39,7 @@
<app>org.onap.cps.Application</app>
<java.version>11</java.version>
<minimum-coverage>0.97</minimum-coverage>
+ <postgres.version>42.5.0</postgres.version>
<jacoco.reportDirectory.aggregate>${project.reporting.outputDirectory}/jacoco-aggregate</jacoco.reportDirectory.aggregate>
<sonar.coverage.jacoco.xmlReportPaths>
diff --git a/cps-ri/pom.xml b/cps-ri/pom.xml
index 4ced335e5f..b6fe284c2e 100644
--- a/cps-ri/pom.xml
+++ b/cps-ri/pom.xml
@@ -61,6 +61,7 @@
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
+ <version>${postgres.version}</version>
</dependency>
<!-- Add Hibernate support for Postgres datatype JSONB -->
<dependency>
diff --git a/cps-ri/src/main/java/org/onap/cps/spi/impl/CpsModulePersistenceServiceImpl.java b/cps-ri/src/main/java/org/onap/cps/spi/impl/CpsModulePersistenceServiceImpl.java
index 400e9b3e83..8008e0324a 100755
--- a/cps-ri/src/main/java/org/onap/cps/spi/impl/CpsModulePersistenceServiceImpl.java
+++ b/cps-ri/src/main/java/org/onap/cps/spi/impl/CpsModulePersistenceServiceImpl.java
@@ -60,9 +60,9 @@ import org.onap.cps.spi.repository.ModuleReferenceRepository;
import org.onap.cps.spi.repository.SchemaSetRepository;
import org.onap.cps.spi.repository.YangResourceRepository;
import org.opendaylight.yangtools.yang.common.Revision;
-import org.opendaylight.yangtools.yang.model.parser.api.YangSyntaxErrorException;
import org.opendaylight.yangtools.yang.model.repo.api.RevisionSourceIdentifier;
import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource;
+import org.opendaylight.yangtools.yang.parser.api.YangSyntaxErrorException;
import org.opendaylight.yangtools.yang.parser.rfc7950.repo.YangModelDependencyInfo;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.retry.annotation.Backoff;
@@ -252,6 +252,11 @@ public class CpsModulePersistenceServiceImpl implements CpsModulePersistenceServ
final var tempYangTextSchemaSource = new YangTextSchemaSource(revisionSourceIdentifier) {
@Override
+ public Optional<String> getSymbolicName() {
+ return Optional.empty();
+ }
+
+ @Override
protected MoreObjects.ToStringHelper addToStringAttributes(
final MoreObjects.ToStringHelper toStringHelper) {
return toStringHelper;
diff --git a/cps-ri/src/test/groovy/org/onap/cps/spi/performance/CpsToDataNodePerfTest.groovy b/cps-ri/src/test/groovy/org/onap/cps/spi/performance/CpsToDataNodePerfTest.groovy
index a3e2e92ecb..fb6749c3fe 100644
--- a/cps-ri/src/test/groovy/org/onap/cps/spi/performance/CpsToDataNodePerfTest.groovy
+++ b/cps-ri/src/test/groovy/org/onap/cps/spi/performance/CpsToDataNodePerfTest.groovy
@@ -31,14 +31,16 @@ import static org.onap.cps.spi.FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS
class CpsToDataNodePerfTest extends CpsPersistenceSpecBase {
- static final String SET_DATA = '/data/fragment.sql'
+ static final String PERF_TEST_DATA = '/data/perf-test.sql'
@Autowired
CpsDataPersistenceService objectUnderTest
- def XPATH_DATA_NODE_WITH_DESCENDANTS = '/parent-1'
+ def PERF_TEST_PARENT = '/perf-parent-1'
- @Sql([CLEAR_DATA, SET_DATA])
+ def EXPECTED_NUMBER_OF_NODES = 10051 // 1 Parent + 50 Children + 10000 Grand-children
+
+ @Sql([CLEAR_DATA, PERF_TEST_DATA])
def 'Get data node by xpath with all descendants with many children'() {
given: 'nodes and grandchildren have been persisted'
def setupStopWatch = new StopWatch()
@@ -46,43 +48,65 @@ class CpsToDataNodePerfTest extends CpsPersistenceSpecBase {
createLineage()
setupStopWatch.stop()
def setupDurationInMillis = setupStopWatch.getTime()
- when: 'data node is requested with all descendants'
+ and: 'setup duration is under 8000 milliseconds'
+ assert setupDurationInMillis < 8000
+ when: 'get parent is executed with all descendants'
def readStopWatch = new StopWatch()
readStopWatch.start()
- def result = objectUnderTest.getDataNode(DATASPACE_NAME, ANCHOR_NAME1, XPATH_DATA_NODE_WITH_DESCENDANTS, INCLUDE_ALL_DESCENDANTS)
+ def result = objectUnderTest.getDataNode('PERF-DATASPACE', 'PERF-ANCHOR', PERF_TEST_PARENT, INCLUDE_ALL_DESCENDANTS)
readStopWatch.stop()
def readDurationInMillis = readStopWatch.getTime()
- then: 'setup duration is under 2500 milliseconds'
- assert setupDurationInMillis < 2500
- and: 'read duration is under 180 milliseconds'
- assert readDurationInMillis < 180
+ then: 'read duration is under 450 milliseconds'
+ assert readDurationInMillis < 450
+ and: 'data node is returned with all the descendants populated'
+ assert countDataNodes(result) == EXPECTED_NUMBER_OF_NODES
+ when: 'get root is executed with all descendants'
+ readStopWatch.reset()
+ readStopWatch.start()
+ result = objectUnderTest.getDataNode('PERF-DATASPACE', 'PERF-ANCHOR', '', INCLUDE_ALL_DESCENDANTS)
+ readStopWatch.stop()
+ readDurationInMillis = readStopWatch.getTime()
+ then: 'read duration is under 450 milliseconds'
+ assert readDurationInMillis < 450
+ and: 'data node is returned with all the descendants populated'
+ assert countDataNodes(result) == EXPECTED_NUMBER_OF_NODES
+ when: 'query is executed with all descendants'
+ readStopWatch.reset()
+ readStopWatch.start()
+ result = objectUnderTest.queryDataNodes('PERF-DATASPACE', 'PERF-ANCHOR', '//perf-parent-1', INCLUDE_ALL_DESCENDANTS)
+ readStopWatch.stop()
+ readDurationInMillis = readStopWatch.getTime()
+ then: 'read duration is under 450 milliseconds'
+ assert readDurationInMillis < 450
and: 'data node is returned with all the descendants populated'
- assert countDataNodes(result) == 1533
+ assert countDataNodes(result) == EXPECTED_NUMBER_OF_NODES
}
def createLineage() {
- def numOfChildren = 30
- def numOfGrandChildren = 50
+ def numOfChildren = 50
+ def numOfGrandChildren = 200
(1..numOfChildren).each {
def childName = "perf-test-child-${it}".toString()
- def newChild = goForthAndMultiply(XPATH_DATA_NODE_WITH_DESCENDANTS, childName, numOfGrandChildren)
- objectUnderTest.addChildDataNode(DATASPACE_NAME, ANCHOR_NAME1, XPATH_DATA_NODE_WITH_DESCENDANTS, newChild)
+ def newChild = goForthAndMultiply(PERF_TEST_PARENT, childName, numOfGrandChildren)
+ objectUnderTest.addChildDataNode('PERF-DATASPACE', 'PERF-ANCHOR', PERF_TEST_PARENT, newChild)
}
}
def goForthAndMultiply(parentXpath, childName, numOfGrandChildren) {
def children = []
(1..numOfGrandChildren).each {
- def child = new DataNodeBuilder().withXpath("${parentXpath}/${childName}/${it}-grand-child").build()
+ def child = new DataNodeBuilder().withXpath("${parentXpath}/${childName}/${it}perf-test-grand-child").build()
children.add(child)
}
return new DataNodeBuilder().withXpath("${parentXpath}/${childName}").withChildDataNodes(children).build()
}
- def countDataNodes(DataNode dataNode) {
+ def countDataNodes(dataNodes) {
int nodeCount = 1
- for (DataNode child : dataNode.childDataNodes) {
- nodeCount = nodeCount + (countDataNodes(child))
+ for (DataNode parent : dataNodes) {
+ for (DataNode child : parent.childDataNodes) {
+ nodeCount = nodeCount + (countDataNodes(child))
+ }
}
return nodeCount
}
diff --git a/cps-ri/src/test/resources/data/perf-test.sql b/cps-ri/src/test/resources/data/perf-test.sql
new file mode 100644
index 0000000000..5119f26b24
--- /dev/null
+++ b/cps-ri/src/test/resources/data/perf-test.sql
@@ -0,0 +1,28 @@
+/*
+ ============LICENSE_START=======================================================
+ Copyright (C) 2022 Nordix Foundation.
+ ================================================================================
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+ SPDX-License-Identifier: Apache-2.0
+ ============LICENSE_END=========================================================
+*/
+
+INSERT INTO DATASPACE (ID, NAME) VALUES (9001, 'PERF-DATASPACE');
+
+INSERT INTO SCHEMA_SET (ID, NAME, DATASPACE_ID) VALUES (9002, 'PERF-SCHEMA-SET', 9001);
+
+INSERT INTO ANCHOR (ID, NAME, DATASPACE_ID, SCHEMA_SET_ID) VALUES (9003, 'PERF-ANCHOR', 9001, 9002);
+
+INSERT INTO FRAGMENT (ID, DATASPACE_ID, ANCHOR_ID, PARENT_ID, XPATH) VALUES (0, 9001, 9003, null, '/perf-parent-1');
+
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 88ebe3bd01..b08d8c1eba 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
@@ -226,11 +226,11 @@ public class CpsDataServiceImpl implements CpsDataService {
final SchemaContext schemaContext = getSchemaContext(dataspaceName, anchor.getSchemaSetName());
if (ROOT_NODE_XPATH.equals(parentNodeXpath)) {
- final NormalizedNode<?, ?> normalizedNode = YangUtils.parseJsonData(jsonData, schemaContext);
+ final NormalizedNode normalizedNode = YangUtils.parseJsonData(jsonData, schemaContext);
return new DataNodeBuilder().withNormalizedNodeTree(normalizedNode).build();
}
- final NormalizedNode<?, ?> normalizedNode = YangUtils.parseJsonData(jsonData, schemaContext, parentNodeXpath);
+ final NormalizedNode normalizedNode = YangUtils.parseJsonData(jsonData, schemaContext, parentNodeXpath);
return new DataNodeBuilder()
.withParentNodeXpath(parentNodeXpath)
.withNormalizedNodeTree(normalizedNode)
@@ -252,7 +252,7 @@ public class CpsDataServiceImpl implements CpsDataService {
final Anchor anchor = cpsAdminService.getAnchor(dataspaceName, anchorName);
final SchemaContext schemaContext = getSchemaContext(dataspaceName, anchor.getSchemaSetName());
- final NormalizedNode<?, ?> normalizedNode = YangUtils.parseJsonData(jsonData, schemaContext, parentNodeXpath);
+ final NormalizedNode normalizedNode = YangUtils.parseJsonData(jsonData, schemaContext, parentNodeXpath);
final Collection<DataNode> dataNodes = new DataNodeBuilder()
.withParentNodeXpath(parentNodeXpath)
.withNormalizedNodeTree(normalizedNode)
diff --git a/cps-service/src/main/java/org/onap/cps/spi/model/DataNodeBuilder.java b/cps-service/src/main/java/org/onap/cps/spi/model/DataNodeBuilder.java
index f2bde03a01..eaa2d77f47 100644
--- a/cps-service/src/main/java/org/onap/cps/spi/model/DataNodeBuilder.java
+++ b/cps-service/src/main/java/org/onap/cps/spi/model/DataNodeBuilder.java
@@ -44,7 +44,7 @@ import org.opendaylight.yangtools.yang.data.api.schema.ValueNode;
@Slf4j
public class DataNodeBuilder {
- private NormalizedNode<?, ?> normalizedNodeTree;
+ private NormalizedNode normalizedNodeTree;
private String xpath;
private String moduleNamePrefix;
private String parentNodeXpath = "";
@@ -69,7 +69,7 @@ public class DataNodeBuilder {
* @param normalizedNodeTree used for creating the Data Node
* @return this {@link DataNodeBuilder} object
*/
- public DataNodeBuilder withNormalizedNodeTree(final NormalizedNode<?, ?> normalizedNodeTree) {
+ public DataNodeBuilder withNormalizedNodeTree(final NormalizedNode normalizedNodeTree) {
this.normalizedNodeTree = normalizedNodeTree;
return this;
}
@@ -171,15 +171,16 @@ public class DataNodeBuilder {
}
private static void addDataNodeFromNormalizedNode(final DataNode currentDataNode,
- final NormalizedNode<?, ?> normalizedNode) {
+ final NormalizedNode normalizedNode) {
if (normalizedNode instanceof DataContainerNode) {
- addYangContainer(currentDataNode, (DataContainerNode<?>) normalizedNode);
+ addYangContainer(currentDataNode, (DataContainerNode) normalizedNode);
} else if (normalizedNode instanceof MapNode) {
addDataNodeForEachListElement(currentDataNode, (MapNode) normalizedNode);
} else if (normalizedNode instanceof ValueNode) {
- final ValueNode<?, ?> valuesNode = (ValueNode<?, ?>) normalizedNode;
- addYangLeaf(currentDataNode, valuesNode.getNodeType().getLocalName(), valuesNode.getValue());
+ final ValueNode<NormalizedNode> valuesNode = (ValueNode) normalizedNode;
+ addYangLeaf(currentDataNode, valuesNode.getIdentifier().getNodeType().getLocalName(),
+ valuesNode.body());
} else if (normalizedNode instanceof LeafSetNode) {
addYangLeafList(currentDataNode, (LeafSetNode<?>) normalizedNode);
} else {
@@ -187,13 +188,13 @@ public class DataNodeBuilder {
}
}
- private static void addYangContainer(final DataNode currentDataNode, final DataContainerNode<?> dataContainerNode) {
+ private static void addYangContainer(final DataNode currentDataNode, final DataContainerNode dataContainerNode) {
final DataNode dataContainerDataNode =
(dataContainerNode.getIdentifier() instanceof YangInstanceIdentifier.AugmentationIdentifier)
? currentDataNode
: createAndAddChildDataNode(currentDataNode, YangUtils.buildXpath(dataContainerNode.getIdentifier()));
- final Collection<DataContainerChild<?, ?>> normalizedChildNodes = dataContainerNode.getValue();
- for (final NormalizedNode<?, ?> normalizedNode : normalizedChildNodes) {
+ final Collection<DataContainerChild> normalizedChildNodes = dataContainerNode.body();
+ for (final NormalizedNode normalizedNode : normalizedChildNodes) {
addDataNodeFromNormalizedNode(dataContainerDataNode, normalizedNode);
}
}
@@ -207,16 +208,16 @@ public class DataNodeBuilder {
}
private static void addYangLeafList(final DataNode currentDataNode, final LeafSetNode<?> leafSetNode) {
- final String leafListName = leafSetNode.getNodeType().getLocalName();
- final List<?> leafListValues = ((Collection<? extends NormalizedNode<?, ?>>) leafSetNode.getValue())
- .stream()
- .map(normalizedNode -> ((ValueNode<?, ?>) normalizedNode).getValue())
- .collect(Collectors.toUnmodifiableList());
+ final String leafListName = leafSetNode.getIdentifier().getNodeType().getLocalName();
+ final List<?> leafListValues = ((Collection<? extends NormalizedNode>) leafSetNode.body())
+ .stream()
+ .map(normalizedNode -> (normalizedNode).body())
+ .collect(Collectors.toUnmodifiableList());
addYangLeaf(currentDataNode, leafListName, leafListValues);
}
private static void addDataNodeForEachListElement(final DataNode currentDataNode, final MapNode mapNode) {
- final Collection<MapEntryNode> mapEntryNodes = mapNode.getValue();
+ final Collection<MapEntryNode> mapEntryNodes = mapNode.body();
for (final MapEntryNode mapEntryNode : mapEntryNodes) {
addDataNodeFromNormalizedNode(currentDataNode, mapEntryNode);
}
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 8fcdc4ebdb..48241ed392 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
@@ -26,6 +26,7 @@ import com.google.gson.JsonSyntaxException;
import com.google.gson.stream.JsonReader;
import java.io.IOException;
import java.io.StringReader;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
@@ -36,8 +37,11 @@ import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.onap.cps.spi.exceptions.DataValidationException;
+import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
+import org.opendaylight.yangtools.yang.data.codec.gson.JSONCodecFactory;
import org.opendaylight.yangtools.yang.data.codec.gson.JSONCodecFactorySupplier;
import org.opendaylight.yangtools.yang.data.codec.gson.JsonParserStream;
import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNormalizedNodeStreamWriter;
@@ -45,7 +49,10 @@ import org.opendaylight.yangtools.yang.data.impl.schema.NormalizedNodeResult;
import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
+import org.opendaylight.yangtools.yang.model.api.EffectiveStatementInference;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier;
+import org.opendaylight.yangtools.yang.model.util.SchemaInferenceStack;
@Slf4j
@NoArgsConstructor(access = AccessLevel.PRIVATE)
@@ -61,8 +68,7 @@ public class YangUtils {
* @param schemaContext schema context describing associated data model
* @return the NormalizedNode object
*/
- @SuppressWarnings("squid:S1452") // Generic type <? ,?> is returned by external librray, opendaylight.yangtools
- public static NormalizedNode<?, ?> parseJsonData(final String jsonData, final SchemaContext schemaContext) {
+ public static NormalizedNode parseJsonData(final String jsonData, final SchemaContext schemaContext) {
return parseJsonData(jsonData, schemaContext, Optional.empty());
}
@@ -74,32 +80,41 @@ public class YangUtils {
* @param parentNodeXpath the xpath referencing the parent node current data fragment belong to
* @return the NormalizedNode object
*/
- @SuppressWarnings("squid:S1452") // Generic type <? ,?> is returned by external librray, opendaylight.yangtools
- public static NormalizedNode<?, ?> parseJsonData(final String jsonData, final SchemaContext schemaContext,
+ public static NormalizedNode parseJsonData(final String jsonData, final SchemaContext schemaContext,
final String parentNodeXpath) {
- final var parentSchemaNode = getDataSchemaNodeByXpath(parentNodeXpath, schemaContext);
- return parseJsonData(jsonData, schemaContext, Optional.of(parentSchemaNode));
+ final Collection<QName> dataSchemaNodeIdentifiers =
+ getDataSchemaNodeIdentifiersByXpath(parentNodeXpath, schemaContext);
+ return parseJsonData(jsonData, schemaContext, Optional.of(dataSchemaNodeIdentifiers));
}
- private static NormalizedNode<?, ?> parseJsonData(final String jsonData, final SchemaContext schemaContext,
- final Optional<DataSchemaNode> optionalParentSchemaNode) {
- final var jsonCodecFactory = JSONCodecFactorySupplier.DRAFT_LHOTKA_NETMOD_YANG_JSON_02
+ private static NormalizedNode parseJsonData(final String jsonData, final SchemaContext schemaContext,
+ final Optional<Collection<QName>> dataSchemaNodeIdentifiers) {
+ final JSONCodecFactory jsonCodecFactory = JSONCodecFactorySupplier.DRAFT_LHOTKA_NETMOD_YANG_JSON_02
.getShared((EffectiveModelContext) schemaContext);
- final var normalizedNodeResult = new NormalizedNodeResult();
- final var normalizedNodeStreamWriter = ImmutableNormalizedNodeStreamWriter
+ final NormalizedNodeResult normalizedNodeResult = new NormalizedNodeResult();
+ final NormalizedNodeStreamWriter normalizedNodeStreamWriter = ImmutableNormalizedNodeStreamWriter
.from(normalizedNodeResult);
+ final JsonReader jsonReader = new JsonReader(new StringReader(jsonData));
+ final JsonParserStream jsonParserStream;
+
+ if (dataSchemaNodeIdentifiers.isPresent()) {
+ final EffectiveModelContext effectiveModelContext = ((EffectiveModelContext) schemaContext);
+ final EffectiveStatementInference effectiveStatementInference =
+ SchemaInferenceStack.of(effectiveModelContext,
+ SchemaNodeIdentifier.Absolute.of(dataSchemaNodeIdentifiers.get())).toInference();
+ jsonParserStream =
+ JsonParserStream.create(normalizedNodeStreamWriter, jsonCodecFactory, effectiveStatementInference);
+ } else {
+ jsonParserStream = JsonParserStream.create(normalizedNodeStreamWriter, jsonCodecFactory);
+ }
- try (final JsonParserStream jsonParserStream = optionalParentSchemaNode.isPresent()
- ? JsonParserStream.create(normalizedNodeStreamWriter, jsonCodecFactory, optionalParentSchemaNode.get())
- : JsonParserStream.create(normalizedNodeStreamWriter, jsonCodecFactory)
- ) {
- final var jsonReader = new JsonReader(new StringReader(jsonData));
+ try {
jsonParserStream.parse(jsonReader);
-
- } catch (final IOException | JsonSyntaxException exception) {
+ jsonParserStream.close();
+ } catch (final JsonSyntaxException exception) {
throw new DataValidationException(
"Failed to parse json data: " + jsonData, exception.getMessage(), exception);
- } catch (final IllegalStateException illegalStateException) {
+ } catch (final IOException | IllegalStateException illegalStateException) {
throw new DataValidationException(
"Failed to parse json data. Unsupported xpath or json data:" + jsonData, illegalStateException
.getMessage(), illegalStateException);
@@ -114,7 +129,7 @@ public class YangUtils {
* @return an xpath
*/
public static String buildXpath(final YangInstanceIdentifier.PathArgument nodeIdentifier) {
- final var xpathBuilder = new StringBuilder();
+ final StringBuilder xpathBuilder = new StringBuilder();
xpathBuilder.append("/").append(nodeIdentifier.getNodeType().getLocalName());
if (nodeIdentifier instanceof YangInstanceIdentifier.NodeIdentifierWithPredicates) {
@@ -143,10 +158,11 @@ public class YangUtils {
}
}
- private static DataSchemaNode getDataSchemaNodeByXpath(final String parentNodeXpath,
- final SchemaContext schemaContext) {
+ private static Collection<QName> getDataSchemaNodeIdentifiersByXpath(final String parentNodeXpath,
+ final SchemaContext schemaContext) {
final String[] xpathNodeIdSequence = xpathToNodeIdSequence(parentNodeXpath);
- return findDataSchemaNodeByXpathNodeIdSequence(xpathNodeIdSequence, schemaContext.getChildNodes());
+ return findDataSchemaNodeIdentifiersByXpathNodeIdSequence(xpathNodeIdSequence, schemaContext.getChildNodes(),
+ new ArrayList<>());
}
private static String[] xpathToNodeIdSequence(final String xpath) {
@@ -161,25 +177,29 @@ public class YangUtils {
return xpathNodeIdSequence;
}
- private static DataSchemaNode findDataSchemaNodeByXpathNodeIdSequence(final String[] xpathNodeIdSequence,
- final Collection<? extends DataSchemaNode> dataSchemaNodes) {
+ private static Collection<QName> findDataSchemaNodeIdentifiersByXpathNodeIdSequence(
+ final String[] xpathNodeIdSequence,
+ final Collection<? extends DataSchemaNode> dataSchemaNodes,
+ final Collection<QName> dataSchemaNodeIdentifiers) {
final String currentXpathNodeId = xpathNodeIdSequence[0];
final DataSchemaNode currentDataSchemaNode = dataSchemaNodes.stream()
.filter(dataSchemaNode -> currentXpathNodeId.equals(dataSchemaNode.getQName().getLocalName()))
.findFirst().orElseThrow(() -> schemaNodeNotFoundException(currentXpathNodeId));
+ dataSchemaNodeIdentifiers.add(currentDataSchemaNode.getQName());
if (xpathNodeIdSequence.length <= 1) {
- return currentDataSchemaNode;
+ return dataSchemaNodeIdentifiers;
}
if (currentDataSchemaNode instanceof DataNodeContainer) {
- return findDataSchemaNodeByXpathNodeIdSequence(
+ return findDataSchemaNodeIdentifiersByXpathNodeIdSequence(
getNextLevelXpathNodeIdSequence(xpathNodeIdSequence),
- ((DataNodeContainer) currentDataSchemaNode).getChildNodes());
+ ((DataNodeContainer) currentDataSchemaNode).getChildNodes(),
+ dataSchemaNodeIdentifiers);
}
throw schemaNodeNotFoundException(xpathNodeIdSequence[1]);
}
private static String[] getNextLevelXpathNodeIdSequence(final String[] xpathNodeIdSequence) {
- final var nextXpathNodeIdSequence = new String[xpathNodeIdSequence.length - 1];
+ final String[] nextXpathNodeIdSequence = new String[xpathNodeIdSequence.length - 1];
System.arraycopy(xpathNodeIdSequence, 1, nextXpathNodeIdSequence, 0, nextXpathNodeIdSequence.length);
return nextXpathNodeIdSequence;
}
diff --git a/cps-service/src/main/java/org/onap/cps/yang/YangTextSchemaSourceSetBuilder.java b/cps-service/src/main/java/org/onap/cps/yang/YangTextSchemaSourceSetBuilder.java
index fd534971a1..e0f24f3158 100644
--- a/cps-service/src/main/java/org/onap/cps/yang/YangTextSchemaSourceSetBuilder.java
+++ b/cps-service/src/main/java/org/onap/cps/yang/YangTextSchemaSourceSetBuilder.java
@@ -32,6 +32,7 @@ import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.List;
import java.util.Map;
+import java.util.Optional;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import lombok.NoArgsConstructor;
@@ -41,9 +42,9 @@ import org.onap.cps.spi.model.ModuleReference;
import org.opendaylight.yangtools.yang.common.Revision;
import org.opendaylight.yangtools.yang.model.api.Module;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.opendaylight.yangtools.yang.model.parser.api.YangSyntaxErrorException;
import org.opendaylight.yangtools.yang.model.repo.api.RevisionSourceIdentifier;
import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource;
+import org.opendaylight.yangtools.yang.parser.api.YangSyntaxErrorException;
import org.opendaylight.yangtools.yang.parser.rfc7950.reactor.RFC7950Reactors;
import org.opendaylight.yangtools.yang.parser.rfc7950.repo.YangStatementStreamSource;
import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException;
@@ -155,6 +156,11 @@ public final class YangTextSchemaSourceSetBuilder {
return new YangTextSchemaSource(revisionSourceIdentifier) {
@Override
+ public Optional<String> getSymbolicName() {
+ return Optional.empty();
+ }
+
+ @Override
protected MoreObjects.ToStringHelper addToStringAttributes(
final MoreObjects.ToStringHelper toStringHelper) {
return toStringHelper;
diff --git a/cps-service/src/test/groovy/org/onap/cps/utils/JsonParserStreamSpec.groovy b/cps-service/src/test/groovy/org/onap/cps/utils/JsonParserStreamSpec.groovy
index 68f9251eb9..40f0e0a2ae 100644
--- a/cps-service/src/test/groovy/org/onap/cps/utils/JsonParserStreamSpec.groovy
+++ b/cps-service/src/test/groovy/org/onap/cps/utils/JsonParserStreamSpec.groovy
@@ -10,7 +10,7 @@ import org.opendaylight.yangtools.yang.data.codec.gson.JSONCodecFactorySupplier
import org.opendaylight.yangtools.yang.data.codec.gson.JsonParserStream
import org.opendaylight.yangtools.yang.data.impl.schema.Builders
import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNormalizedNodeStreamWriter
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeBuilder
+import org.opendaylight.yangtools.yang.data.api.schema.builder.DataContainerNodeBuilder
import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
import spock.lang.Specification
import org.onap.cps.TestUtils
@@ -38,10 +38,10 @@ class JsonParserStreamSpec extends Specification{
then: 'result is the correct size'
result.size() == 2
then: 'data container child is a type of normalized node'
- def dataContainerChild = result.getValue()[index]
+ def dataContainerChild = result.body().getAt(index)
dataContainerChild instanceof NormalizedNode == true
then: 'qualified name created is as expected'
- dataContainerChild.nodeType == QName.create('org:onap:ccsdk:multiDataTree', '2020-09-15', nodeName)
+ dataContainerChild.identifier.nodeType == QName.create('org:onap:ccsdk:multiDataTree', '2020-09-15', nodeName)
where:
index | nodeName
0 | 'first-container'
diff --git a/cps-service/src/test/groovy/org/onap/cps/utils/YangUtilsSpec.groovy b/cps-service/src/test/groovy/org/onap/cps/utils/YangUtilsSpec.groovy
index 3f190910b1..65aa3af7d8 100644
--- a/cps-service/src/test/groovy/org/onap/cps/utils/YangUtilsSpec.groovy
+++ b/cps-service/src/test/groovy/org/onap/cps/utils/YangUtilsSpec.groovy
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2020 Nordix Foundation
+ * Copyright (C) 2020-2022 Nordix Foundation
* Modifications Copyright (C) 2021 Pantheon.tech
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -36,9 +36,9 @@ class YangUtilsSpec extends Specification {
def yangResourceNameToContent = TestUtils.getYangResourcesAsMap('bookstore.yang')
def schemaContext = YangTextSchemaSourceSetBuilder.of(yangResourceNameToContent).getSchemaContext()
when: 'the json data is parsed'
- NormalizedNode<?, ?> result = YangUtils.parseJsonData(jsonData, schemaContext)
+ NormalizedNode result = YangUtils.parseJsonData(jsonData, schemaContext)
then: 'the result is a normalized node of the correct type'
- result.nodeType == QName.create('org:onap:ccsdk:sample', '2020-09-15', 'bookstore')
+ result.getIdentifier().nodeType == QName.create('org:onap:ccsdk:sample', '2020-09-15', 'bookstore')
}
def 'Parsing invalid data: #description.'() {
@@ -63,7 +63,7 @@ class YangUtilsSpec extends Specification {
when: 'json string is parsed'
def result = YangUtils.parseJsonData(jsonData, schemaContext, parentNodeXpath)
then: 'result represents a node of expected type'
- result.nodeType == QName.create('org:onap:cps:test:test-tree', '2020-02-02', nodeName)
+ result.getIdentifier().nodeType == QName.create('org:onap:cps:test:test-tree', '2020-02-02', nodeName)
where:
scenario | jsonData | parentNodeXpath || nodeName
'list element as container' | '{ "branch": { "name": "B", "nest": { "name": "N", "birds": ["bird"] } } }' | '/test-tree' || 'branch'
diff --git a/csit/prepare-csit.sh b/csit/prepare-csit.sh
index b56c3855dd..67412f3cf3 100755
--- a/csit/prepare-csit.sh
+++ b/csit/prepare-csit.sh
@@ -20,6 +20,8 @@
# Branched from ccsdk/distribution to this repository Feb 23, 2021
#
+echo "---> prepare-csit.sh"
+
if [ -z "$WORKSPACE" ]; then
export WORKSPACE=`git rev-parse --show-toplevel`
fi
@@ -35,11 +37,12 @@ if [ -f ${WORKSPACE}/env.properties ]; then
fi
if [ -f ${ROBOT3_VENV}/bin/activate ]; then
source ${ROBOT3_VENV}/bin/activate
-#else
-# rm -rf /tmp/ci-management
-# rm -f ${WORKSPACE}/env.properties
-# cd /tmp
-# source ${WORKSPACE}/install-robotframework.sh
+else
+ rm -rf /tmp/ci-management
+ rm -f ${WORKSPACE}/env.properties
+ cd /tmp
+ git clone "https://gerrit.onap.org/r/ci-management"
+ source /tmp/ci-management/jjb/integration/include-raw-integration-install-robotframework-py3.sh
fi
# install eteutils
diff --git a/csit/pylibs.txt b/csit/pylibs.txt
index d6250dbab5..4952616540 100644
--- a/csit/pylibs.txt
+++ b/csit/pylibs.txt
@@ -5,7 +5,7 @@ netifaces
pyhocon
requests
robotframework-httplibrary
-robotframework-requests
+robotframework-requests==0.9.3
robotframework-selenium2library
robotframework-extendedselenium2library
robotframework-sshlibrary
diff --git a/csit/run-csit.sh b/csit/run-csit.sh
index 25f5f6a77a..6703160a37 100755
--- a/csit/run-csit.sh
+++ b/csit/run-csit.sh
@@ -26,6 +26,8 @@ WORKDIR=$(mktemp -d --suffix=-robot-workdir)
# functions
#
+echo "---> run-csit.sh"
+
# wrapper for sourcing a file
function source_safely() {
[ -z "$1" ] && return 1