diff options
Diffstat (limited to 'cps-service')
16 files changed, 286 insertions, 85 deletions
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 b0e68cf8fb..fcf3f54cce 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 @@ -1,6 +1,6 @@ /* * ============LICENSE_START======================================================= - * Copyright (C) 2020-2022 Nordix Foundation + * Copyright (C) 2020-2023 Nordix Foundation * Modifications Copyright (C) 2020-2022 Bell Canada. * Modifications Copyright (C) 2021 Pantheon.tech * Modifications Copyright (C) 2022 TechMahindra Ltd. @@ -84,7 +84,7 @@ public interface CpsAdminService { Collection<Anchor> getAnchors(String dataspaceName); /** - * Read all anchors associated the given schema-set in the given dataspace. + * Read all anchors associated with the given schema-set in the given dataspace. * * @param dataspaceName dataspace name * @param schemaSetName schema-set name @@ -93,6 +93,15 @@ public interface CpsAdminService { Collection<Anchor> getAnchors(String dataspaceName, String schemaSetName); /** + * Read all anchors associated with the given schema-sets in the given dataspace. + * + * @param dataspaceName dataspace name + * @param schemaSetNames schema-set names + * @return a collection of anchors + */ + Collection<Anchor> getAnchors(String dataspaceName, Collection<String> schemaSetNames); + + /** * Get an anchor in the given dataspace using the anchor name. * * @param dataspaceName dataspace name @@ -110,6 +119,14 @@ public interface CpsAdminService { void deleteAnchor(String dataspaceName, String anchorName); /** + * Delete anchors by name in given dataspace. + * + * @param dataspaceName dataspace name + * @param anchorNames anchor names + */ + void deleteAnchors(String dataspaceName, Collection<String> anchorNames); + + /** * Query anchor names for the given module names in the provided dataspace. * * @param dataspaceName dataspace name diff --git a/cps-service/src/main/java/org/onap/cps/api/CpsDataService.java b/cps-service/src/main/java/org/onap/cps/api/CpsDataService.java index 174d71f64d..39fa45ac1a 100644 --- a/cps-service/src/main/java/org/onap/cps/api/CpsDataService.java +++ b/cps-service/src/main/java/org/onap/cps/api/CpsDataService.java @@ -4,6 +4,7 @@ * Modifications Copyright (C) 2021 Pantheon.tech * Modifications Copyright (C) 2021-2022 Bell Canada * Modifications Copyright (C) 2022 Deutsche Telekom AG + * Modifications Copyright (C) 2023 TechMahindra Ltd. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -110,30 +111,31 @@ public interface CpsDataService { Collection<String> jsonDataList, OffsetDateTime observedTimestamp); /** - * Retrieves datanode by XPath for given dataspace and anchor. + * Retrieves all the datanodes by XPath for given dataspace and anchor. * - * @param dataspaceName dataspace name - * @param anchorName anchor name - * @param xpath xpath - * @param fetchDescendantsOption defines the scope of data to fetch: either single node or all the descendant nodes - * (recursively) as well - * @return data node object + * @param dataspaceName dataspace name + * @param anchorName anchor name + * @param xpath xpath + * @param fetchDescendantsOption defines the scope of data to fetch: either single node or all the descendant nodes + * (recursively) as well + * @return collection of data node objects */ - DataNode getDataNode(String dataspaceName, String anchorName, String xpath, - FetchDescendantsOption fetchDescendantsOption); + Collection<DataNode> getDataNodes(String dataspaceName, String anchorName, String xpath, + FetchDescendantsOption fetchDescendantsOption); /** - * Retrieves datanodes by XPath for given dataspace and anchor. + * Retrieves all the datanodes for multiple XPaths for given dataspace and anchor. * - * @param dataspaceName dataspace name - * @param anchorName anchor name - * @param xpaths collection of xpath - * @param fetchDescendantsOption defines the scope of data to fetch: either single node or all the descendant nodes - * (recursively) as well - * @return data node object + * @param dataspaceName dataspace name + * @param anchorName anchor name + * @param xpaths collection of xpaths + * @param fetchDescendantsOption defines the scope of data to fetch: either single node or all the descendant nodes + * (recursively) as well + * @return collection of data node objects */ - Collection<DataNode> getDataNodes(String dataspaceName, String anchorName, Collection<String> xpaths, - FetchDescendantsOption fetchDescendantsOption); + Collection<DataNode> getDataNodesForMultipleXpaths(String dataspaceName, String anchorName, + Collection<String> xpaths, + FetchDescendantsOption fetchDescendantsOption); /** * Updates data node for given dataspace and anchor using xpath to parent node. @@ -228,6 +230,15 @@ public interface CpsDataService { void deleteDataNodes(String dataspaceName, String anchorName, OffsetDateTime observedTimestamp); /** + * Deletes all data nodes for multiple anchors in a dataspace. + * + * @param dataspaceName dataspace name + * @param anchorNames anchor names + * @param observedTimestamp observed timestamp + */ + void deleteDataNodes(String dataspaceName, Collection<String> anchorNames, OffsetDateTime observedTimestamp); + + /** * Deletes a list or a list-element under given anchor and dataspace. * * @param dataspaceName dataspace name 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 ece3eb95c9..e286eea173 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 @@ -1,6 +1,6 @@ /* * ============LICENSE_START======================================================= - * Copyright (C) 2020-2022 Nordix Foundation + * Copyright (C) 2020-2023 Nordix Foundation * Modifications Copyright (C) 2020-2022 Bell Canada. * Modifications Copyright (C) 2021 Pantheon.tech * Modifications Copyright (C) 2022 TechMahindra Ltd. @@ -87,6 +87,13 @@ public class CpsAdminServiceImpl implements CpsAdminService { } @Override + public Collection<Anchor> getAnchors(final String dataspaceName, final Collection<String> schemaSetNames) { + cpsValidator.validateNameCharacters(dataspaceName); + cpsValidator.validateNameCharacters(schemaSetNames); + return cpsAdminPersistenceService.getAnchors(dataspaceName, schemaSetNames); + } + + @Override public Anchor getAnchor(final String dataspaceName, final String anchorName) { cpsValidator.validateNameCharacters(dataspaceName, anchorName); return cpsAdminPersistenceService.getAnchor(dataspaceName, anchorName); @@ -100,6 +107,14 @@ public class CpsAdminServiceImpl implements CpsAdminService { } @Override + public void deleteAnchors(final String dataspaceName, final Collection<String> anchorNames) { + cpsValidator.validateNameCharacters(dataspaceName); + cpsValidator.validateNameCharacters(anchorNames); + cpsDataService.deleteDataNodes(dataspaceName, anchorNames, OffsetDateTime.now()); + cpsAdminPersistenceService.deleteAnchors(dataspaceName, anchorNames); + } + + @Override public Collection<String> queryAnchorNames(final String dataspaceName, final Collection<String> moduleNames) { cpsValidator.validateNameCharacters(dataspaceName); final Collection<Anchor> anchors = cpsAdminPersistenceService.queryAnchors(dataspaceName, moduleNames); diff --git a/cps-service/src/main/java/org/onap/cps/api/impl/CpsDataServiceImpl.java b/cps-service/src/main/java/org/onap/cps/api/impl/CpsDataServiceImpl.java index 06a0845385..721d4a9fbb 100755 --- a/cps-service/src/main/java/org/onap/cps/api/impl/CpsDataServiceImpl.java +++ b/cps-service/src/main/java/org/onap/cps/api/impl/CpsDataServiceImpl.java @@ -3,7 +3,7 @@ * Copyright (C) 2021-2023 Nordix Foundation * Modifications Copyright (C) 2020-2022 Bell Canada. * Modifications Copyright (C) 2021 Pantheon.tech - * Modifications Copyright (C) 2022 TechMahindra Ltd. + * Modifications Copyright (C) 2022-2023 TechMahindra Ltd. * Modifications Copyright (C) 2022 Deutsche Telekom AG * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); @@ -134,21 +134,23 @@ public class CpsDataServiceImpl implements CpsDataService { @Override @Timed(value = "cps.data.service.datanode.get", - description = "Time taken to get a data node") - public DataNode getDataNode(final String dataspaceName, final String anchorName, final String xpath, - final FetchDescendantsOption fetchDescendantsOption) { + description = "Time taken to get data nodes for an xpath") + public Collection<DataNode> getDataNodes(final String dataspaceName, final String anchorName, + final String xpath, + final FetchDescendantsOption fetchDescendantsOption) { cpsValidator.validateNameCharacters(dataspaceName, anchorName); - return cpsDataPersistenceService.getDataNode(dataspaceName, anchorName, xpath, fetchDescendantsOption); + return cpsDataPersistenceService.getDataNodes(dataspaceName, anchorName, xpath, fetchDescendantsOption); } @Override @Timed(value = "cps.data.service.datanode.batch.get", description = "Time taken to get a batch of data nodes") - public Collection<DataNode> getDataNodes(final String dataspaceName, final String anchorName, - final Collection<String> xpaths, - final FetchDescendantsOption fetchDescendantsOption) { + public Collection<DataNode> getDataNodesForMultipleXpaths(final String dataspaceName, final String anchorName, + final Collection<String> xpaths, + final FetchDescendantsOption fetchDescendantsOption) { cpsValidator.validateNameCharacters(dataspaceName, anchorName); - return cpsDataPersistenceService.getDataNodes(dataspaceName, anchorName, xpaths, fetchDescendantsOption); + return cpsDataPersistenceService.getDataNodesForMultipleXpaths(dataspaceName, anchorName, xpaths, + fetchDescendantsOption); } @Override @@ -272,8 +274,8 @@ public class CpsDataServiceImpl implements CpsDataService { } @Override - @Timed(value = "cps.data.service.datanode.all.delete", - description = "Time taken to delete all datanodes") + @Timed(value = "cps.data.service.datanode.delete.anchor", + description = "Time taken to delete all datanodes for an anchor") public void deleteDataNodes(final String dataspaceName, final String anchorName, final OffsetDateTime observedTimestamp) { cpsValidator.validateNameCharacters(dataspaceName, anchorName); @@ -282,6 +284,19 @@ public class CpsDataServiceImpl implements CpsDataService { } @Override + @Timed(value = "cps.data.service.datanode.delete.anchor.batch", + description = "Time taken to delete all datanodes for multiple anchors") + public void deleteDataNodes(final String dataspaceName, final Collection<String> anchorNames, + final OffsetDateTime observedTimestamp) { + cpsValidator.validateNameCharacters(dataspaceName); + cpsValidator.validateNameCharacters(anchorNames); + for (final String anchorName : anchorNames) { + processDataUpdatedEventAsync(dataspaceName, anchorName, ROOT_NODE_XPATH, DELETE, observedTimestamp); + } + cpsDataPersistenceService.deleteDataNodes(dataspaceName, anchorNames); + } + + @Override @Timed(value = "cps.data.service.list.delete", description = "Time taken to delete a list or list element") public void deleteListOrListElement(final String dataspaceName, final String anchorName, final String listNodeXpath, 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 e71e6ce662..d6c01f7a9b 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 @@ -26,6 +26,7 @@ package org.onap.cps.api.impl; import io.micrometer.core.annotation.Timed; import java.util.Collection; import java.util.Map; +import java.util.stream.Collectors; import lombok.RequiredArgsConstructor; import org.onap.cps.api.CpsAdminService; import org.onap.cps.api.CpsModuleService; @@ -114,12 +115,9 @@ public class CpsModuleServiceImpl implements CpsModuleService { public void deleteSchemaSetsWithCascade(final String dataspaceName, final Collection<String> schemaSetNames) { cpsValidator.validateNameCharacters(dataspaceName); cpsValidator.validateNameCharacters(schemaSetNames); - for (final String schemaSetName : schemaSetNames) { - final Collection<Anchor> anchors = cpsAdminService.getAnchors(dataspaceName, schemaSetName); - for (final Anchor anchor : anchors) { - cpsAdminService.deleteAnchor(dataspaceName, anchor.getName()); - } - } + final Collection<String> anchorNames = cpsAdminService.getAnchors(dataspaceName, schemaSetNames) + .stream().map(Anchor::getName).collect(Collectors.toSet()); + cpsAdminService.deleteAnchors(dataspaceName, anchorNames); cpsModulePersistenceService.deleteUnusedYangResourceModules(); cpsModulePersistenceService.deleteSchemaSets(dataspaceName, schemaSetNames); for (final String schemaSetName : schemaSetNames) { diff --git a/cps-service/src/main/java/org/onap/cps/notification/CpsDataUpdatedEventFactory.java b/cps-service/src/main/java/org/onap/cps/notification/CpsDataUpdatedEventFactory.java index f0cdaee8d6..38f8988279 100644 --- a/cps-service/src/main/java/org/onap/cps/notification/CpsDataUpdatedEventFactory.java +++ b/cps-service/src/main/java/org/onap/cps/notification/CpsDataUpdatedEventFactory.java @@ -2,6 +2,7 @@ * ============LICENSE_START======================================================= * Copyright (c) 2021-2022 Bell Canada. * Modifications Copyright (c) 2022 Nordix Foundation + * Modifications Copyright (C) 2023 TechMahindra Ltd. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -76,8 +77,8 @@ public class CpsDataUpdatedEventFactory { public CpsDataUpdatedEvent createCpsDataUpdatedEvent(final Anchor anchor, final OffsetDateTime observedTimestamp, final Operation operation) { final var dataNode = (operation == Operation.DELETE) ? null : - cpsDataService.getDataNode(anchor.getDataspaceName(), anchor.getName(), - "/", FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS); + cpsDataService.getDataNodes(anchor.getDataspaceName(), anchor.getName(), + "/", FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS).iterator().next(); return toCpsDataUpdatedEvent(anchor, dataNode, observedTimestamp, operation); } 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 6bcb69844d..1c1e80a20f 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 @@ -73,7 +73,7 @@ public interface CpsAdminPersistenceService { void createAnchor(String dataspaceName, String schemaSetName, String anchorName); /** - * Read all anchors associated the given schema-set in the given dataspace. + * Read all anchors associated with the given schema-set in the given dataspace. * * @param dataspaceName dataspace name * @param schemaSetName schema-set name @@ -82,6 +82,15 @@ public interface CpsAdminPersistenceService { Collection<Anchor> getAnchors(String dataspaceName, String schemaSetName); /** + * Read all anchors associated with multiple schema-sets in the given dataspace. + * + * @param dataspaceName dataspace name + * @param schemaSetNames schema-set names + * @return a collection of anchors + */ + Collection<Anchor> getAnchors(String dataspaceName, Collection<String> schemaSetNames); + + /** * Read all anchors in the given a dataspace. * * @param dataspaceName dataspace name @@ -116,4 +125,12 @@ public interface CpsAdminPersistenceService { * @param anchorName anchor name */ void deleteAnchor(String dataspaceName, String anchorName); + + /** + * Delete anchors by name in given dataspace. + * + * @param dataspaceName dataspace name + * @param anchorNames anchor names + */ + void deleteAnchors(String dataspaceName, Collection<String> anchorNames); } diff --git a/cps-service/src/main/java/org/onap/cps/spi/CpsDataPersistenceService.java b/cps-service/src/main/java/org/onap/cps/spi/CpsDataPersistenceService.java index 3e0b4475e8..90e6ec761d 100644 --- a/cps-service/src/main/java/org/onap/cps/spi/CpsDataPersistenceService.java +++ b/cps-service/src/main/java/org/onap/cps/spi/CpsDataPersistenceService.java @@ -3,7 +3,7 @@ * Copyright (C) 2020-2023 Nordix Foundation. * Modifications Copyright (C) 2021 Pantheon.tech * Modifications Copyright (C) 2022 Bell Canada - * Modifications Copyright (C) 2022 TechMahindra Ltd. + * Modifications Copyright (C) 2022-2023 TechMahindra Ltd. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -99,30 +99,33 @@ public interface CpsDataPersistenceService { Collection<Collection<DataNode>> newLists); /** - * Retrieves datanode by XPath for given dataspace and anchor. + * Retrieves multiple datanodes for a single XPath for given dataspace and anchor. + * Multiple data nodes are returned when xPath is set to root '/', otherwise single data node + * is returned when a specific xpath is used (Example: /bookstore). * * @param dataspaceName dataspace name * @param anchorName anchor name - * @param xpath xpath + * @param xpath one xpath * @param fetchDescendantsOption defines the scope of data to fetch: either single node or all the descendant nodes * (recursively) as well - * @return data node object + * @return collection of data node object */ - DataNode getDataNode(String dataspaceName, String anchorName, String xpath, - FetchDescendantsOption fetchDescendantsOption); + Collection<DataNode> getDataNodes(String dataspaceName, String anchorName, String xpath, + FetchDescendantsOption fetchDescendantsOption); /** - * Retrieves datanode by XPath for given dataspace and anchor. + * Retrieves multiple datanodes for multiple XPaths, given a dataspace and anchor. * - * @param dataspaceName dataspace name - * @param anchorName anchor name - * @param xpaths collection of xpaths - * @param fetchDescendantsOption defines the scope of data to fetch: either single node or all the descendant nodes - * (recursively) as well - * @return data node object + * @param dataspaceName dataspace name + * @param anchorName anchor name + * @param xpaths collection of xpaths + * @param fetchDescendantsOption defines the scope of data to fetch: either single node or all the descendant nodes + * (recursively) as well + * @return collection of data node object */ - Collection<DataNode> getDataNodes(String dataspaceName, String anchorName, Collection<String> xpaths, - FetchDescendantsOption fetchDescendantsOption); + Collection<DataNode> getDataNodesForMultipleXpaths(String dataspaceName, String anchorName, + Collection<String> xpaths, + FetchDescendantsOption fetchDescendantsOption); /** * Updates leaves for existing data node. @@ -191,6 +194,14 @@ public interface CpsDataPersistenceService { void deleteDataNodes(String dataspaceName, String anchorName); /** + * Deletes all dataNodes in multiple anchors. + * + * @param dataspaceName dataspace name + * @param anchorNames anchor names + */ + void deleteDataNodes(String dataspaceName, Collection<String> anchorNames); + + /** * Deletes a single existing list element or the whole list. * * @param dataspaceName dataspace name diff --git a/cps-service/src/main/java/org/onap/cps/spi/FetchDescendantsOption.java b/cps-service/src/main/java/org/onap/cps/spi/FetchDescendantsOption.java index 0c8cddcd73..cf5e04dc46 100644 --- a/cps-service/src/main/java/org/onap/cps/spi/FetchDescendantsOption.java +++ b/cps-service/src/main/java/org/onap/cps/spi/FetchDescendantsOption.java @@ -1,7 +1,7 @@ /* * ============LICENSE_START======================================================= * Copyright (C) 2021 Pantheon.tech - * Copyright (C) 2022 Nordix Foundation + * Copyright (C) 2022-2023 Nordix Foundation * Modifications Copyright (C) 2023 TechMahindra Ltd. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); @@ -30,15 +30,24 @@ import org.onap.cps.spi.exceptions.DataValidationException; @RequiredArgsConstructor public class FetchDescendantsOption { - public static final FetchDescendantsOption FETCH_DIRECT_CHILDREN_ONLY = new FetchDescendantsOption(1); - public static final FetchDescendantsOption OMIT_DESCENDANTS = new FetchDescendantsOption(0); - public static final FetchDescendantsOption INCLUDE_ALL_DESCENDANTS = new FetchDescendantsOption(-1); + public static final FetchDescendantsOption DIRECT_CHILDREN_ONLY + = new FetchDescendantsOption(1, "DirectChildrenOnly"); + public static final FetchDescendantsOption OMIT_DESCENDANTS + = new FetchDescendantsOption(0, "OmitDescendants"); + public static final FetchDescendantsOption INCLUDE_ALL_DESCENDANTS + = new FetchDescendantsOption(-1, "IncludeAllDescendants"); + + FetchDescendantsOption(final int depth) { + this(depth, "Depth=" + depth); + } private static final Pattern FETCH_DESCENDANTS_OPTION_PATTERN = Pattern.compile("^$|^all$|^none$|^[0-9]+$|^-1$"); private final int depth; + private final String optionName; + /** * Has next depth. * @@ -85,6 +94,11 @@ public class FetchDescendantsOption { } } + @Override + public String toString() { + return optionName; + } + private static void validateFetchDescendantsOption(final String fetchDescendantsOptionAsString) { if (Strings.isNullOrEmpty(fetchDescendantsOptionAsString)) { return; diff --git a/cps-service/src/main/java/org/onap/cps/spi/exceptions/DataNodeNotFoundExceptionBatch.java b/cps-service/src/main/java/org/onap/cps/spi/exceptions/DataNodeNotFoundExceptionBatch.java new file mode 100644 index 0000000000..f38c41b407 --- /dev/null +++ b/cps-service/src/main/java/org/onap/cps/spi/exceptions/DataNodeNotFoundExceptionBatch.java @@ -0,0 +1,38 @@ +/* + * ============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========================================================= + */ + +package org.onap.cps.spi.exceptions; + +import java.util.Collection; +import lombok.Getter; + +@SuppressWarnings("squid:S110") // Team agreed to accept 6 levels of inheritance for CPS Exceptions +public class DataNodeNotFoundExceptionBatch extends DataNodeNotFoundException { + + @Getter + private final Collection<String> notFoundXpaths; + + public DataNodeNotFoundExceptionBatch(final String dataspaceName, final String anchorName, + final Collection<String> notFoundXpaths) { + super(dataspaceName, anchorName); + this.notFoundXpaths = notFoundXpaths; + } + +} 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 e7d4e4ddb1..4e0349d2b8 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 @@ -1,6 +1,6 @@ /* * ============LICENSE_START======================================================= - * Copyright (C) 2020-2022 Nordix Foundation + * Copyright (C) 2020-2023 Nordix Foundation * Modifications Copyright (C) 2020-2022 Bell Canada. * Modifications Copyright (C) 2021 Pantheon.tech * Modifications Copyright (C) 2022 TechMahindra Ltd. @@ -79,6 +79,19 @@ class CpsAdminServiceImplSpec extends Specification { 1 * mockCpsValidator.validateNameCharacters('someDataspace', 'someSchemaSet') } + def 'Retrieve all anchors for multiple schema-sets.'() { + given: 'that anchor is associated with the dataspace and schemasets' + def anchors = [new Anchor(), new Anchor()] + mockCpsAdminPersistenceService.getAnchors('someDataspace', _ as Collection<String>) >> anchors + when: 'get anchors is called for a dataspace name and schema set names' + def result = objectUnderTest.getAnchors('someDataspace', ['schemaSet1', 'schemaSet2']) + then: 'the collection provided by persistence service is returned as result' + result == anchors + and: 'the CpsValidator is called on the dataspace name and schema-set names' + 1 * mockCpsValidator.validateNameCharacters('someDataspace') + 1 * mockCpsValidator.validateNameCharacters(_) + } + def 'Retrieve anchor for dataspace and provided anchor name.'() { given: 'that anchor name is associated with the dataspace' Anchor anchor = new Anchor() @@ -118,6 +131,18 @@ class CpsAdminServiceImplSpec extends Specification { 1 * mockCpsValidator.validateNameCharacters('someDataspace', 'someAnchor') } + def 'Delete multiple anchors.'() { + when: 'delete anchors is invoked' + objectUnderTest.deleteAnchors('someDataspace', ['anchor1', 'anchor2']) + then: 'delete data nodes is invoked on the data service with expected parameters' + 1 * mockCpsDataService.deleteDataNodes('someDataspace', _ as Collection<String>, _ as OffsetDateTime) + and: 'the persistence service method is invoked with same parameters to delete anchor' + 1 * mockCpsAdminPersistenceService.deleteAnchors('someDataspace',_ as Collection<String>) + and: 'the CpsValidator is called on the dataspace name and anchor names' + 1 * mockCpsValidator.validateNameCharacters('someDataspace') + 1 * mockCpsValidator.validateNameCharacters(_) + } + def 'Query all anchor identifiers for a dataspace and module names.'() { given: 'the persistence service is invoked with the expected parameters and returns a list of anchors' mockCpsAdminPersistenceService.queryAnchors('some-dataspace-name', ['some-module-name']) >> [new Anchor(name:'some-anchor-identifier')] diff --git a/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsDataServiceImplSpec.groovy b/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsDataServiceImplSpec.groovy index 8bbf4e5715..e304d28d8a 100644 --- a/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsDataServiceImplSpec.groovy +++ b/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsDataServiceImplSpec.groovy @@ -3,7 +3,7 @@ * Copyright (C) 2021-2023 Nordix Foundation * Modifications Copyright (C) 2021 Pantheon.tech * Modifications Copyright (C) 2021-2022 Bell Canada. - * Modifications Copyright (C) 2022 TechMahindra Ltd. + * Modifications Copyright (C) 2022-2023 TechMahindra Ltd. * Modifications Copyright (C) 2022 Deutsche Telekom AG * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -184,13 +184,27 @@ class CpsDataServiceImplSpec extends Specification { thrown(DataValidationException) } - def 'Get data node with option #fetchDescendantsOption.'() { - def xpath = '/xpath' - def dataNode = new DataNodeBuilder().withXpath(xpath).build() + def 'Get all data nodes #scenario.'() { + given: 'persistence service returns data for GET request' + mockCpsDataPersistenceService.getDataNodes(dataspaceName, anchorName, xpath, fetchDescendantsOption) >> dataNode + expect: 'service returns same data if using same parameters' + objectUnderTest.getDataNodes(dataspaceName, anchorName, xpath, fetchDescendantsOption) == dataNode + where: 'following parameters were used' + scenario | xpath | fetchDescendantsOption | dataNode + 'with root node xpath and descendants' | '/' | FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS | [new DataNodeBuilder().withXpath('/xpath-1').build(), new DataNodeBuilder().withXpath('/xpath-2').build()] + 'with root node xpath and no descendants' | '/' | FetchDescendantsOption.OMIT_DESCENDANTS | [new DataNodeBuilder().withXpath('/xpath-1').build(), new DataNodeBuilder().withXpath('/xpath-2').build()] + 'with valid xpath and descendants' | '/xpath'| FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS | [new DataNodeBuilder().withXpath('/xpath').build()] + 'with valid xpath and no descendants' | '/xpath'| FetchDescendantsOption.OMIT_DESCENDANTS | [new DataNodeBuilder().withXpath('/xpath').build()] + } + + def 'Get all data nodes over multiple xpaths with option #fetchDescendantsOption.'() { + def xpath1 = '/xpath-1' + def xpath2 = '/xpath-2' + def dataNode = [new DataNodeBuilder().withXpath(xpath1).build(), new DataNodeBuilder().withXpath(xpath2).build()] given: 'persistence service returns data for get data request' - mockCpsDataPersistenceService.getDataNode(dataspaceName, anchorName, xpath, fetchDescendantsOption) >> dataNode + mockCpsDataPersistenceService.getDataNodesForMultipleXpaths(dataspaceName, anchorName, [xpath1, xpath2], fetchDescendantsOption) >> dataNode expect: 'service returns same data if uses same parameters' - objectUnderTest.getDataNode(dataspaceName, anchorName, xpath, fetchDescendantsOption) == dataNode + objectUnderTest.getDataNodesForMultipleXpaths(dataspaceName, anchorName, [xpath1, xpath2], fetchDescendantsOption) == dataNode where: 'all fetch options are supported' fetchDescendantsOption << [FetchDescendantsOption.OMIT_DESCENDANTS, FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS] } @@ -364,6 +378,19 @@ class CpsDataServiceImplSpec extends Specification { 1 * mockCpsDataPersistenceService.deleteDataNodes(dataspaceName, anchorName) } + def 'Delete all data nodes for given dataspace and multiple anchors.'() { + given: 'schema set for given anchors and dataspace references test tree model' + setupSchemaSetMocks('test-tree.yang') + when: 'delete data node method is invoked with correct parameters' + objectUnderTest.deleteDataNodes(dataspaceName, ['anchor1', 'anchor2'], observedTimestamp) + then: 'data updated events are sent to notification service before the delete' + 2 * mockNotificationService.processDataUpdatedEvent(dataspaceName, _, '/', Operation.DELETE, observedTimestamp) + and: 'the CpsValidator is called on the dataspace name and the anchor names' + 2 * mockCpsValidator.validateNameCharacters(_) + and: 'the persistence service method is invoked with the correct parameters' + 1 * mockCpsDataPersistenceService.deleteDataNodes(dataspaceName, _ as Collection<String>) + } + def setupSchemaSetMocks(String... yangResources) { def mockYangTextSchemaSourceSet = Mock(YangTextSchemaSourceSet) mockYangTextSchemaSourceSetCache.get(dataspaceName, schemaSetName) >> mockYangTextSchemaSourceSet @@ -404,4 +431,4 @@ class CpsDataServiceImplSpec extends Specification { 1 * mockCpsDataPersistenceService.lockAnchor('some-sessionId', 'some-dataspaceName', 'some-anchorName', 250L) } -} +}
\ No newline at end of file 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 615d3af35a..3884eda661 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 @@ -169,12 +169,11 @@ class CpsModuleServiceImplSpec extends Specification { def 'Delete multiple schema-sets when cascade is allowed.'() { given: '#numberOfAnchors anchors are associated with each schemaset' - mockCpsAdminService.getAnchors('my-dataspace', 'my-schemaset1') >> createAnchors(numberOfAnchors) - mockCpsAdminService.getAnchors('my-dataspace', 'my-schemaset2') >> createAnchors(numberOfAnchors) + mockCpsAdminService.getAnchors('my-dataspace', ['my-schemaset1', 'my-schemaset2']) >> createAnchors(numberOfAnchors * 2) when: 'schema set deletion is requested with cascade allowed' objectUnderTest.deleteSchemaSetsWithCascade('my-dataspace', ['my-schemaset1', 'my-schemaset2']) - then: 'anchor deletion is called 2 * #numberOfAnchors times' - (2 * numberOfAnchors) * mockCpsAdminService.deleteAnchor('my-dataspace', _) + then: 'anchor deletion is called #numberOfAnchors times' + mockCpsAdminService.deleteAnchors('my-dataspace', _) and: 'persistence service method is invoked with same parameters' mockCpsModulePersistenceService.deleteSchemaSets('my-dataspace', _) and: 'schema sets will be removed from the cache' diff --git a/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsQueryServiceImplSpec.groovy b/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsQueryServiceImplSpec.groovy index 60286b6643..56c43d1633 100644 --- a/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsQueryServiceImplSpec.groovy +++ b/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsQueryServiceImplSpec.groovy @@ -1,6 +1,6 @@ /* * ============LICENSE_START======================================================= - * Copyright (C) 2021-2022 Nordix Foundation + * Copyright (C) 2021-2023 Nordix Foundation * Modifications Copyright (C) 2023 TechMahindra Ltd. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); @@ -45,7 +45,7 @@ class CpsQueryServiceImplSpec extends Specification { 1 * mockCpsValidator.validateNameCharacters(dataspaceName, anchorName) where: 'all fetch descendants options are supported' fetchDescendantsOption << [FetchDescendantsOption.OMIT_DESCENDANTS, FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS, - FetchDescendantsOption.FETCH_DIRECT_CHILDREN_ONLY, new FetchDescendantsOption(10)] + FetchDescendantsOption.DIRECT_CHILDREN_ONLY, new FetchDescendantsOption(10)] } } diff --git a/cps-service/src/test/groovy/org/onap/cps/notification/CpsDataUpdateEventFactorySpec.groovy b/cps-service/src/test/groovy/org/onap/cps/notification/CpsDataUpdateEventFactorySpec.groovy index 6f9a148eb2..5dbc2bb04b 100644 --- a/cps-service/src/test/groovy/org/onap/cps/notification/CpsDataUpdateEventFactorySpec.groovy +++ b/cps-service/src/test/groovy/org/onap/cps/notification/CpsDataUpdateEventFactorySpec.groovy @@ -2,6 +2,7 @@ * ============LICENSE_START======================================================= * Copyright (c) 2021-2022 Bell Canada. * Modifications Copyright (c) 2022 Nordix Foundation + * Modifications Copyright (C) 2023 TechMahindra Ltd. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -50,8 +51,8 @@ class CpsDataUpdateEventFactorySpec extends Specification { and: 'cps data service returns the data node details' def xpath = '/xpath' def dataNode = new DataNodeBuilder().withXpath(xpath).withLeaves(['leafName': 'leafValue']).build() - mockCpsDataService.getDataNode( - 'my-dataspace', 'my-anchorname', '/', FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) >> dataNode + mockCpsDataService.getDataNodes( + 'my-dataspace', 'my-anchorname', '/', FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) >> [dataNode] when: 'CPS data updated event is created' def cpsDataUpdatedEvent = objectUnderTest.createCpsDataUpdatedEvent(anchor, DateTimeUtility.toOffsetDateTime(inputObservedTimestamp), Operation.CREATE) diff --git a/cps-service/src/test/groovy/org/onap/cps/spi/FetchDescendantsOptionSpec.groovy b/cps-service/src/test/groovy/org/onap/cps/spi/FetchDescendantsOptionSpec.groovy index c4d3dd8b7b..24f3487d17 100644 --- a/cps-service/src/test/groovy/org/onap/cps/spi/FetchDescendantsOptionSpec.groovy +++ b/cps-service/src/test/groovy/org/onap/cps/spi/FetchDescendantsOptionSpec.groovy @@ -1,6 +1,6 @@ /* * ============LICENSE_START======================================================= - * Copyright (C) 2022 Nordix Foundation + * Copyright (C) 2022-2023 Nordix Foundation * Modifications Copyright (C) 2023 TechMahindra Ltd. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); @@ -21,15 +21,15 @@ package org.onap.cps.spi -import org.onap.cps.spi.exceptions.DataValidationException import spock.lang.Specification class FetchDescendantsOptionSpec extends Specification { - def 'Check has next descendant for fetch descendant option: #scenario'() { + + def 'Has next descendant for fetch descendant option: #scenario'() { when: 'fetch descendant option with #depth depth' def fetchDescendantsOption = new FetchDescendantsOption(depth) then: 'next level descendants available: #expectedHasNext' - fetchDescendantsOption.hasNext() == expectedHasNext + assert fetchDescendantsOption.hasNext() == expectedHasNext where: 'following parameters are used' scenario | depth || expectedHasNext 'omit descendants' | 0 || false @@ -38,7 +38,7 @@ class FetchDescendantsOptionSpec extends Specification { 'include all descendants' | -1 || true } - def 'Check has next descendant for fetch descendant option: invalid depth'() { + def 'Has next descendant for fetch descendant option: invalid depth'() { given: 'fetch descendant option with -2 depth' def fetchDescendantsOption = new FetchDescendantsOption(-2) when: 'next level descendants not available' @@ -47,7 +47,7 @@ class FetchDescendantsOptionSpec extends Specification { thrown IllegalArgumentException } - def 'Get next descendant for fetch descendant option: #scenario'() { + def 'Next descendant for fetch descendant option: #scenario.'() { when: 'fetch descendant option with #depth depth' def fetchDescendantsOption = new FetchDescendantsOption(depth) then: 'the next level of depth is as expected' @@ -58,14 +58,14 @@ class FetchDescendantsOptionSpec extends Specification { 'second child' | 2 } - def 'Get next descendant for fetch descendant option: include all descendants'() { + def 'Next descendant for fetch descendant option: include all descendants.'() { when: 'fetch descendant option with -1 depth' def fetchDescendantsOption = new FetchDescendantsOption(-1) then: 'the next level of depth is as expected' fetchDescendantsOption.next().depth == -1 } - def 'Get next descendant for fetch descendant option: omit descendants'() { + def 'Next descendant for fetch descendant option: omit descendants.'() { given: 'fetch descendant option with 0 depth' def fetchDescendantsOption = new FetchDescendantsOption(0) when: 'the next level of depth is not allowed' @@ -74,7 +74,7 @@ class FetchDescendantsOptionSpec extends Specification { thrown IllegalArgumentException } - def 'Create fetch descendant option with descendant using #scenario'() { + def 'Create fetch descendant option with descendant using #scenario.'() { when: 'the next level of depth is not allowed' def FetchDescendantsOption fetchDescendantsOption = FetchDescendantsOption.getFetchDescendantsOption(fetchDescendantsOptionAsString) then: 'fetch descendant object created' @@ -87,4 +87,16 @@ class FetchDescendantsOptionSpec extends Specification { 'No descendants using none' | 'none' || 0 'til 10th descendants using number' | '10' || 10 } + + def 'String values.'() { + expect: 'each fetch descendant option has the correct String value' + assert fetchDescendantsOption.toString() == expectedStringValue + where: 'the following option is used' + fetchDescendantsOption || expectedStringValue + FetchDescendantsOption.OMIT_DESCENDANTS || 'OmitDescendants' + FetchDescendantsOption.DIRECT_CHILDREN_ONLY || 'DirectChildrenOnly' + FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS || 'IncludeAllDescendants' + new FetchDescendantsOption(2) || 'Depth=2' + } + } |