diff options
Diffstat (limited to 'cps-ri')
11 files changed, 276 insertions, 55 deletions
diff --git a/cps-ri/pom.xml b/cps-ri/pom.xml index 8d860b0041..37d93156ae 100644 --- a/cps-ri/pom.xml +++ b/cps-ri/pom.xml @@ -26,7 +26,7 @@ <parent>
<groupId>org.onap.cps</groupId>
<artifactId>cps-parent</artifactId>
- <version>2.1.0-SNAPSHOT</version>
+ <version>3.0.0-SNAPSHOT</version>
<relativePath>../cps-parent/pom.xml</relativePath>
</parent>
diff --git a/cps-ri/src/main/java/org/onap/cps/spi/impl/CpsDataPersistenceServiceImpl.java b/cps-ri/src/main/java/org/onap/cps/spi/impl/CpsDataPersistenceServiceImpl.java index 04804726c9..f22d83b981 100644 --- a/cps-ri/src/main/java/org/onap/cps/spi/impl/CpsDataPersistenceServiceImpl.java +++ b/cps-ri/src/main/java/org/onap/cps/spi/impl/CpsDataPersistenceServiceImpl.java @@ -329,22 +329,34 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService } private void deleteDataNode(final String dataspaceName, final String anchorName, final String targetXpath, - final boolean onlySupportListNodeDeletion) { - final String parentNodeXpath = targetXpath.substring(0, targetXpath.lastIndexOf('/')); - final FragmentEntity parentFragmentEntity = getFragmentByXpath(dataspaceName, anchorName, parentNodeXpath); - final String lastXpathElement = targetXpath.substring(targetXpath.lastIndexOf('/')); - final boolean isListElement = REG_EX_PATTERN_FOR_LIST_ELEMENT_KEY_PREDICATE.matcher(lastXpathElement).find(); - boolean targetExist; - if (isListElement) { - targetExist = deleteDataNode(parentFragmentEntity, targetXpath); + final boolean onlySupportListNodeDeletion) { + final String parentNodeXpath; + FragmentEntity parentFragmentEntity = null; + boolean targetDeleted = false; + if (isRootXpath(targetXpath)) { + deleteDataNodes(dataspaceName, anchorName); + targetDeleted = true; } else { - targetExist = deleteAllListElements(parentFragmentEntity, targetXpath); - final boolean tryToDeleteDataNode = !targetExist && !onlySupportListNodeDeletion; - if (tryToDeleteDataNode) { - targetExist = deleteDataNode(parentFragmentEntity, targetXpath); + if (isContainerNodeXpath(targetXpath)) { + parentNodeXpath = targetXpath; + } else { + parentNodeXpath = targetXpath.substring(0, targetXpath.lastIndexOf('/')); + } + parentFragmentEntity = getFragmentByXpath(dataspaceName, anchorName, parentNodeXpath); + final String lastXpathElement = targetXpath.substring(targetXpath.lastIndexOf('/')); + final boolean isListElement = REG_EX_PATTERN_FOR_LIST_ELEMENT_KEY_PREDICATE + .matcher(lastXpathElement).find(); + if (isListElement) { + targetDeleted = deleteDataNode(parentFragmentEntity, targetXpath); + } else { + targetDeleted = deleteAllListElements(parentFragmentEntity, targetXpath); + final boolean tryToDeleteDataNode = !targetDeleted && !onlySupportListNodeDeletion; + if (tryToDeleteDataNode) { + targetDeleted = deleteDataNode(parentFragmentEntity, targetXpath); + } } } - if (!targetExist) { + if (!targetDeleted) { final String additionalInformation = onlySupportListNodeDeletion ? "The target is probably not a List." : ""; throw new DataNodeNotFoundException(parentFragmentEntity.getDataspace().getName(), @@ -353,6 +365,10 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService } private boolean deleteDataNode(final FragmentEntity parentFragmentEntity, final String targetXpath) { + if (parentFragmentEntity.getXpath().equals(targetXpath)) { + fragmentRepository.delete(parentFragmentEntity); + return true; + } if (parentFragmentEntity.getChildFragments() .removeIf(fragment -> fragment.getXpath().equals(targetXpath))) { fragmentRepository.save(parentFragmentEntity); @@ -361,7 +377,6 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService return false; } - private boolean deleteAllListElements(final FragmentEntity parentFragmentEntity, final String listXpath) { final String deleteTargetXpathPrefix = listXpath + "["; if (parentFragmentEntity.getChildFragments() @@ -384,7 +399,7 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService "Cannot replace list elements with empty collection"); } final String firstChildNodeXpath = newListElements.iterator().next().getXpath(); - return firstChildNodeXpath.substring(0, firstChildNodeXpath.lastIndexOf("[") + 1); + return firstChildNodeXpath.substring(0, firstChildNodeXpath.lastIndexOf('[') + 1); } private FragmentEntity getFragmentForReplacement(final FragmentEntity parentEntity, @@ -408,6 +423,10 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService return !existingListElementsByXpath.containsKey(replacementDataNode.getXpath()); } + private static boolean isContainerNodeXpath(final String xpath) { + return 0 == xpath.lastIndexOf('/'); + } + private void copyAttributesFromNewListElement(final FragmentEntity existingListElementEntity, final DataNode newListElement) { final FragmentEntity replacementFragmentEntity = 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 86d5de6d0f..ec720b8a96 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 @@ -1,6 +1,6 @@ /* * ============LICENSE_START======================================================= - * Copyright (C) 2020 Nordix Foundation + * Copyright (C) 2020-2022 Nordix Foundation * Modifications Copyright (C) 2020-2022 Bell Canada. * Modifications Copyright (C) 2021 Pantheon.tech * ================================================================================ @@ -40,6 +40,7 @@ import java.util.Set; import java.util.regex.Pattern; import java.util.stream.Collectors; import javax.transaction.Transactional; +import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.codec.digest.DigestUtils; import org.apache.commons.lang3.StringUtils; @@ -53,9 +54,8 @@ import org.onap.cps.spi.exceptions.AlreadyDefinedException; import org.onap.cps.spi.exceptions.DuplicatedYangResourceException; import org.onap.cps.spi.exceptions.ModelValidationException; import org.onap.cps.spi.model.ModuleReference; -import org.onap.cps.spi.repository.AnchorRepository; import org.onap.cps.spi.repository.DataspaceRepository; -import org.onap.cps.spi.repository.FragmentRepository; +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; @@ -63,15 +63,14 @@ 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.rfc7950.repo.YangModelDependencyInfo; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.dao.DataIntegrityViolationException; import org.springframework.retry.annotation.Backoff; import org.springframework.retry.annotation.Retryable; import org.springframework.stereotype.Component; - -@Component @Slf4j +@Component +@AllArgsConstructor public class CpsModulePersistenceServiceImpl implements CpsModulePersistenceService { private static final String YANG_RESOURCE_CHECKSUM_CONSTRAINT_NAME = "yang_resource_checksum_key"; @@ -79,24 +78,16 @@ public class CpsModulePersistenceServiceImpl implements CpsModulePersistenceServ private static final Pattern RFC6020_RECOMMENDED_FILENAME_PATTERN = Pattern .compile("([\\w-]+)@(\\d{4}-\\d{2}-\\d{2})(?:\\.yang)?", Pattern.CASE_INSENSITIVE); - @Autowired private YangResourceRepository yangResourceRepository; - @Autowired private SchemaSetRepository schemaSetRepository; - @Autowired private DataspaceRepository dataspaceRepository; - @Autowired - private AnchorRepository anchorRepository; - - @Autowired - private FragmentRepository fragmentRepository; - - @Autowired private CpsAdminPersistenceService cpsAdminPersistenceService; + private ModuleReferenceRepository moduleReferenceRepository; + @Override public Map<String, String> getYangSchemaResources(final String dataspaceName, final String schemaSetName) { final var dataspaceEntity = dataspaceRepository.getByName(dataspaceName); @@ -137,9 +128,9 @@ public class CpsModulePersistenceServiceImpl implements CpsModulePersistenceServ @Retryable(value = DuplicatedYangResourceException.class, maxAttempts = 5, backoff = @Backoff(random = true, delay = 200, maxDelay = 2000, multiplier = 2)) public void storeSchemaSet(final String dataspaceName, final String schemaSetName, - final Map<String, String> yangResourcesNameToContentMap) { + final Map<String, String> moduleReferenceNameToContentMap) { final var dataspaceEntity = dataspaceRepository.getByName(dataspaceName); - final var yangResourceEntities = synchronizeYangResources(yangResourcesNameToContentMap); + final var yangResourceEntities = synchronizeYangResources(moduleReferenceNameToContentMap); final var schemaSetEntity = new SchemaSetEntity(); schemaSetEntity.setName(schemaSetName); schemaSetEntity.setDataspace(dataspaceEntity); @@ -158,9 +149,9 @@ public class CpsModulePersistenceServiceImpl implements CpsModulePersistenceServ @Retryable(value = DuplicatedYangResourceException.class, maxAttempts = 5, backoff = @Backoff(random = true, delay = 200, maxDelay = 2000, multiplier = 2)) public void storeSchemaSetFromModules(final String dataspaceName, final String schemaSetName, - final Map<String, String> newYangResourcesModuleNameToContentMap, - final List<ModuleReference> moduleReferences) { - storeSchemaSet(dataspaceName, schemaSetName, newYangResourcesModuleNameToContentMap); + final Map<String, String> newModuleNameToContentMap, + final Collection<ModuleReference> moduleReferences) { + storeSchemaSet(dataspaceName, schemaSetName, newModuleNameToContentMap); final var dataspaceEntity = dataspaceRepository.getByName(dataspaceName); final var schemaSetEntity = schemaSetRepository.getByDataspaceAndName(dataspaceEntity, schemaSetName); @@ -186,8 +177,15 @@ public class CpsModulePersistenceServiceImpl implements CpsModulePersistenceServ yangResourceRepository.deleteOrphans(); } - private Set<YangResourceEntity> synchronizeYangResources(final Map<String, String> yangResourcesNameToContentMap) { - final Map<String, YangResourceEntity> checksumToEntityMap = yangResourcesNameToContentMap.entrySet().stream() + @Override + public Collection<ModuleReference> identifyNewModuleReferences( + final Collection<ModuleReference> moduleReferencesToCheck) { + return moduleReferenceRepository.identifyNewModuleReferences(moduleReferencesToCheck); + } + + private Set<YangResourceEntity> synchronizeYangResources( + final Map<String, String> moduleReferenceNameToContentMap) { + final Map<String, YangResourceEntity> checksumToEntityMap = moduleReferenceNameToContentMap.entrySet().stream() .map(entry -> { final String checksum = DigestUtils.sha256Hex(entry.getValue().getBytes(StandardCharsets.UTF_8)); final Map<String, String> moduleNameAndRevisionMap = createModuleNameAndRevisionMap(entry.getKey(), diff --git a/cps-ri/src/main/java/org/onap/cps/spi/repository/ModuleReferenceQuery.java b/cps-ri/src/main/java/org/onap/cps/spi/repository/ModuleReferenceQuery.java new file mode 100644 index 0000000000..6551937e10 --- /dev/null +++ b/cps-ri/src/main/java/org/onap/cps/spi/repository/ModuleReferenceQuery.java @@ -0,0 +1,34 @@ +/*- + * ============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========================================================= + */ + +package org.onap.cps.spi.repository; + +import java.util.Collection; +import org.onap.cps.spi.model.ModuleReference; + +/** + * This interface is used in conjunction with {@link ModuleReferenceRepository} to create native sql queries. + */ +public interface ModuleReferenceQuery { + + Collection<ModuleReference> identifyNewModuleReferences( + final Collection<ModuleReference> moduleReferencesToCheck); + +} diff --git a/cps-ri/src/main/java/org/onap/cps/spi/repository/ModuleReferenceRepository.java b/cps-ri/src/main/java/org/onap/cps/spi/repository/ModuleReferenceRepository.java new file mode 100644 index 0000000000..ce2bfe7847 --- /dev/null +++ b/cps-ri/src/main/java/org/onap/cps/spi/repository/ModuleReferenceRepository.java @@ -0,0 +1,36 @@ +/* + * ============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========================================================= + */ + +package org.onap.cps.spi.repository; + +import java.util.Collection; +import org.onap.cps.spi.entities.YangResourceEntity; +import org.onap.cps.spi.model.ModuleReference; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface ModuleReferenceRepository extends + JpaRepository<YangResourceEntity, Long>, ModuleReferenceQuery { + + Collection<ModuleReference> identifyNewModuleReferences( + final Collection<ModuleReference> moduleReferencesToCheck); + +}
\ No newline at end of file diff --git a/cps-ri/src/main/java/org/onap/cps/spi/repository/ModuleReferenceRepositoryImpl.java b/cps-ri/src/main/java/org/onap/cps/spi/repository/ModuleReferenceRepositoryImpl.java new file mode 100644 index 0000000000..f4078ffec7 --- /dev/null +++ b/cps-ri/src/main/java/org/onap/cps/spi/repository/ModuleReferenceRepositoryImpl.java @@ -0,0 +1,107 @@ +/*- + * ============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========================================================= + */ + +package org.onap.cps.spi.repository; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.UUID; +import javax.persistence.EntityManager; +import javax.persistence.PersistenceContext; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; +import org.onap.cps.spi.model.ModuleReference; +import org.springframework.transaction.annotation.Transactional; + +@Slf4j +@Transactional +public class ModuleReferenceRepositoryImpl implements ModuleReferenceQuery { + + @PersistenceContext + private EntityManager entityManager; + + @Override + @SneakyThrows + public Collection<ModuleReference> identifyNewModuleReferences( + final Collection<ModuleReference> moduleReferencesToCheck) { + + if (moduleReferencesToCheck == null || moduleReferencesToCheck.isEmpty()) { + return Collections.EMPTY_LIST; + } + + final String tempTableName = "moduleReferencesToCheckTemp" + + UUID.randomUUID().toString().replaceAll("-", ""); + + createTemporaryTable(tempTableName); + insertDataIntoTable(tempTableName, moduleReferencesToCheck); + + return identifyNewModuleReferencesForCmHandle(tempTableName); + } + + private void createTemporaryTable(final String tempTableName) { + final StringBuilder sqlStringBuilder = new StringBuilder("CREATE TEMPORARY TABLE " + tempTableName + "("); + sqlStringBuilder.append(" id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,"); + sqlStringBuilder.append(" module_name varchar NOT NULL,"); + sqlStringBuilder.append(" revision varchar NOT NULL"); + sqlStringBuilder.append(");"); + + entityManager.createNativeQuery(sqlStringBuilder.toString()).executeUpdate(); + } + + private void insertDataIntoTable(final String tempTableName, final Collection<ModuleReference> moduleReferences) { + final StringBuilder sqlStringBuilder = new StringBuilder("INSERT INTO " + tempTableName); + sqlStringBuilder.append(" (module_name, revision) "); + sqlStringBuilder.append(" VALUES "); + + for (final ModuleReference moduleReference : moduleReferences) { + sqlStringBuilder.append("('"); + sqlStringBuilder.append(moduleReference.getModuleName()); + sqlStringBuilder.append("', '"); + sqlStringBuilder.append(moduleReference.getRevision()); + sqlStringBuilder.append("'),"); + } + + // replace last ',' with ';' + sqlStringBuilder.replace(sqlStringBuilder.length() - 1, sqlStringBuilder.length(), ";"); + + entityManager.createNativeQuery(sqlStringBuilder.toString()).executeUpdate(); + } + + private Collection<ModuleReference> identifyNewModuleReferencesForCmHandle(final String tempTableName) { + final String sql = String.format( + "SELECT %1$s.module_name, %1$s.revision" + + " FROM %1$s LEFT JOIN yang_resource" + + " ON yang_resource.module_name=%1$s.module_name" + + " AND yang_resource.revision=%1$s.revision" + + " WHERE yang_resource.module_name IS NULL;", tempTableName); + + final List<Object[]> resultsAsObjects = + entityManager.createNativeQuery(sql).getResultList(); + + final List<ModuleReference> resultsAsModuleReferences = new ArrayList<>(resultsAsObjects.size()); + for (final Object[] row : resultsAsObjects) { + resultsAsModuleReferences.add(new ModuleReference((String) row[0], (String) row[1])); + } + + return resultsAsModuleReferences; + } +} 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 3f5c43decc..895937b60a 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 @@ -1,7 +1,7 @@ /* * ============LICENSE_START======================================================= * Copyright (C) 2020 Pantheon.tech - * Modifications Copyright (C) Nordix Foundation + * Modifications Copyright (C) 2021-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. diff --git a/cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsDataPersistenceServiceIntegrationSpec.groovy b/cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsDataPersistenceServiceIntegrationSpec.groovy index 2277377a5c..ab290051a2 100755 --- a/cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsDataPersistenceServiceIntegrationSpec.groovy +++ b/cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsDataPersistenceServiceIntegrationSpec.groovy @@ -511,6 +511,11 @@ class CpsDataPersistenceServiceIntegrationSpec extends CpsPersistenceSpecBase { 'child data node, parent still exists' | '/parent-206/child-206' | '/parent-206' || '/parent-206' 'list element' | '/parent-206/child-206/grand-child-206[@key="A"]' | '/parent-206/child-206/grand-child-206[@key="A"]' || null 'list element, sibling still exists' | '/parent-206/child-206/grand-child-206[@key="A"]' | '/parent-206/child-206/grand-child-206[@key="X"]' || '/parent-206/child-206/grand-child-206[@key="X"]' + 'container node' | '/parent-206' | '/parent-206' || null + 'container list node' | '/parent-206[@key="A"]' | '/parent-206[@key="B"]' || '/parent-206[@key="B"]' + 'root node with xpath /' | '/' | '/' || null + 'root node with xpath passed as blank' | '' | '' || null + } @Sql([CLEAR_DATA, SET_DATA]) 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 75d6330265..1b37bef9c6 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 @@ -1,6 +1,6 @@ /* * ============LICENSE_START======================================================= - * Copyright (C) 2021 Nordix Foundation + * Copyright (C) 2021-2022 Nordix Foundation * Modifications Copyright (C) 2021-2022 Bell Canada. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the 'License'); @@ -25,18 +25,15 @@ import org.onap.cps.spi.CpsModulePersistenceService import org.onap.cps.spi.entities.YangResourceEntity import org.onap.cps.spi.exceptions.AlreadyDefinedException import org.onap.cps.spi.exceptions.DataspaceNotFoundException -import org.onap.cps.spi.exceptions.SchemaSetInUseException import org.onap.cps.spi.exceptions.SchemaSetNotFoundException import org.onap.cps.spi.model.ModuleReference import org.onap.cps.spi.model.ExtendedModuleReference import org.onap.cps.spi.repository.AnchorRepository +import org.onap.cps.spi.repository.ModuleReferenceRepository import org.onap.cps.spi.repository.SchemaSetRepository import org.springframework.beans.factory.annotation.Autowired import org.springframework.test.context.jdbc.Sql -import static org.onap.cps.spi.CascadeDeleteAllowed.CASCADE_DELETE_ALLOWED -import static org.onap.cps.spi.CascadeDeleteAllowed.CASCADE_DELETE_PROHIBITED - class CpsModulePersistenceServiceIntegrationSpec extends CpsPersistenceSpecBase { @Autowired @@ -54,7 +51,6 @@ class CpsModulePersistenceServiceIntegrationSpec extends CpsPersistenceSpecBase static final String SET_DATA = '/data/schemaset.sql' static final String EXISTING_SCHEMA_SET_NAME = SCHEMA_SET_NAME1 static final String SCHEMA_SET_NAME_NO_ANCHORS = 'SCHEMA-SET-100' - 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 String NEW_RESOURCE_NAME = 'some new resource' @@ -76,9 +72,7 @@ class CpsModulePersistenceServiceIntegrationSpec extends CpsPersistenceSpecBase .revision(NEW_RESOURCE_REVISION).build() def newYangResourcesNameToContentMap = [(NEW_RESOURCE_NAME):NEW_RESOURCE_CONTENT] - def allYangResourcesModuleAndRevisionList = [new ExtendedModuleReference(name: 'MODULE-NAME-002',namespace:null, revision: 'REVISION-002'), new ExtendedModuleReference(name: 'MODULE-NAME-003',namespace:null, revision: 'REVISION-003'), - new ExtendedModuleReference(name: 'MODULE-NAME-004',namespace:null, revision: 'REVISION-004'), ExtendedModuleReference.builder().build(), - ExtendedModuleReference.builder().build(), newModuleReference] + def dataspaceEntity def setup() { @@ -184,6 +178,19 @@ class CpsModulePersistenceServiceIntegrationSpec extends CpsPersistenceSpecBase } @Sql([CLEAR_DATA, SET_DATA]) + def 'Identifying new module references where #scenario'() { + when: 'identifyNewModuleReferences is called' + def result = objectUnderTest.identifyNewModuleReferences(moduleReferences) + then: 'the correct module reference collection is returned' + assert result == expectedResult + where: 'the following data is used' + scenario | moduleReferences || expectedResult + 'new module references exist' | toModuleReference([['some module 1' : 'some revision 1'], ['some module 2' : 'some revision 2']]) || toModuleReference([['some module 1' : 'some revision 1'], ['some module 2' : 'some revision 2']]) + 'no new module references exist' | [] || [] + 'module references collection is null'| null || [] + } + + @Sql([CLEAR_DATA, SET_DATA]) def 'Delete schema set error scenario: #scenario.'() { when: 'attempt to delete a schema set where #scenario' objectUnderTest.deleteSchemaSet(dataspaceName, schemaSetName) @@ -236,4 +243,13 @@ class CpsModulePersistenceServiceIntegrationSpec extends CpsPersistenceSpecBase yangResourceEntity.revision == expectedYangResourceRevision } + def toModuleReference(moduleReferenceAsMap) { + def moduleReferences = [].withDefault { [:] } + moduleReferenceAsMap.forEach(property -> + property.forEach((moduleName, revision) -> { + moduleReferences.add(new ModuleReference('moduleName' : moduleName, 'revision' : revision)) + })) + return moduleReferences + } + } diff --git a/cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsModulePersistenceServiceSpec.groovy b/cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsModulePersistenceServiceSpec.groovy index 8bd7f86ea2..9ef9732681 100644 --- a/cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsModulePersistenceServiceSpec.groovy +++ b/cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsModulePersistenceServiceSpec.groovy @@ -1,6 +1,7 @@ /* * ============LICENSE_START======================================================= * Copyright (c) 2021 Bell Canada. + * Modifications 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. @@ -19,9 +20,11 @@ package org.onap.cps.spi.impl import org.hibernate.exception.ConstraintViolationException +import org.onap.cps.spi.CpsAdminPersistenceService import org.onap.cps.spi.CpsModulePersistenceService import org.onap.cps.spi.exceptions.DuplicatedYangResourceException import org.onap.cps.spi.repository.DataspaceRepository +import org.onap.cps.spi.repository.ModuleReferenceRepository import org.onap.cps.spi.repository.SchemaSetRepository import org.onap.cps.spi.repository.YangResourceRepository import org.springframework.dao.DataIntegrityViolationException @@ -42,6 +45,8 @@ class CpsModulePersistenceServiceSpec extends Specification { def dataspaceRepositoryMock = Mock(DataspaceRepository) def yangResourceRepositoryMock = Mock(YangResourceRepository) def schemaSetRepositoryMock = Mock(SchemaSetRepository) + def cpsAdminPersistenceServiceMock = Mock(CpsAdminPersistenceService) + def moduleReferenceRepositoryMock = Mock(ModuleReferenceRepository) // Constants def yangResourceName = 'my-yang-resource-name' @@ -73,10 +78,8 @@ class CpsModulePersistenceServiceSpec extends Specification { anotherIntegrityException = new DataIntegrityViolationException("another integrity exception") def setup() { - objectUnderTest = new CpsModulePersistenceServiceImpl() - objectUnderTest.dataspaceRepository = dataspaceRepositoryMock - objectUnderTest.yangResourceRepository = yangResourceRepositoryMock - objectUnderTest.schemaSetRepository = schemaSetRepositoryMock + objectUnderTest = new CpsModulePersistenceServiceImpl(yangResourceRepositoryMock, schemaSetRepositoryMock, + dataspaceRepositoryMock, cpsAdminPersistenceServiceMock, moduleReferenceRepositoryMock) } def 'Store schema set error scenario: #scenario.'() { diff --git a/cps-ri/src/test/resources/data/fragment.sql b/cps-ri/src/test/resources/data/fragment.sql index 49c4c9f3ee..a27bb5fdea 100755 --- a/cps-ri/src/test/resources/data/fragment.sql +++ b/cps-ri/src/test/resources/data/fragment.sql @@ -2,7 +2,7 @@ ============LICENSE_START======================================================= Copyright (C) 2021 Nordix Foundation. Modifications Copyright (C) 2021 Pantheon.tech - Modifications Copyright (C) 2021 Bell Canada. + Modifications Copyright (C) 2021-2022 Bell Canada. ================================================================================ Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -64,4 +64,7 @@ INSERT INTO FRAGMENT (ID, DATASPACE_ID, ANCHOR_ID, PARENT_ID, XPATH, ATTRIBUTES) (4227, 1001, 3003, 4226, '/parent-206/child-206', '{}'), (4228, 1001, 3003, 4227, '/parent-206/child-206/grand-child-206', '{}'), (4229, 1001, 3003, 4227, '/parent-206/child-206/grand-child-206[@key="A"]', '{"key": "A"}'), - (4230, 1001, 3003, 4227, '/parent-206/child-206/grand-child-206[@key="X"]', '{"key": "X"}'); + (4230, 1001, 3003, 4227, '/parent-206/child-206/grand-child-206[@key="X"]', '{"key": "X"}'), + (4231, 1001, 3003, null, '/parent-206[@key="A"]', '{"key": "A"}'), + (4232, 1001, 3003, 4231, '/parent-206[@key="A"]/child-206', '{}'), + (4233, 1001, 3003, null, '/parent-206[@key="B"]', '{"key": "B"}');
\ No newline at end of file |