From 4c52e1a31c1424a954b2a1540117b4fbb443c578 Mon Sep 17 00:00:00 2001 From: shivasubedi Date: Thu, 12 Aug 2021 12:00:57 +0100 Subject: CPS-508: Create anchor/schemaset from new modules and existing modules Issue-ID: CPS-508 Signed-off-by: shivasubedi Change-Id: I8023a093334b77d0220f7c7d94de66863f5ba6dd --- .../spi/impl/CpsModulePersistenceServiceImpl.java | 17 ++++++++ .../SchemaSetYangResourceRepository.java | 29 ++++++++++++++ .../SchemaSetYangResourceRepositoryImpl.java | 45 ++++++++++++++++++++++ .../cps/spi/repository/YangResourceRepository.java | 7 +++- .../spi/impl/CpsAdminPersistenceServiceSpec.groovy | 1 + ...sModulePersistenceServiceIntegrationSpec.groovy | 32 +++++++++------ .../java/org/onap/cps/api/CpsModuleService.java | 12 ++++++ .../onap/cps/api/impl/CpsModuleServiceImpl.java | 9 +++++ .../onap/cps/spi/CpsAdminPersistenceService.java | 1 - .../onap/cps/spi/CpsModulePersistenceService.java | 12 ++++++ .../cps/api/impl/CpsModuleServiceImplSpec.groovy | 13 ++++++- 11 files changed, 164 insertions(+), 14 deletions(-) create mode 100644 cps-ri/src/main/java/org/onap/cps/spi/repository/SchemaSetYangResourceRepository.java create mode 100644 cps-ri/src/main/java/org/onap/cps/spi/repository/SchemaSetYangResourceRepositoryImpl.java 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 535cbe22ef..1c7828f32e 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 @@ -30,6 +30,7 @@ import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.nio.charset.StandardCharsets; +import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.List; @@ -143,6 +144,22 @@ public class CpsModulePersistenceServiceImpl implements CpsModulePersistenceServ } } + @Override + @Transactional + public void storeSchemaSetFromModules(final String dataspaceName, final String schemaSetName, + final Map newYangResourcesModuleNameToContentMap, + final List moduleReferenceList) { + storeSchemaSet(dataspaceName, schemaSetName, newYangResourcesModuleNameToContentMap); + final var dataspaceEntity = dataspaceRepository.getByName(dataspaceName); + final var schemaSetEntity = + schemaSetRepository.getByDataspaceAndName(dataspaceEntity, schemaSetName); + final List listOfYangResourceIds = new ArrayList<>(); + moduleReferenceList.forEach(moduleReference -> + listOfYangResourceIds.add(yangResourceRepository.getIdByModuleNameAndRevision( + moduleReference.getName(), moduleReference.getRevision()))); + yangResourceRepository.insertSchemaSetIdYangResourceId(schemaSetEntity.getId(), listOfYangResourceIds); + } + @Override @Transactional public void deleteSchemaSet(final String dataspaceName, final String schemaSetName, diff --git a/cps-ri/src/main/java/org/onap/cps/spi/repository/SchemaSetYangResourceRepository.java b/cps-ri/src/main/java/org/onap/cps/spi/repository/SchemaSetYangResourceRepository.java new file mode 100644 index 0000000000..0361749cdc --- /dev/null +++ b/cps-ri/src/main/java/org/onap/cps/spi/repository/SchemaSetYangResourceRepository.java @@ -0,0 +1,29 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 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========================================================= + */ + +package org.onap.cps.spi.repository; + +import java.util.List; + +public interface SchemaSetYangResourceRepository { + + void insertSchemaSetIdYangResourceId(final Integer schemaSetId, final List yangResourceId); + +} diff --git a/cps-ri/src/main/java/org/onap/cps/spi/repository/SchemaSetYangResourceRepositoryImpl.java b/cps-ri/src/main/java/org/onap/cps/spi/repository/SchemaSetYangResourceRepositoryImpl.java new file mode 100644 index 0000000000..04eaa453ef --- /dev/null +++ b/cps-ri/src/main/java/org/onap/cps/spi/repository/SchemaSetYangResourceRepositoryImpl.java @@ -0,0 +1,45 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 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========================================================= + */ + +package org.onap.cps.spi.repository; + +import java.util.List; +import javax.persistence.EntityManager; +import javax.persistence.PersistenceContext; +import org.springframework.transaction.annotation.Transactional; + +@Transactional +public class SchemaSetYangResourceRepositoryImpl implements SchemaSetYangResourceRepository { + + @PersistenceContext + private EntityManager entityManager; + + @Override + public void insertSchemaSetIdYangResourceId(final Integer schemaSetId, final List yangResourceId) { + final var query = "INSERT INTO SCHEMA_SET_YANG_RESOURCES (SCHEMA_SET_ID, YANG_RESOURCE_ID) " + + "VALUES ( :schemaSetId, :yangResourceId)"; + yangResourceId.forEach(id -> + entityManager.createNativeQuery(query) + .setParameter("schemaSetId", schemaSetId) + .setParameter("yangResourceId", id) + .executeUpdate() + ); + } +} diff --git a/cps-ri/src/main/java/org/onap/cps/spi/repository/YangResourceRepository.java b/cps-ri/src/main/java/org/onap/cps/spi/repository/YangResourceRepository.java index fe8787f93d..0b48eaaf63 100644 --- a/cps-ri/src/main/java/org/onap/cps/spi/repository/YangResourceRepository.java +++ b/cps-ri/src/main/java/org/onap/cps/spi/repository/YangResourceRepository.java @@ -28,16 +28,21 @@ import org.onap.cps.spi.entities.YangResourceModuleReference; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; @Repository -public interface YangResourceRepository extends JpaRepository { +public interface YangResourceRepository extends JpaRepository, + SchemaSetYangResourceRepository { List findAllByChecksumIn(@NotNull Set checksum); @Query(value = "SELECT module_name, revision FROM yang_resource", nativeQuery = true) List findAllModuleNameAndRevision(); + @Query(value = "SELECT id FROM yang_resource WHERE module_name=:name and revision=:revision", nativeQuery = true) + Long getIdByModuleNameAndRevision(@Param("name") String moduleName, @Param("revision") String revision); + @Modifying @Query(value = "DELETE FROM yang_resource yr WHERE NOT EXISTS " + "(SELECT 1 FROM schema_set_yang_resources ssyr WHERE ssyr.yang_resource_id = yr.id)", nativeQuery = true) diff --git a/cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsAdminPersistenceServiceSpec.groovy b/cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsAdminPersistenceServiceSpec.groovy index e41c71be7b..cff8d56321 100644 --- a/cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsAdminPersistenceServiceSpec.groovy +++ b/cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsAdminPersistenceServiceSpec.groovy @@ -35,6 +35,7 @@ class CpsAdminPersistenceServiceSpec extends CpsPersistenceSpecBase { @Autowired CpsAdminPersistenceService objectUnderTest + static final String SET_DATA = '/data/anchor.sql' static final String EMPTY_DATASPACE_NAME = 'DATASPACE-002' static final Integer DELETED_ANCHOR_ID = 3001 diff --git a/cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsModulePersistenceServiceIntegrationSpec.groovy b/cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsModulePersistenceServiceIntegrationSpec.groovy index f5d5fc6456..7a16a97d4b 100644 --- a/cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsModulePersistenceServiceIntegrationSpec.groovy +++ b/cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsModulePersistenceServiceIntegrationSpec.groovy @@ -56,7 +56,6 @@ class CpsModulePersistenceServiceIntegrationSpec extends CpsPersistenceSpecBase static final String SCHEMA_SET_NAME_WITH_ANCHORS_AND_DATA = 'SCHEMA-SET-101' static final String SCHEMA_SET_NAME_NEW = 'SCHEMA-SET-NEW' - static final Long NEW_RESOURCE_ABSTRACT_ID = 0L static final String NEW_RESOURCE_NAME = 'some new resource' static final String NEW_RESOURCE_CONTENT = 'module stores {\n' + ' yang-version 1.1;\n' + @@ -102,10 +101,27 @@ class CpsModulePersistenceServiceIntegrationSpec extends CpsPersistenceSpecBase when: 'a new schemaset is stored' objectUnderTest.storeSchemaSet(DATASPACE_NAME, SCHEMA_SET_NAME_NEW, newYangResourcesNameToContentMap) then: 'the schema set is persisted correctly' - assertSchemaSetPersisted(DATASPACE_NAME, SCHEMA_SET_NAME_NEW, NEW_RESOURCE_ABSTRACT_ID, NEW_RESOURCE_NAME, + assertSchemaSetPersisted(DATASPACE_NAME, SCHEMA_SET_NAME_NEW, NEW_RESOURCE_NAME, NEW_RESOURCE_CONTENT, NEW_RESOURCE_CHECKSUM, NEW_RESOURCE_MODULE_NAME, NEW_RESOURCE_REVISION) } + @Sql([CLEAR_DATA, SET_DATA]) + def 'Store and retrieve new schema set from new modules and existing modules.'() { + given: 'map of new modules, a list of existing modules, module reference' + def mapOfNewModules = [newModule1: 'module newmodule { yang-version 1.1; revision "2021-10-12" { } }'] + def moduleReferenceForExistingModule = new ModuleReference("test","test.org","2021-10-12") + def listOfExistingModulesModuleReference = [moduleReferenceForExistingModule] + def mapOfExistingModule = [test: 'module test { yang-version 1.1; revision "2021-10-12" { } }'] + objectUnderTest.storeSchemaSet(DATASPACE_NAME, "someSchemaSetName", mapOfExistingModule) + when: 'a new schema set is created from these new modules and existing modules' + objectUnderTest.storeSchemaSetFromModules(DATASPACE_NAME, "newSchemaSetName" , mapOfNewModules, listOfExistingModulesModuleReference) + then: 'the schema set can be retrieved' + def expectedYangResourcesMapAfterSchemaSetHasBeenCreated = mapOfNewModules + mapOfExistingModule + def actualYangResourcesMapAfterSchemaSetHasBeenCreated = + objectUnderTest.getYangSchemaResources(DATASPACE_NAME, "newSchemaSetName") + actualYangResourcesMapAfterSchemaSetHasBeenCreated == expectedYangResourcesMapAfterSchemaSetHasBeenCreated + } + @Sql([CLEAR_DATA, SET_DATA]) def 'Retrieving schema set (resources) by anchor.'() { given: 'a new schema set is stored' @@ -135,14 +151,13 @@ class CpsModulePersistenceServiceIntegrationSpec extends CpsPersistenceSpecBase def newYangResourcesNameToContentMap = [(NEW_RESOURCE_NAME):existingResourceContent] when: 'the schema set with duplicate resource is stored' objectUnderTest.storeSchemaSet(DATASPACE_NAME, SCHEMA_SET_NAME_NEW, newYangResourcesNameToContentMap) - then: 'the schema persisted (re)uses the existing id, name and has the same checksum' - def existingResourceId = 9L + then: 'the schema persisted (re)uses the existing name and has the same checksum' def existingResourceName = 'module1@2020-02-02.yang' def existingResourceChecksum = 'bea1afcc3d1517e7bf8cae151b3b6bfbd46db77a81754acdcb776a50368efa0a' def existingResourceModelName = 'test' def existingResourceRevision = '2020-09-15' - assertSchemaSetPersisted(DATASPACE_NAME, SCHEMA_SET_NAME_NEW, - existingResourceId, existingResourceName, existingResourceContent, existingResourceChecksum, + assertSchemaSetPersisted(DATASPACE_NAME, SCHEMA_SET_NAME_NEW, existingResourceName, + existingResourceContent, existingResourceChecksum, existingResourceModelName, existingResourceRevision) } @@ -195,7 +210,6 @@ class CpsModulePersistenceServiceIntegrationSpec extends CpsPersistenceSpecBase def assertSchemaSetPersisted(expectedDataspaceName, expectedSchemaSetName, - expectedYangResourceId, expectedYangResourceName, expectedYangResourceContent, expectedYangResourceChecksum, @@ -214,10 +228,6 @@ class CpsModulePersistenceServiceIntegrationSpec extends CpsPersistenceSpecBase // assert the attached yang resource content YangResourceEntity yangResourceEntity = yangResourceEntities.iterator().next() assert yangResourceEntity.id != null - if (expectedYangResourceId != NEW_RESOURCE_ABSTRACT_ID) { - // existing resource with known id - assert yangResourceEntity.id == expectedYangResourceId - } yangResourceEntity.name == expectedYangResourceName yangResourceEntity.content == expectedYangResourceContent yangResourceEntity.checksum == expectedYangResourceChecksum diff --git a/cps-service/src/main/java/org/onap/cps/api/CpsModuleService.java b/cps-service/src/main/java/org/onap/cps/api/CpsModuleService.java index fee4daa51a..d174085263 100644 --- a/cps-service/src/main/java/org/onap/cps/api/CpsModuleService.java +++ b/cps-service/src/main/java/org/onap/cps/api/CpsModuleService.java @@ -45,6 +45,18 @@ public interface CpsModuleService { void createSchemaSet(@NonNull String dataspaceName, @NonNull String schemaSetName, @NonNull Map yangResourcesNameToContentMap); + /** + * Create a schema set from new modules and existing modules. + * + * @param dataspaceName Dataspace name + * @param schemaSetName schema set name + * @param newYangResourcesModuleNameToContentMap YANG resources map where key is a module name and value is content + * @param moduleReferenceList List of YANG resources module references + */ + void createSchemaSetFromModules(@NonNull String dataspaceName, @NonNull String schemaSetName, + @NonNull Map newYangResourcesModuleNameToContentMap, + @NonNull List moduleReferenceList); + /** * Read schema set in the given dataspace. * diff --git a/cps-service/src/main/java/org/onap/cps/api/impl/CpsModuleServiceImpl.java b/cps-service/src/main/java/org/onap/cps/api/impl/CpsModuleServiceImpl.java index 34735f8482..c65f827816 100644 --- a/cps-service/src/main/java/org/onap/cps/api/impl/CpsModuleServiceImpl.java +++ b/cps-service/src/main/java/org/onap/cps/api/impl/CpsModuleServiceImpl.java @@ -50,6 +50,15 @@ public class CpsModuleServiceImpl implements CpsModuleService { yangTextSchemaSourceSetCache.updateCache(dataspaceName, schemaSetName, yangTextSchemaSourceSet); } + @Override + public void createSchemaSetFromModules(final String dataspaceName, final String schemaSetName, + final Map newYangResourcesModuleNameToContentMap, + final List moduleReferenceList) { + cpsModulePersistenceService.storeSchemaSetFromModules(dataspaceName, schemaSetName, + newYangResourcesModuleNameToContentMap, moduleReferenceList); + + } + @Override public SchemaSet getSchemaSet(final String dataspaceName, final String schemaSetName) { final var yangTextSchemaSourceSet = yangTextSchemaSourceSetCache 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 f71ff0b3be..b05385fbf4 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 @@ -49,7 +49,6 @@ public interface CpsAdminPersistenceService { */ void createAnchor(@NonNull String dataspaceName, @NonNull String schemaSetName, @NonNull String anchorName); - /** * Read all anchors in the given a dataspace. * diff --git a/cps-service/src/main/java/org/onap/cps/spi/CpsModulePersistenceService.java b/cps-service/src/main/java/org/onap/cps/spi/CpsModulePersistenceService.java index bc62a23c52..7ad109d815 100755 --- a/cps-service/src/main/java/org/onap/cps/spi/CpsModulePersistenceService.java +++ b/cps-service/src/main/java/org/onap/cps/spi/CpsModulePersistenceService.java @@ -42,6 +42,18 @@ public interface CpsModulePersistenceService { void storeSchemaSet(@NonNull String dataspaceName, @NonNull String schemaSetName, @NonNull Map yangResourcesNameToContentMap); + /** + * Stores a schema set from new modules and existing modules. + * + * @param dataspaceName Dataspace name + * @param schemaSetName Schema set name + * @param newYangResourcesModuleNameToContentMap YANG resources map where key is a module name and value is content + * @param moduleReferenceList List of YANG resources module references + */ + void storeSchemaSetFromModules(@NonNull String dataspaceName, @NonNull String schemaSetName, + @NonNull Map newYangResourcesModuleNameToContentMap, + @NonNull List moduleReferenceList); + /** * Deletes Schema Set. * diff --git a/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsModuleServiceImplSpec.groovy b/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsModuleServiceImplSpec.groovy index b8bfd4593e..d719b3d24e 100644 --- a/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsModuleServiceImplSpec.groovy +++ b/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsModuleServiceImplSpec.groovy @@ -52,7 +52,7 @@ class CpsModuleServiceImplSpec extends Specification { @Autowired CpsModuleServiceImpl objectUnderTest - def 'Create schema set'() { + def 'Create schema set.'() { given: 'Valid yang resource as name-to-content map' def yangResourcesNameToContentMap = TestUtils.getYangResourcesAsMap('bookstore.yang') when: 'Create schema set method is invoked' @@ -61,6 +61,17 @@ class CpsModuleServiceImplSpec extends Specification { 1 * mockModuleStoreService.storeSchemaSet('someDataspace', 'someSchemaSet', yangResourcesNameToContentMap) } + def 'Create schema set from new modules and existing modules.'() { + given: 'a list of existing modules module reference' + def moduleReferenceForExistingModule = new ModuleReference("test", "test.org", "2021-10-12") + def listOfExistingModulesModuleReference = [moduleReferenceForExistingModule] + when: 'create schema set from modules method is invoked' + objectUnderTest.createSchemaSetFromModules("someDataspaceName", "someSchemaSetName", [newModule: "newContent"], listOfExistingModulesModuleReference) + then: 'processing is delegated to persistence service' + 1 * mockModuleStoreService.storeSchemaSetFromModules("someDataspaceName", "someSchemaSetName", [newModule: "newContent"], listOfExistingModulesModuleReference) + + } + def 'Create schema set from invalid resources'() { given: 'Invalid yang resource as name-to-content map' def yangResourcesNameToContentMap = TestUtils.getYangResourcesAsMap('invalid.yang') -- cgit 1.2.3-korg