diff options
author | danielhanrahan <daniel.hanrahan@est.tech> | 2023-02-15 19:00:37 +0000 |
---|---|---|
committer | danielhanrahan <daniel.hanrahan@est.tech> | 2023-02-16 12:05:02 +0000 |
commit | fbb79a0a112da3b05989fdc3a8e88c5865f3cc9a (patch) | |
tree | c67557b80e46c8133fc70c254cf0f84e81fcbe11 /cps-service/src | |
parent | e28b62148676d189bdd11b78d8d78419d548e358 (diff) |
Improve batch delete schemasets performance
- Bulk delete anchors and datanodes associated with schemasets.
Improves de-registration performance by approx 10%
Issue-ID: CPS-1423
Signed-off-by: danielhanrahan <daniel.hanrahan@est.tech>
Change-Id: Ie38e8b4c64356bf5935d8c7a5d3f5bfa73fb1714
Diffstat (limited to 'cps-service/src')
10 files changed, 131 insertions, 17 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..07da5773d8 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 @@ -228,6 +228,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..59de411397 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 @@ -272,8 +272,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 +282,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/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..fe9cf2f698 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 @@ -191,6 +191,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/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..69b0c94f45 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 @@ -364,6 +364,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 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' |