Merge "Fix SonarQube Violations"
authorSourabh Sourabh <sourabh.sourabh@est.tech>
Thu, 8 Dec 2022 10:55:49 +0000 (10:55 +0000)
committerGerrit Code Review <gerrit@onap.org>
Thu, 8 Dec 2022 10:55:49 +0000 (10:55 +0000)
15 files changed:
cps-dependencies/pom.xml
cps-parent/pom.xml
cps-ri/pom.xml
cps-ri/src/main/java/org/onap/cps/spi/impl/CpsModulePersistenceServiceImpl.java
cps-ri/src/test/groovy/org/onap/cps/spi/performance/CpsToDataNodePerfTest.groovy
cps-ri/src/test/resources/data/perf-test.sql [new file with mode: 0644]
cps-service/src/main/java/org/onap/cps/api/impl/CpsDataServiceImpl.java
cps-service/src/main/java/org/onap/cps/spi/model/DataNodeBuilder.java
cps-service/src/main/java/org/onap/cps/utils/YangUtils.java
cps-service/src/main/java/org/onap/cps/yang/YangTextSchemaSourceSetBuilder.java
cps-service/src/test/groovy/org/onap/cps/utils/JsonParserStreamSpec.groovy
cps-service/src/test/groovy/org/onap/cps/utils/YangUtilsSpec.groovy
csit/prepare-csit.sh
csit/pylibs.txt
csit/run-csit.sh

index e69e571..5bdf793 100755 (executable)
@@ -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>
index 0a8798a..d3fe0f3 100755 (executable)
@@ -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>
index 4ced335..b6fe284 100644 (file)
@@ -61,6 +61,7 @@
         <dependency>\r
             <groupId>org.postgresql</groupId>\r
             <artifactId>postgresql</artifactId>\r
+            <version>${postgres.version}</version>\r
         </dependency>\r
         <!-- Add Hibernate support for Postgres datatype JSONB -->\r
         <dependency>\r
index 400e9b3..8008e03 100755 (executable)
@@ -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;
@@ -251,6 +251,11 @@ public class CpsModulePersistenceServiceImpl implements CpsModulePersistenceServ
                 createIdentifierFromSourceName(checkNotNull(sourceName));
 
         final var tempYangTextSchemaSource = new YangTextSchemaSource(revisionSourceIdentifier) {
+            @Override
+            public Optional<String> getSymbolicName() {
+                return Optional.empty();
+            }
+
             @Override
             protected MoreObjects.ToStringHelper addToStringAttributes(
                     final MoreObjects.ToStringHelper toStringHelper) {
index a3e2e92..fb6749c 100644 (file)
@@ -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 (file)
index 0000000..5119f26
--- /dev/null
@@ -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');
+
index 88ebe3b..b08d8c1 100755 (executable)
@@ -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)
index f2bde03..eaa2d77 100644 (file)
@@ -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);
         }
index 8fcdc4e..48241ed 100644 (file)
@@ -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;
     }
index fd53497..e0f24f3 100644 (file)
@@ -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;
@@ -154,6 +155,11 @@ public final class YangTextSchemaSourceSetBuilder {
             createIdentifierFromSourceName(checkNotNull(sourceName));
 
         return new YangTextSchemaSource(revisionSourceIdentifier) {
+            @Override
+            public Optional<String> getSymbolicName() {
+                return Optional.empty();
+            }
+
             @Override
             protected MoreObjects.ToStringHelper addToStringAttributes(
                 final MoreObjects.ToStringHelper toStringHelper) {
index 68f9251..40f0e0a 100644 (file)
@@ -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'
index 3f19091..65aa3af 100644 (file)
@@ -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'
index b56c385..67412f3 100755 (executable)
@@ -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
index d6250db..4952616 100644 (file)
@@ -5,7 +5,7 @@ netifaces
 pyhocon
 requests
 robotframework-httplibrary
-robotframework-requests
+robotframework-requests==0.9.3
 robotframework-selenium2library
 robotframework-extendedselenium2library
 robotframework-sshlibrary
index 25f5f6a..6703160 100755 (executable)
@@ -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