From 17aab0023e514cfe99b70ea161b271c9e42c5667 Mon Sep 17 00:00:00 2001 From: sourabh_sourabh Date: Tue, 15 Aug 2023 12:15:33 +0100 Subject: CPS-Core : Expose a java interface to update schema set - Exposed an interface to update anchor by schema set name. - New interface is implemented into RI model. - New native query is exposed to update id with given schema set name. - A new integration test is written to test new interface into cps core. Issue-ID: CPS-1800 Signed-off-by: sourabh_sourabh Change-Id: Ibf44712e11b53cb6673b04b9e3fd864321c90839 Signed-off-by: sourabh_sourabh --- .../spi/impl/CpsAdminPersistenceServiceImpl.java | 12 ++++++++ .../onap/cps/spi/repository/AnchorRepository.java | 4 +++ .../java/org/onap/cps/api/CpsAdminService.java | 9 ++++++ .../org/onap/cps/api/impl/CpsAdminServiceImpl.java | 7 +++++ .../onap/cps/spi/CpsAdminPersistenceService.java | 9 ++++++ .../cps/api/impl/CpsAdminServiceImplSpec.groovy | 7 +++++ .../integration/base/CpsIntegrationSpecBase.groovy | 2 +- .../CpsAdminServiceIntegrationSpec.groovy | 34 +++++++++++++++++++--- .../test/resources/data/tree/new-test-tree.json | 12 ++++++++ .../test/resources/data/tree/new-test-tree.yang | 21 +++++++++++++ .../resources/data/tree/updated-test-tree.json | 10 +++++++ .../resources/data/tree/updated-test-tree.yang | 33 +++++++++++++++++++++ 12 files changed, 155 insertions(+), 5 deletions(-) create mode 100644 integration-test/src/test/resources/data/tree/new-test-tree.json create mode 100644 integration-test/src/test/resources/data/tree/new-test-tree.yang create mode 100644 integration-test/src/test/resources/data/tree/updated-test-tree.json create mode 100644 integration-test/src/test/resources/data/tree/updated-test-tree.yang diff --git a/cps-ri/src/main/java/org/onap/cps/spi/impl/CpsAdminPersistenceServiceImpl.java b/cps-ri/src/main/java/org/onap/cps/spi/impl/CpsAdminPersistenceServiceImpl.java index 6f9f5a482..847a4a32f 100755 --- a/cps-ri/src/main/java/org/onap/cps/spi/impl/CpsAdminPersistenceServiceImpl.java +++ b/cps-ri/src/main/java/org/onap/cps/spi/impl/CpsAdminPersistenceServiceImpl.java @@ -171,6 +171,18 @@ public class CpsAdminPersistenceServiceImpl implements CpsAdminPersistenceServic anchorRepository.deleteAllByDataspaceAndNameIn(dataspaceEntity, anchorNames); } + @Transactional + @Override + public void updateAnchorSchemaSet(final String dataspaceName, + final String anchorName, + final String schemaSetName) { + final DataspaceEntity dataspaceEntity = dataspaceRepository.getByName(dataspaceName); + final AnchorEntity anchorEntity = anchorRepository.getByDataspaceAndName(dataspaceEntity, anchorName); + final SchemaSetEntity schemaSetEntity = schemaSetRepository + .getByDataspaceAndName(dataspaceEntity, schemaSetName); + anchorRepository.updateAnchorSchemaSetId(schemaSetEntity.getId(), anchorEntity.getId()); + } + private AnchorEntity getAnchorEntity(final String dataspaceName, final String anchorName) { final var dataspaceEntity = dataspaceRepository.getByName(dataspaceName); return anchorRepository.getByDataspaceAndName(dataspaceEntity, anchorName); diff --git a/cps-ri/src/main/java/org/onap/cps/spi/repository/AnchorRepository.java b/cps-ri/src/main/java/org/onap/cps/spi/repository/AnchorRepository.java index 5bb585781..b8503a7fe 100755 --- a/cps-ri/src/main/java/org/onap/cps/spi/repository/AnchorRepository.java +++ b/cps-ri/src/main/java/org/onap/cps/spi/repository/AnchorRepository.java @@ -99,4 +99,8 @@ public interface AnchorRepository extends JpaRepository { deleteAllByDataspaceIdAndNameIn(dataspaceEntity.getId(), anchorNames.toArray(new String[0])); } + @Modifying + @Query(value = "UPDATE anchor SET schema_set_id =:schemaSetId WHERE id = :anchorId ", nativeQuery = true) + void updateAnchorSchemaSetId(@Param("schemaSetId") int schemaSetId, @Param("anchorId") long anchorId); + } diff --git a/cps-service/src/main/java/org/onap/cps/api/CpsAdminService.java b/cps-service/src/main/java/org/onap/cps/api/CpsAdminService.java index fcf3f54cc..edd052a51 100755 --- a/cps-service/src/main/java/org/onap/cps/api/CpsAdminService.java +++ b/cps-service/src/main/java/org/onap/cps/api/CpsAdminService.java @@ -135,4 +135,13 @@ public interface CpsAdminService { * given module names */ Collection queryAnchorNames(String dataspaceName, Collection moduleNames); + + /** + * Update schema set of an anchor. + * + * @param dataspaceName dataspace name + * @param anchorName anchor name + * @param schemaSetName schema set name + */ + void updateAnchorSchemaSet(String dataspaceName, String anchorName, String schemaSetName); } diff --git a/cps-service/src/main/java/org/onap/cps/api/impl/CpsAdminServiceImpl.java b/cps-service/src/main/java/org/onap/cps/api/impl/CpsAdminServiceImpl.java index e286eea17..d83ee434d 100755 --- a/cps-service/src/main/java/org/onap/cps/api/impl/CpsAdminServiceImpl.java +++ b/cps-service/src/main/java/org/onap/cps/api/impl/CpsAdminServiceImpl.java @@ -120,4 +120,11 @@ public class CpsAdminServiceImpl implements CpsAdminService { final Collection anchors = cpsAdminPersistenceService.queryAnchors(dataspaceName, moduleNames); return anchors.stream().map(Anchor::getName).collect(Collectors.toList()); } + + @Override + public void updateAnchorSchemaSet(final String dataspaceName, + final String anchorName, + final String schemaSetName) { + cpsAdminPersistenceService.updateAnchorSchemaSet(dataspaceName, anchorName, schemaSetName); + } } diff --git a/cps-service/src/main/java/org/onap/cps/spi/CpsAdminPersistenceService.java b/cps-service/src/main/java/org/onap/cps/spi/CpsAdminPersistenceService.java index 1c1e80a20..5a1810f47 100755 --- a/cps-service/src/main/java/org/onap/cps/spi/CpsAdminPersistenceService.java +++ b/cps-service/src/main/java/org/onap/cps/spi/CpsAdminPersistenceService.java @@ -133,4 +133,13 @@ public interface CpsAdminPersistenceService { * @param anchorNames anchor names */ void deleteAnchors(String dataspaceName, Collection anchorNames); + + /** + * Delete anchors by name in given dataspace. + * + * @param dataspaceName dataspace name + * @param anchorName anchor name + * @param schemaSetName schema set name + */ + void updateAnchorSchemaSet(String dataspaceName, String anchorName, String schemaSetName); } diff --git a/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsAdminServiceImplSpec.groovy b/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsAdminServiceImplSpec.groovy index eb41e2085..12564fb6d 100755 --- a/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsAdminServiceImplSpec.groovy +++ b/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsAdminServiceImplSpec.groovy @@ -178,4 +178,11 @@ class CpsAdminServiceImplSpec extends Specification { and: 'the CpsValidator is called on the dataspaceName' 1 * mockCpsValidator.validateNameCharacters('someDataspace') } + + def 'Update anchor schema set.'() { + when: 'update anchor is invoked' + objectUnderTest.updateAnchorSchemaSet('someDataspace', 'someAnchor', 'someSchemaSetName') + then: 'associated persistence service method is invoked with correct parameter' + 1 * mockCpsAdminPersistenceService.updateAnchorSchemaSet('someDataspace', 'someAnchor', 'someSchemaSetName') + } } diff --git a/integration-test/src/test/groovy/org/onap/cps/integration/base/CpsIntegrationSpecBase.groovy b/integration-test/src/test/groovy/org/onap/cps/integration/base/CpsIntegrationSpecBase.groovy index 4780e3642..03ef9c2fd 100644 --- a/integration-test/src/test/groovy/org/onap/cps/integration/base/CpsIntegrationSpecBase.groovy +++ b/integration-test/src/test/groovy/org/onap/cps/integration/base/CpsIntegrationSpecBase.groovy @@ -108,7 +108,7 @@ class CpsIntegrationSpecBase extends Specification { def dataspaceExists(dataspaceName) { try { cpsAdminService.getDataspace(dataspaceName) - } catch (DataspaceNotFoundException e) { + } catch (DataspaceNotFoundException dataspaceNotFoundException) { return false } return true diff --git a/integration-test/src/test/groovy/org/onap/cps/integration/functional/CpsAdminServiceIntegrationSpec.groovy b/integration-test/src/test/groovy/org/onap/cps/integration/functional/CpsAdminServiceIntegrationSpec.groovy index 92fbdaaa2..bdd894c31 100644 --- a/integration-test/src/test/groovy/org/onap/cps/integration/functional/CpsAdminServiceIntegrationSpec.groovy +++ b/integration-test/src/test/groovy/org/onap/cps/integration/functional/CpsAdminServiceIntegrationSpec.groovy @@ -22,10 +22,12 @@ package org.onap.cps.integration.functional import org.onap.cps.api.CpsAdminService import org.onap.cps.integration.base.CpsIntegrationSpecBase +import org.onap.cps.spi.FetchDescendantsOption import org.onap.cps.spi.exceptions.AlreadyDefinedException import org.onap.cps.spi.exceptions.AnchorNotFoundException import org.onap.cps.spi.exceptions.DataspaceInUseException import org.onap.cps.spi.exceptions.DataspaceNotFoundException +import java.time.OffsetDateTime class CpsAdminServiceIntegrationSpec extends CpsIntegrationSpecBase { @@ -44,8 +46,8 @@ class CpsAdminServiceIntegrationSpec extends CpsIntegrationSpecBase { def thrown = null try { objectUnderTest.getDataspace('newDataspace') - } catch(Exception e) { - thrown = e + } catch(Exception exception) { + thrown = exception } assert thrown instanceof DataspaceNotFoundException } @@ -100,8 +102,8 @@ class CpsAdminServiceIntegrationSpec extends CpsIntegrationSpecBase { def thrown = null try { objectUnderTest.getAnchor(GENERAL_TEST_DATASPACE, 'newAnchor') - } catch(Exception e) { - thrown = e + } catch(Exception exception) { + thrown = exception } assert thrown instanceof AnchorNotFoundException } @@ -151,4 +153,28 @@ class CpsAdminServiceIntegrationSpec extends CpsIntegrationSpecBase { 'just unknown module(s)' | GENERAL_TEST_DATASPACE } + def 'Update anchor schema set.'() { + when: 'a new schema set with tree yang model is created' + def newTreeYangModelAsString = readResourceDataFile('tree/new-test-tree.yang') + cpsModuleService.createSchemaSet(GENERAL_TEST_DATASPACE, 'newTreeSchemaSet', [tree: newTreeYangModelAsString]) + then: 'an anchor with new schema set is created' + objectUnderTest.createAnchor(GENERAL_TEST_DATASPACE, 'newTreeSchemaSet', 'anchor4') + and: 'the new tree datanode is saved' + def treeJsonData = readResourceDataFile('tree/new-test-tree.json') + cpsDataService.saveData(GENERAL_TEST_DATASPACE, 'anchor4', treeJsonData, OffsetDateTime.now()) + and: 'saved tree data node can be retrieved by its normalized xpath' + def branchName = cpsDataService.getDataNodes(GENERAL_TEST_DATASPACE, 'anchor4', "/test-tree/branch", FetchDescendantsOption.DIRECT_CHILDREN_ONLY)[0].leaves['name'] + assert branchName == 'left' + and: 'a another schema set with updated tree yang model is created' + def updatedTreeYangModelAsString = readResourceDataFile('tree/updated-test-tree.yang') + cpsModuleService.createSchemaSet(GENERAL_TEST_DATASPACE, 'anotherTreeSchemaSet', [tree: updatedTreeYangModelAsString]) + and: 'anchor4 schema set is updated with another schema set successfully' + objectUnderTest.updateAnchorSchemaSet(GENERAL_TEST_DATASPACE, 'anchor4', 'anotherTreeSchemaSet') + when: 'updated tree data node with new leaves' + def updatedTreeJsonData = readResourceDataFile('tree/updated-test-tree.json') + cpsDataService.updateNodeLeaves(GENERAL_TEST_DATASPACE, "anchor4", "/test-tree/branch[@name='left']", updatedTreeJsonData, OffsetDateTime.now()) + then: 'updated tree data node can be retrieved by its normalized xpath' + def birdsName = cpsDataService.getDataNodes(GENERAL_TEST_DATASPACE, 'anchor4',"/test-tree/branch[@name='left']/nest", FetchDescendantsOption.DIRECT_CHILDREN_ONLY)[0].leaves['birds'] + assert birdsName as String == '[Raven, Night Owl, Crow]' + } } diff --git a/integration-test/src/test/resources/data/tree/new-test-tree.json b/integration-test/src/test/resources/data/tree/new-test-tree.json new file mode 100644 index 000000000..f7aefc472 --- /dev/null +++ b/integration-test/src/test/resources/data/tree/new-test-tree.json @@ -0,0 +1,12 @@ +{ + "test-tree": { + "branch": [ + { + "name": "left", + "nest": { + "name": "small" + } + } + ] + } +} \ No newline at end of file diff --git a/integration-test/src/test/resources/data/tree/new-test-tree.yang b/integration-test/src/test/resources/data/tree/new-test-tree.yang new file mode 100644 index 000000000..1a08b92f1 --- /dev/null +++ b/integration-test/src/test/resources/data/tree/new-test-tree.yang @@ -0,0 +1,21 @@ +module test-tree { + yang-version 1.1; + + namespace "org:onap:cps:test:test-tree"; + prefix tree; + revision "2020-02-02"; + + container test-tree { + list branch { + key "name"; + leaf name { + type string; + } + container nest { + leaf name { + type string; + } + } + } + } +} \ No newline at end of file diff --git a/integration-test/src/test/resources/data/tree/updated-test-tree.json b/integration-test/src/test/resources/data/tree/updated-test-tree.json new file mode 100644 index 000000000..2c2eea4f0 --- /dev/null +++ b/integration-test/src/test/resources/data/tree/updated-test-tree.json @@ -0,0 +1,10 @@ +{ + "nest": { + "name": "small", + "birds": [ + "Night Owl", + "Raven", + "Crow" + ] + } +} \ No newline at end of file diff --git a/integration-test/src/test/resources/data/tree/updated-test-tree.yang b/integration-test/src/test/resources/data/tree/updated-test-tree.yang new file mode 100644 index 000000000..bd883e8b6 --- /dev/null +++ b/integration-test/src/test/resources/data/tree/updated-test-tree.yang @@ -0,0 +1,33 @@ +module test-tree { + yang-version 1.1; + + namespace "org:onap:cps:test:test-tree"; + prefix tree; + + revision "2023-08-17" { + description + "added list of birds to nest"; + } + + revision "2020-09-15" { + description + "Sample Model"; + } + + container test-tree { + list branch { + key "name"; + leaf name { + type string; + } + container nest { + leaf name { + type string; + } + leaf-list birds { + type string; + } + } + } + } +} \ No newline at end of file -- cgit 1.2.3-korg