diff options
23 files changed, 138 insertions, 309 deletions
diff --git a/cps-ri/pom.xml b/cps-ri/pom.xml index db274f7f01..25dc91c6fd 100644 --- a/cps-ri/pom.xml +++ b/cps-ri/pom.xml @@ -33,7 +33,7 @@ <artifactId>cps-ri</artifactId>
<properties>
- <minimum-coverage>0.64</minimum-coverage>
+ <minimum-coverage>0.54</minimum-coverage>
<!-- Additional coverage is provided by integration-test module -->
</properties>
diff --git a/cps-ri/src/main/java/org/onap/cps/spi/entities/AnchorEntity.java b/cps-ri/src/main/java/org/onap/cps/spi/entities/AnchorEntity.java index b59150f2e4..403741a2d6 100644 --- a/cps-ri/src/main/java/org/onap/cps/spi/entities/AnchorEntity.java +++ b/cps-ri/src/main/java/org/onap/cps/spi/entities/AnchorEntity.java @@ -55,7 +55,7 @@ public class AnchorEntity implements Serializable { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) - private Integer id; + private Long id; @NotNull @Column diff --git a/cps-ri/src/main/java/org/onap/cps/spi/entities/FragmentEntityArranger.java b/cps-ri/src/main/java/org/onap/cps/spi/entities/FragmentEntityArranger.java index c1b1322bb5..697eb8de00 100644 --- a/cps-ri/src/main/java/org/onap/cps/spi/entities/FragmentEntityArranger.java +++ b/cps-ri/src/main/java/org/onap/cps/spi/entities/FragmentEntityArranger.java @@ -58,7 +58,7 @@ public class FragmentEntityArranger { * @return a collection of FragmentEntities (trees) with descendants. */ public static Collection<FragmentEntity> toFragmentEntityTreesAcrossAnchors( - final Map<Integer, AnchorEntity> anchorEntityPerId, final Collection<FragmentExtract> fragmentExtracts) { + final Map<Long, AnchorEntity> anchorEntityPerId, final Collection<FragmentExtract> fragmentExtracts) { final Map<Long, FragmentEntity> fragmentEntityPerId = new HashMap<>(); for (final FragmentExtract fragmentExtract : fragmentExtracts) { final AnchorEntity anchorEntity = anchorEntityPerId.get(fragmentExtract.getAnchorId()); diff --git a/cps-ri/src/main/java/org/onap/cps/spi/entities/FragmentExtract.java b/cps-ri/src/main/java/org/onap/cps/spi/entities/FragmentExtract.java index 3aa19e670b..50be3c7b7a 100644 --- a/cps-ri/src/main/java/org/onap/cps/spi/entities/FragmentExtract.java +++ b/cps-ri/src/main/java/org/onap/cps/spi/entities/FragmentExtract.java @@ -24,7 +24,7 @@ public interface FragmentExtract { Long getId(); - Integer getAnchorId(); + Long getAnchorId(); String getXpath(); diff --git a/cps-ri/src/main/java/org/onap/cps/spi/entities/YangResourceEntity.java b/cps-ri/src/main/java/org/onap/cps/spi/entities/YangResourceEntity.java index 53ae820262..71d97a3ed2 100644 --- a/cps-ri/src/main/java/org/onap/cps/spi/entities/YangResourceEntity.java +++ b/cps-ri/src/main/java/org/onap/cps/spi/entities/YangResourceEntity.java @@ -1,7 +1,7 @@ /* * ============LICENSE_START======================================================= * Copyright (C) 2020 Pantheon.tech - * Modifications Copyright (C) 2021-2022 Nordix Foundation + * Modifications Copyright (C) 2021-2023 Nordix Foundation * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -48,7 +48,7 @@ public class YangResourceEntity implements Serializable { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; + private Integer id; @NotNull @Column 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 162b268d87..6f9f5a482c 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 @@ -198,12 +198,10 @@ public class CpsAdminPersistenceServiceImpl implements CpsAdminPersistenceServic verifyDataspaceName(dataspaceName); } if (inputModuleNames.size() > retrievedModuleReferences.size()) { - final List<String> moduleNamesNotFound = inputModuleNames.stream() + final List<String> unknownModules = inputModuleNames.stream() .filter(moduleName -> !retrievedModuleReferences.contains(moduleName)) .collect(Collectors.toList()); - if (!moduleNamesNotFound.isEmpty()) { - throw new ModuleNamesNotFoundException(dataspaceName, moduleNamesNotFound); - } + throw new ModuleNamesNotFoundException(dataspaceName, unknownModules); } } 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 890941bf33..fdb01485ad 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 @@ -346,10 +346,10 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService fragmentRepository.findExtractsWithDescendantsByIds(fragmentEntityIds, fetchDescendantsOption.getDepth()); if (anchorEntity == ALL_ANCHORS) { - final Collection<Integer> anchorIds = fragmentExtracts.stream() + final Collection<Long> anchorIds = fragmentExtracts.stream() .map(FragmentExtract::getAnchorId).collect(Collectors.toSet()); final List<AnchorEntity> anchorEntities = anchorRepository.findAllById(anchorIds); - final Map<Integer, AnchorEntity> anchorEntityPerId = anchorEntities.stream() + final Map<Long, AnchorEntity> anchorEntityPerId = anchorEntities.stream() .collect(Collectors.toMap(AnchorEntity::getId, Function.identity())); return FragmentEntityArranger.toFragmentEntityTreesAcrossAnchors(anchorEntityPerId, fragmentExtracts); } 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 5eda15a3d7..e149a1f149 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 @@ -172,7 +172,7 @@ public class CpsModulePersistenceServiceImpl implements CpsModulePersistenceServ final DataspaceEntity dataspaceEntity = dataspaceRepository.getByName(dataspaceName); final SchemaSetEntity schemaSetEntity = schemaSetRepository.getByDataspaceAndName(dataspaceEntity, schemaSetName); - final List<Long> allYangResourceIds = + final List<Integer> allYangResourceIds = yangResourceRepository.getResourceIdsByModuleReferences(allModuleReferences); yangResourceRepository.insertSchemaSetIdYangResourceId(schemaSetEntity.getId(), allYangResourceIds); } 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 fe9ff9e2f0..5bb5857810 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 @@ -33,7 +33,7 @@ import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; @Repository -public interface AnchorRepository extends JpaRepository<AnchorEntity, Integer> { +public interface AnchorRepository extends JpaRepository<AnchorEntity, Long> { Optional<AnchorEntity> findByDataspaceAndName(DataspaceEntity dataspaceEntity, String name); diff --git a/cps-ri/src/main/java/org/onap/cps/spi/repository/FragmentRepository.java b/cps-ri/src/main/java/org/onap/cps/spi/repository/FragmentRepository.java index 2691be9844..425a7267d9 100755 --- a/cps-ri/src/main/java/org/onap/cps/spi/repository/FragmentRepository.java +++ b/cps-ri/src/main/java/org/onap/cps/spi/repository/FragmentRepository.java @@ -47,7 +47,7 @@ public interface FragmentRepository extends JpaRepository<FragmentEntity, Long>, new DataNodeNotFoundException(anchorEntity.getDataspace().getName(), anchorEntity.getName(), xpath));
}
- List<FragmentEntity> findByAnchorIdAndXpathIn(int anchorId, String[] xpaths);
+ List<FragmentEntity> findByAnchorIdAndXpathIn(long anchorId, String[] xpaths);
default List<FragmentEntity> findByAnchorAndXpathIn(final AnchorEntity anchorEntity,
final Collection<String> xpaths) {
@@ -64,41 +64,41 @@ public interface FragmentRepository extends JpaRepository<FragmentEntity, Long>, return findByDataspaceIdAndXpathIn(dataspaceEntity.getId(), xpaths.toArray(new String[0]));
}
- boolean existsByAnchorId(int anchorId);
+ boolean existsByAnchorId(long anchorId);
@Query("SELECT f FROM FragmentEntity f WHERE anchor = :anchor")
List<FragmentExtract> findAllExtractsByAnchor(@Param("anchor") AnchorEntity anchorEntity);
@Modifying
@Query(value = "DELETE FROM fragment WHERE anchor_id = ANY (:anchorIds)", nativeQuery = true)
- void deleteByAnchorIdIn(@Param("anchorIds") int[] anchorIds);
+ void deleteByAnchorIdIn(@Param("anchorIds") long[] anchorIds);
default void deleteByAnchorIn(final Collection<AnchorEntity> anchorEntities) {
- deleteByAnchorIdIn(anchorEntities.stream().map(AnchorEntity::getId).mapToInt(id -> id).toArray());
+ deleteByAnchorIdIn(anchorEntities.stream().map(AnchorEntity::getId).mapToLong(id -> id).toArray());
}
@Modifying
@Query(value = "DELETE FROM fragment WHERE anchor_id = :anchorId AND xpath = ANY (:xpaths)", nativeQuery = true)
- void deleteByAnchorIdAndXpaths(@Param("anchorId") int anchorId, @Param("xpaths") String[] xpaths);
+ void deleteByAnchorIdAndXpaths(@Param("anchorId") long anchorId, @Param("xpaths") String[] xpaths);
- default void deleteByAnchorIdAndXpaths(final int anchorId, final Collection<String> xpaths) {
+ default void deleteByAnchorIdAndXpaths(final long anchorId, final Collection<String> xpaths) {
deleteByAnchorIdAndXpaths(anchorId, xpaths.toArray(new String[0]));
}
@Modifying
@Query(value = "DELETE FROM fragment f WHERE anchor_id = :anchorId AND xpath LIKE ANY (:xpathPatterns)",
nativeQuery = true)
- void deleteByAnchorIdAndXpathLikeAny(@Param("anchorId") int anchorId,
+ void deleteByAnchorIdAndXpathLikeAny(@Param("anchorId") long anchorId,
@Param("xpathPatterns") String[] xpathPatterns);
- default void deleteListsByAnchorIdAndXpaths(int anchorId, Collection<String> xpaths) {
+ default void deleteListsByAnchorIdAndXpaths(long anchorId, Collection<String> xpaths) {
final String[] listXpathPatterns = xpaths.stream().map(xpath -> xpath + "[%").toArray(String[]::new);
deleteByAnchorIdAndXpathLikeAny(anchorId, listXpathPatterns);
}
@Query(value = "SELECT xpath FROM fragment WHERE anchor_id = :anchorId AND xpath = ANY (:xpaths)",
nativeQuery = true)
- List<String> findAllXpathByAnchorIdAndXpathIn(@Param("anchorId") int anchorId,
+ List<String> findAllXpathByAnchorIdAndXpathIn(@Param("anchorId") long anchorId,
@Param("xpaths") String[] xpaths);
default List<String> findAllXpathByAnchorAndXpathIn(final AnchorEntity anchorEntity,
@@ -125,11 +125,11 @@ public interface FragmentRepository extends JpaRepository<FragmentEntity, Long>, + "FROM fragment f INNER JOIN parent_search p ON f.id = p.id",
nativeQuery = true
)
- List<FragmentExtract> findExtractsWithDescendants(@Param("anchorId") int anchorId,
+ List<FragmentExtract> findExtractsWithDescendants(@Param("anchorId") long anchorId,
@Param("xpaths") String[] xpaths,
@Param("maxDepth") int maxDepth);
- default List<FragmentExtract> findExtractsWithDescendants(final int anchorId, final Collection<String> xpaths,
+ default List<FragmentExtract> findExtractsWithDescendants(final long anchorId, final Collection<String> xpaths,
final int maxDepth) {
return findExtractsWithDescendants(anchorId, xpaths.toArray(new String[0]), maxDepth);
}
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 index ef701bc7dc..15ffa372f9 100644 --- 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 @@ -1,6 +1,6 @@ /* * ============LICENSE_START======================================================= - * Copyright (C) 2022 Nordix Foundation. + * Copyright (C) 2022-2023 Nordix Foundation. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,5 +25,5 @@ import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; @Repository -public interface ModuleReferenceRepository extends JpaRepository<YangResourceEntity, Long>, ModuleReferenceQuery {} +public interface ModuleReferenceRepository extends JpaRepository<YangResourceEntity, Integer>, ModuleReferenceQuery {} 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 index 0361749cdc..aacebd63b3 100644 --- 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 @@ -1,6 +1,6 @@ /*- * ============LICENSE_START======================================================= - * Copyright (C) 2021 Nordix Foundation. + * Copyright (C) 2021-2023 Nordix Foundation. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,6 +24,6 @@ import java.util.List; public interface SchemaSetYangResourceRepository { - void insertSchemaSetIdYangResourceId(final Integer schemaSetId, final List<Long> yangResourceId); + void insertSchemaSetIdYangResourceId(final Integer schemaSetId, final List<Integer> yangResourceIds); } 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 index c87e15adbf..0f7f2c0658 100644 --- 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 @@ -1,6 +1,6 @@ /*- * ============LICENSE_START======================================================= - * Copyright (C) 2021-2022 Nordix Foundation. + * Copyright (C) 2021-2023 Nordix Foundation. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -37,15 +37,15 @@ public class SchemaSetYangResourceRepositoryImpl implements SchemaSetYangResourc private EntityManager entityManager; @Override - public void insertSchemaSetIdYangResourceId(final Integer schemaSetId, final List<Long> yangResourceIds) { + public void insertSchemaSetIdYangResourceId(final Integer schemaSetId, final List<Integer> yangResourceIds) { final Session session = entityManager.unwrap(Session.class); session.doWork(connection -> { try (PreparedStatement preparedStatement = connection.prepareStatement( "INSERT INTO SCHEMA_SET_YANG_RESOURCES (SCHEMA_SET_ID, YANG_RESOURCE_ID) VALUES ( ?, ?)")) { int sqlQueryCount = 1; - for (final long yangResourceId : yangResourceIds) { + for (final int yangResourceId : yangResourceIds) { preparedStatement.setInt(1, schemaSetId); - preparedStatement.setLong(2, yangResourceId); + preparedStatement.setInt(2, yangResourceId); preparedStatement.addBatch(); if (sqlQueryCount % MAX_INSERT_BATCH_SIZE == 0 || sqlQueryCount == yangResourceIds.size()) { preparedStatement.executeBatch(); diff --git a/cps-ri/src/main/java/org/onap/cps/spi/repository/YangResourceNativeRepository.java b/cps-ri/src/main/java/org/onap/cps/spi/repository/YangResourceNativeRepository.java index 335c971f97..9ae32b3e78 100644 --- a/cps-ri/src/main/java/org/onap/cps/spi/repository/YangResourceNativeRepository.java +++ b/cps-ri/src/main/java/org/onap/cps/spi/repository/YangResourceNativeRepository.java @@ -1,6 +1,6 @@ /*- * ============LICENSE_START======================================================= - * Copyright (C) 2022 Nordix Foundation. + * Copyright (C) 2022-2023 Nordix Foundation. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,6 +26,6 @@ import org.onap.cps.spi.model.ModuleReference; public interface YangResourceNativeRepository { - List<Long> getResourceIdsByModuleReferences(Collection<ModuleReference> moduleReferences); + List<Integer> getResourceIdsByModuleReferences(Collection<ModuleReference> moduleReferences); } diff --git a/cps-ri/src/main/java/org/onap/cps/spi/repository/YangResourceNativeRepositoryImpl.java b/cps-ri/src/main/java/org/onap/cps/spi/repository/YangResourceNativeRepositoryImpl.java index 850b274c91..f09a1a0c46 100644 --- a/cps-ri/src/main/java/org/onap/cps/spi/repository/YangResourceNativeRepositoryImpl.java +++ b/cps-ri/src/main/java/org/onap/cps/spi/repository/YangResourceNativeRepositoryImpl.java @@ -1,6 +1,6 @@ /*- * ============LICENSE_START======================================================= - * Copyright (C) 2022 Nordix Foundation. + * Copyright (C) 2022-2023 Nordix Foundation. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -42,14 +42,14 @@ public class YangResourceNativeRepositoryImpl implements YangResourceNativeRepos @Override @Transactional - public List<Long> getResourceIdsByModuleReferences(final Collection<ModuleReference> moduleReferences) { + public List<Integer> getResourceIdsByModuleReferences(final Collection<ModuleReference> moduleReferences) { if (moduleReferences.isEmpty()) { return Collections.emptyList(); } final Query query = entityManager.createNativeQuery(getCombinedSelectSqlQuery(moduleReferences)) .unwrap(org.hibernate.query.NativeQuery.class) - .addScalar("id", StandardBasicTypes.LONG); - final List<Long> yangResourceIds = query.getResultList(); + .addScalar("id", StandardBasicTypes.INTEGER); + final List<Integer> yangResourceIds = query.getResultList(); if (yangResourceIds.size() != moduleReferences.size()) { log.warn("ModuleReferences size : {} and QueryResult size : {}", moduleReferences.size(), yangResourceIds.size()); 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 7584ff65c0..df21ccc52e 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 @@ -32,7 +32,7 @@ import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; @Repository -public interface YangResourceRepository extends JpaRepository<YangResourceEntity, Long>, +public interface YangResourceRepository extends JpaRepository<YangResourceEntity, Integer>, YangResourceNativeRepository, SchemaSetYangResourceRepository { List<YangResourceEntity> findAllByChecksumIn(String[] checksums); diff --git a/cps-ri/src/main/java/org/onap/cps/spi/utils/SessionManager.java b/cps-ri/src/main/java/org/onap/cps/spi/utils/SessionManager.java index 6f96cffdc1..eb3c5289af 100644 --- a/cps-ri/src/main/java/org/onap/cps/spi/utils/SessionManager.java +++ b/cps-ri/src/main/java/org/onap/cps/spi/utils/SessionManager.java @@ -163,7 +163,7 @@ public class SessionManager { final Session session = getSession(sessionId); final DataspaceEntity dataspaceEntity = dataspaceRepository.getByName(dataspaceName); final AnchorEntity anchorEntity = anchorRepository.getByDataspaceAndName(dataspaceEntity, anchorName); - final int anchorId = anchorEntity.getId(); + final long anchorId = anchorEntity.getId(); log.debug("Attempting to lock anchor {} for session {}", anchorName, sessionId); session.get(AnchorEntity.class, anchorId, LockMode.PESSIMISTIC_WRITE); log.info("Anchor {} successfully locked", anchorName); diff --git a/cps-ri/src/main/resources/changelog/changelog-master.yaml b/cps-ri/src/main/resources/changelog/changelog-master.yaml index 40e23e2e30..4e6986e71f 100644 --- a/cps-ri/src/main/resources/changelog/changelog-master.yaml +++ b/cps-ri/src/main/resources/changelog/changelog-master.yaml @@ -54,3 +54,5 @@ databaseChangeLog: file: changelog/db/changes/18-cascade-delete-fragment-children.yaml - include: file: changelog/db/changes/19-delete-not-required-dataspace-id-from-fragment.yaml + - include: + file: changelog/db/changes/20-change-foreign-key-id-types-to-integer.yaml diff --git a/cps-ri/src/main/resources/changelog/db/changes/20-change-foreign-key-id-types-to-integer.yaml b/cps-ri/src/main/resources/changelog/db/changes/20-change-foreign-key-id-types-to-integer.yaml new file mode 100644 index 0000000000..4c0cd9f336 --- /dev/null +++ b/cps-ri/src/main/resources/changelog/db/changes/20-change-foreign-key-id-types-to-integer.yaml @@ -0,0 +1,48 @@ +# ============LICENSE_START======================================================= +# Copyright (C) 2023 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========================================================= + +databaseChangeLog: + - changeSet: + author: cps + id: 20 + changes: + - modifyDataType: + columnName: dataspace_id + newDataType: INTEGER + tableName: schema_set + - modifyDataType: + columnName: schema_set_id + newDataType: INTEGER + tableName: schema_set_yang_resources + - modifyDataType: + columnName: yang_resource_id + newDataType: INTEGER + tableName: schema_set_yang_resources + rollback: + - modifyDataType: + columnName: dataspace_id + newDataType: BIGINT + tableName: schema_set + - modifyDataType: + columnName: schema_set_id + newDataType: BIGINT + tableName: schema_set_yang_resources + - modifyDataType: + columnName: yang_resource_id + newDataType: BIGINT + tableName: schema_set_yang_resources 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 deleted file mode 100644 index 28d3bcfa4c..0000000000 --- a/cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsAdminPersistenceServiceSpec.groovy +++ /dev/null @@ -1,263 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * Copyright (C) 2021-2023 Nordix Foundation - * Modifications Copyright (C) 2021 Pantheon.tech - * Modifications Copyright (C) 2022 Bell Canada - * Modifications Copyright (C) 2022 TechMahindra Ltd. - * ================================================================================ - * 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.impl - -import org.mockito.Mock -import org.onap.cps.spi.CpsAdminPersistenceService -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 org.onap.cps.spi.exceptions.SchemaSetNotFoundException -import org.onap.cps.spi.model.Anchor -import org.onap.cps.spi.model.Dataspace -import org.springframework.beans.factory.annotation.Autowired -import org.springframework.test.context.jdbc.Sql -import org.testcontainers.shaded.com.fasterxml.jackson.databind.ObjectMapper - -class CpsAdminPersistenceServiceSpec extends CpsPersistenceSpecBase { - - @Autowired - CpsAdminPersistenceService objectUnderTest - - @Mock - ObjectMapper objectMapper - - static final String SET_DATA = '/data/anchor.sql' - static final String SAMPLE_DATA_FOR_ANCHORS_WITH_MODULES = '/data/anchors-schemaset-modules.sql' - static final String DATASPACE_WITH_NO_DATA = 'DATASPACE-002-NO-DATA' - static final Integer DELETED_ANCHOR_ID = 3002 - - @Sql(CLEAR_DATA) - def 'Create and retrieve a new dataspace.'() { - when: 'a new dataspace is created' - def dataspaceName = 'some-new-dataspace' - objectUnderTest.createDataspace(dataspaceName) - then: 'that dataspace can be retrieved from the dataspace repository' - def dataspaceEntity = dataspaceRepository.findByName(dataspaceName).orElseThrow() - dataspaceEntity.id != null - dataspaceEntity.name == dataspaceName - } - - @Sql([CLEAR_DATA, SET_DATA]) - def 'Attempt to create a duplicate dataspace.'() { - when: 'an attempt is made to create an already existing dataspace' - objectUnderTest.createDataspace(DATASPACE_NAME) - then: 'an exception that is is already defined is thrown with the correct details' - def thrown = thrown(AlreadyDefinedException) - thrown.details.contains(DATASPACE_NAME) - } - - @Sql([CLEAR_DATA, SET_DATA]) - def 'Get a dataspace.'() { - when: 'dataspace is retrieved' - def dataspace = objectUnderTest.getDataspace(DATASPACE_NAME) - then: ' the response contains expected dataspace' - assert dataspace.getName().equals(DATASPACE_NAME); - } - - @Sql([CLEAR_DATA, SET_DATA]) - def 'Get all dataspaces.'() { - when: 'all dataspaces are retrieved' - def dataspaces = objectUnderTest.getAllDataspaces() - then: 'the response contains expected dataspaces' - def expectedDataspaces = Set.of(new Dataspace(name: 'DATASPACE-001'), new Dataspace(name: 'DATASPACE-002-NO-DATA'), - new Dataspace(name: 'DATASPACE-003')) - assert dataspaces == expectedDataspaces - } - - @Sql([CLEAR_DATA, SET_DATA]) - def 'Get non existing dataspace.'() { - when: 'attempting to retrieve a non-existing dataspace' - def dataspace = objectUnderTest.getDataspace('non_existing_dataspace') - then: 'an DataspaceNotFoundException is thrown' - thrown(DataspaceNotFoundException) - } - - @Sql([CLEAR_DATA, SET_DATA]) - def 'Create and retrieve a new anchor.'() { - when: 'a new anchor is created' - def newAnchorName = 'my-new-anchor' - objectUnderTest.createAnchor(DATASPACE_NAME, SCHEMA_SET_NAME1, newAnchorName) - then: 'that anchor can be retrieved' - def anchor = objectUnderTest.getAnchor(DATASPACE_NAME, newAnchorName) - anchor.name == newAnchorName - anchor.dataspaceName == DATASPACE_NAME - anchor.schemaSetName == SCHEMA_SET_NAME1 - } - - @Sql([CLEAR_DATA, SET_DATA]) - def 'Create anchor error scenario: #scenario.'() { - when: 'attempt to create new anchor named #anchorName in dataspace #dataspaceName with #schemaSetName' - objectUnderTest.createAnchor(dataspaceName, schemaSetName, anchorName) - then: 'an #expectedException is thrown' - thrown(expectedException) - where: 'the following data is used' - scenario | dataspaceName | schemaSetName | anchorName || expectedException - 'dataspace does not exist' | 'unknown' | 'not-relevant' | 'not-relevant' || DataspaceNotFoundException - 'schema set does not exist' | DATASPACE_NAME | 'unknown' | 'not-relevant' || SchemaSetNotFoundException - 'anchor already exists' | DATASPACE_NAME | SCHEMA_SET_NAME1 | ANCHOR_NAME1 || AlreadyDefinedException - } - - @Sql([CLEAR_DATA, SET_DATA]) - def 'Get anchor error scenario: #scenario.'() { - when: 'attempt to get anchor named #anchorName in dataspace #dataspaceName' - objectUnderTest.getAnchor(dataspaceName, anchorName) - then: 'an #expectedException is thrown' - thrown(expectedException) - where: 'the following data is used' - scenario | dataspaceName | anchorName || expectedException - 'dataspace does not exist' | 'unknown' | 'not-relevant' || DataspaceNotFoundException - 'anchor does not exists' | DATASPACE_NAME | 'unknown' || AnchorNotFoundException - } - - @Sql([CLEAR_DATA, SET_DATA]) - def 'Get all anchors in dataspace #dataspaceName.'() { - when: 'all anchors are retrieved from #DATASPACE_NAME' - def result = objectUnderTest.getAnchors(dataspaceName) - then: 'the expected collection of anchors is returned' - result.size() == expectedAnchors.size() - result.containsAll(expectedAnchors) - where: 'the following data is used' - dataspaceName || expectedAnchors - DATASPACE_NAME || [Anchor.builder().name(ANCHOR_NAME1).schemaSetName(SCHEMA_SET_NAME1).dataspaceName(DATASPACE_NAME).build(), - Anchor.builder().name(ANCHOR_NAME2).schemaSetName(SCHEMA_SET_NAME2).dataspaceName(DATASPACE_NAME).build(), - Anchor.builder().name(ANCHOR_NAME3).schemaSetName(SCHEMA_SET_NAME2).dataspaceName(DATASPACE_NAME).build()] - DATASPACE_WITH_NO_DATA || [] - } - - @Sql([CLEAR_DATA, SET_DATA]) - def 'Get all anchors associated with schemaset in a dataspace.'() { - when: 'anchors are retrieved by dataspace and schema-set' - def anchors = objectUnderTest.getAnchors(dataspace, schemasetName) - then: ' the response contains expected anchors' - anchors == expectedAnchors - where: - scenario | dataspace | schemasetName || expectedAnchors - 'no-anchors' | 'DATASPACE-003' | 'SCHEMA-SET-002-NO-ANCHORS' || Collections.emptySet() - 'one-anchor' | 'DATASPACE-001' | 'SCHEMA-SET-001' || Set.of(new Anchor('ANCHOR-001', 'DATASPACE-001', 'SCHEMA-SET-001')) - } - - @Sql([CLEAR_DATA, SET_DATA]) - def 'Error Handling: Get all anchors associated with schemaset in a dataspace.'() { - when: 'anchors are retrieved by dataspace and schema-set' - def anchors = objectUnderTest.getAnchors(dataspace, schemasetName) - then: ' an expected expception is thrown' - thrown(expectedException) - where: - scenario | dataspace | schemasetName || expectedException - 'unknown-dataspace' | 'unknown' | 'SCHEMA-SET-002-NO-ANCHORS' || DataspaceNotFoundException - 'unknown-schemaset' | 'DATASPACE-001' | 'unknown-schema-set' || SchemaSetNotFoundException - } - - @Sql(CLEAR_DATA) - def 'Get all anchors in unknown dataspace.'() { - when: 'attempt to get all anchors in an unknown dataspace' - objectUnderTest.getAnchors('unknown-dataspace') - then: 'an DataspaceNotFoundException is thrown' - thrown(DataspaceNotFoundException) - } - - @Sql([CLEAR_DATA, SET_DATA]) - def 'Get all anchors associated with multiple schemasets in a dataspace.'() { - when: 'anchors are retrieved by dataspace and schema-sets' - def anchors = objectUnderTest.getAnchors('DATASPACE-001', ['SCHEMA-SET-001', 'SCHEMA-SET-002']) - then: ' the response contains expected anchors' - anchors == Set.of( - new Anchor('ANCHOR-001', 'DATASPACE-001', 'SCHEMA-SET-001'), - new Anchor('ANCHOR-002', 'DATASPACE-001', 'SCHEMA-SET-002'), - new Anchor('ANCHOR-003', 'DATASPACE-001', 'SCHEMA-SET-002')) - } - - @Sql([CLEAR_DATA, SET_DATA]) - def 'Delete anchor'() { - when: 'delete anchor action is invoked' - objectUnderTest.deleteAnchor(DATASPACE_NAME, ANCHOR_NAME2) - then: 'anchor is deleted' - assert anchorRepository.findById(DELETED_ANCHOR_ID).isEmpty() - } - - @Sql([CLEAR_DATA, SET_DATA]) - def 'delete anchor error scenario: #scenario'() { - when: 'delete anchor attempt is performed' - objectUnderTest.deleteAnchor(dataspaceName, anchorName) - then: 'an #expectedException is thrown' - thrown(expectedException) - where: 'the following data is used' - scenario | dataspaceName | anchorName || expectedException - 'dataspace does not exist' | 'unknown' | 'not-relevant' || DataspaceNotFoundException - 'anchor does not exists' | DATASPACE_NAME | 'unknown' || AnchorNotFoundException - } - - @Sql([CLEAR_DATA, SET_DATA]) - def 'Delete multiple anchors'() { - when: 'delete anchors action is invoked' - objectUnderTest.deleteAnchors(DATASPACE_NAME, ['ANCHOR-002', 'ANCHOR-003']) - then: 'anchors are deleted' - anchorRepository.findById(3002).isEmpty() - anchorRepository.findById(3003).isEmpty() - } - - @Sql([CLEAR_DATA, SAMPLE_DATA_FOR_ANCHORS_WITH_MODULES]) - def 'Query anchors that have #scenario.'() { - when: 'all anchor are retrieved for the given dataspace name and module names' - def anchors = objectUnderTest.queryAnchors(inputDataspaceName, inputModuleNames) - then: 'the expected anchors are returned' - anchors.size() == expectedAnchors.size() - anchors.containsAll(expectedAnchors) - where: 'the following data is used' - scenario | inputDataspaceName | inputModuleNames || expectedAnchors - 'one module' | 'dataspace-1' | ['module-name-1'] || [buildAnchor('anchor-2', 'dataspace-1', 'schema-set-2'), buildAnchor('anchor-1', 'dataspace-1', 'schema-set-1')] - 'two modules' | 'dataspace-1' | ['module-name-1', 'module-name-2'] || [buildAnchor('anchor-2', 'dataspace-1', 'schema-set-2'), buildAnchor('anchor-1', 'dataspace-1', 'schema-set-1')] - 'no anchors for all three modules' | 'dataspace-1' | ['module-name-1', 'module-name-2', 'module-name-3'] || [] - 'unknown dataspace' | 'db-does-not-exist' | ['does-not-matter'] || [] - 'unknown module and known module' | 'dataspace-1' | ['module-name-1', 'module-does-not-exist'] || [] - } - - def buildAnchor(def anchorName, def dataspaceName, def SchemaSetName) { - return Anchor.builder().name(anchorName).dataspaceName(dataspaceName).schemaSetName(SchemaSetName).build() - } - - @Sql([CLEAR_DATA, SET_DATA]) - def 'Delete dataspace.'() { - when: 'delete dataspace action is invoked' - objectUnderTest.deleteDataspace(DATASPACE_WITH_NO_DATA) - then: 'dataspace is deleted' - assert dataspaceRepository.findByName(DATASPACE_WITH_NO_DATA).isEmpty(); - } - - @Sql([CLEAR_DATA, SET_DATA]) - def 'Delete dataspace when #scenario.'() { - when: 'delete dataspace action is invoked' - objectUnderTest.deleteDataspace(dataspaceName) - then: 'the correct exception is thrown with the relevant details' - def thrownException = thrown(expectedException) - thrownException.details.contains(expectedMessageDetails) - where: 'the following data is used' - scenario | dataspaceName || expectedException | expectedMessageDetails - 'dataspace name does not exist' | 'unknown' || DataspaceNotFoundException | 'unknown does not exist' - 'dataspace contains an anchor' | 'DATASPACE-001' || DataspaceInUseException | 'contains 3 anchor(s)' - 'dataspace contains schemasets' | 'DATASPACE-003' || DataspaceInUseException | 'contains 1 schemaset(s)' - } -} diff --git a/docker-compose/docker-compose.yml b/docker-compose/docker-compose.yml index 720761d498..3dc54bbfc4 100644 --- a/docker-compose/docker-compose.yml +++ b/docker-compose/docker-compose.yml @@ -81,7 +81,7 @@ services: ncmp-dmi-plugin: container_name: ncmp-dmi-plugin - image: ${DOCKER_REPO:-nexus3.onap.org:10003}/onap/ncmp-dmi-plugin:${DMI_VERSION:-1.3.0-SNAPSHOT-latest} + image: ${DOCKER_REPO:-nexus3.onap.org:10003}/onap/ncmp-dmi-plugin:${DMI_VERSION:-1.4.0-SNAPSHOT-latest} ports: - ${DMI_PORT:-8783}:8080 - ${DMI_MANAGEMENT_PORT:-8787}:8081 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 91a4c8ac0e..92fbdaaa25 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 @@ -24,6 +24,7 @@ import org.onap.cps.api.CpsAdminService import org.onap.cps.integration.base.CpsIntegrationSpecBase 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 class CpsAdminServiceIntegrationSpec extends CpsIntegrationSpecBase { @@ -49,6 +50,27 @@ class CpsAdminServiceIntegrationSpec extends CpsIntegrationSpecBase { assert thrown instanceof DataspaceNotFoundException } + def 'Delete dataspace with error; #scenario.'() { + setup: 'add some anchors if needed' + numberOfAnchors.times { + objectUnderTest.createAnchor(GENERAL_TEST_DATASPACE, BOOKSTORE_SCHEMA_SET, 'anchor' + it) + } + when: 'attempt to delete dataspace' + objectUnderTest.deleteDataspace(dataspaceName) + then: 'the correct exception is thrown with the relevant details' + def thrownException = thrown(expectedException) + thrownException.details.contains(expectedMessageDetails) + cleanup: + numberOfAnchors.times { + objectUnderTest.deleteAnchor(GENERAL_TEST_DATASPACE, 'anchor' + it) + } + where: 'the following data is used' + scenario | dataspaceName | numberOfAnchors || expectedException | expectedMessageDetails + 'dataspace name does not exist' | 'unknown' | 0 || DataspaceNotFoundException | 'unknown does not exist' + 'dataspace contains schemasets' | GENERAL_TEST_DATASPACE | 0 || DataspaceInUseException | 'contains 1 schemaset(s)' + 'dataspace contains anchors' | GENERAL_TEST_DATASPACE | 2 || DataspaceInUseException | 'contains 2 anchor(s)' + } + def 'Retrieve all dataspaces (depends on total test suite).'() { given: 'two addtional dataspaces are created' objectUnderTest.createDataspace('dataspace1') @@ -68,7 +90,7 @@ class CpsAdminServiceIntegrationSpec extends CpsIntegrationSpecBase { } def 'Anchor CRUD operations.'() { - when: 'a anchor is created' + when: 'an anchor is created' objectUnderTest.createAnchor(GENERAL_TEST_DATASPACE, BOOKSTORE_SCHEMA_SET, 'newAnchor') then: 'the anchor be read' assert objectUnderTest.getAnchor(GENERAL_TEST_DATASPACE, 'newAnchor').name == 'newAnchor' @@ -107,4 +129,26 @@ class CpsAdminServiceIntegrationSpec extends CpsIntegrationSpecBase { assert objectUnderTest.queryAnchorNames(GENERAL_TEST_DATASPACE, ['stores', 'unused-model']).size() == 0 } + def 'Duplicate anchors.'() { + given: 'an anchor is created' + objectUnderTest.createAnchor(GENERAL_TEST_DATASPACE, BOOKSTORE_SCHEMA_SET, 'newAnchor') + when: 'attempt to create another anchor with the same name' + objectUnderTest.createAnchor(GENERAL_TEST_DATASPACE, BOOKSTORE_SCHEMA_SET, 'newAnchor') + then: 'an exception is thrown that the anchor already is defined' + thrown(AlreadyDefinedException) + cleanup: + objectUnderTest.deleteAnchor(GENERAL_TEST_DATASPACE, 'newAnchor') + } + + def 'Query anchors without any known modules and #scenario'() { + when: 'querying for anchors with #scenario' + def result = objectUnderTest.queryAnchorNames(dataspaceName, ['unknownModule']) + then: 'an empty result is returned (no error)' + assert result == [] + where: + scenario | dataspaceName + 'non existing database' | 'nonExistingDataspace' + 'just unknown module(s)' | GENERAL_TEST_DATASPACE + } + } diff --git a/integration-test/src/test/resources/liquibase/test-changelog.yaml b/integration-test/src/test/resources/liquibase/test-changelog.yaml index f9e2e2fafb..3f12331453 100644 --- a/integration-test/src/test/resources/liquibase/test-changelog.yaml +++ b/integration-test/src/test/resources/liquibase/test-changelog.yaml @@ -150,7 +150,7 @@ databaseChangeLog: constraints: nullable: false name: dataspace_id - type: BIGINT + type: INTEGER tableName: schema_set - changeSet: id: 1-6 @@ -232,12 +232,12 @@ databaseChangeLog: constraints: nullable: false name: schema_set_id - type: BIGINT + type: INTEGER - column: constraints: nullable: false name: yang_resource_id - type: BIGINT + type: INTEGER tableName: schema_set_yang_resources - changeSet: id: 1-10 |