From 926d40875fecb3c11e4103dfdaf00ac615de3cdc Mon Sep 17 00:00:00 2001 From: danielhanrahan Date: Fri, 4 Aug 2023 11:22:43 +0100 Subject: Remove inefficient saveListElementsBatch API CpsDataService::saveListElementsBatch method is not needed as saveListElements supports saving multiple list elements in a single operation. This both simplifies implementation and greatly improves performance when saving list elements, as the Yang parser need only run once for the whole batch. - Change InventoryPersistence to save CM-handles in batches of 100 using existing CpsDataService::saveListElements method. - Remove not needed CpsDataService::saveListElementBatch. Issue-ID: CPS-2019 Signed-off-by: danielhanrahan Change-Id: I8b74dda2917e094d064b42f2c0e4d57029b90395 --- .../CpsDataServiceIntegrationSpec.groovy | 20 +++++++--------- .../performance/cps/WritePerfTest.groovy | 28 ---------------------- 2 files changed, 9 insertions(+), 39 deletions(-) (limited to 'integration-test') diff --git a/integration-test/src/test/groovy/org/onap/cps/integration/functional/CpsDataServiceIntegrationSpec.groovy b/integration-test/src/test/groovy/org/onap/cps/integration/functional/CpsDataServiceIntegrationSpec.groovy index b107a87e8..e14309994 100644 --- a/integration-test/src/test/groovy/org/onap/cps/integration/functional/CpsDataServiceIntegrationSpec.groovy +++ b/integration-test/src/test/groovy/org/onap/cps/integration/functional/CpsDataServiceIntegrationSpec.groovy @@ -1,6 +1,6 @@ /* * ============LICENSE_START======================================================= - * Copyright (C) 2023 Nordix Foundation + * Copyright (C) 2023-2024 Nordix Foundation * Modifications Copyright (C) 2023 TechMahindra Ltd. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the 'License'); @@ -276,12 +276,11 @@ class CpsDataServiceIntegrationSpec extends FunctionalSpecBase { assert originalCountBookstoreChildNodes == countDataNodesInBookstore() } - def 'Add and Delete a batch of lists (element) data nodes.'() { - given: 'two new (categories) data nodes in two separate batches' - def json1 = '{"categories": [ {"code":"new1"} ] }' - def json2 = '{"categories": [ {"code":"new2"} ] } ' + def 'Add and Delete a batch of list element data nodes.'() { + given: 'two new (categories) data nodes in a single batch' + def json = '{"categories": [ {"code":"new1"}, {"code":"new2"} ] }' when: 'the batches of new list element(s) are saved' - objectUnderTest.saveListElementsBatch(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_ANCHOR_1 , '/bookstore', [json1, json2], now) + objectUnderTest.saveListElements(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_ANCHOR_1 , '/bookstore', json, now) then: 'they can be retrieved by their xpaths' assert objectUnderTest.getDataNodes(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_ANCHOR_1, '/bookstore/categories[@code="new1"]', DIRECT_CHILDREN_ONLY).size() == 1 assert objectUnderTest.getDataNodes(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_ANCHOR_1, '/bookstore/categories[@code="new2"]', DIRECT_CHILDREN_ONLY).size() == 1 @@ -294,12 +293,11 @@ class CpsDataServiceIntegrationSpec extends FunctionalSpecBase { assert originalCountBookstoreChildNodes == countDataNodesInBookstore() } - def 'Add and Delete a batch of lists (element) data nodes with partial success.'() { - given: 'two new (categories) data nodes in two separate batches' - def jsonNewElement = '{"categories": [ {"code":"new1"} ] }' - def jsonExistingElement = '{"categories": [ {"code":"1"} ] } ' + def 'Add and Delete a batch of list element data nodes with partial success.'() { + given: 'one existing and one new (categories) data nodes in a single batch' + def json = '{"categories": [ {"code":"new1"}, {"code":"1"} ] }' when: 'the batches of new list element(s) are saved' - objectUnderTest.saveListElementsBatch(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_ANCHOR_1 , '/bookstore', [jsonNewElement, jsonExistingElement], now) + objectUnderTest.saveListElements(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_ANCHOR_1 , '/bookstore', json, now) then: 'an already defined (batch) exception is thrown for the existing path' def exceptionThrown = thrown(AlreadyDefinedException) assert exceptionThrown.alreadyDefinedObjectNames == ['/bookstore/categories[@code=\'1\']' ] as Set diff --git a/integration-test/src/test/groovy/org/onap/cps/integration/performance/cps/WritePerfTest.groovy b/integration-test/src/test/groovy/org/onap/cps/integration/performance/cps/WritePerfTest.groovy index a5669baf6..1898f436b 100644 --- a/integration-test/src/test/groovy/org/onap/cps/integration/performance/cps/WritePerfTest.groovy +++ b/integration-test/src/test/groovy/org/onap/cps/integration/performance/cps/WritePerfTest.groovy @@ -106,32 +106,4 @@ class WritePerfTest extends CpsPerfTestBase { 400 || 28 | 250 } - def 'Writing openroadm list data using saveListElementsBatch.'() { - given: 'an anchor and empty container node for openroadm' - cpsAnchorService.createAnchor(CPS_PERFORMANCE_TEST_DATASPACE, LARGE_SCHEMA_SET, WRITE_TEST_ANCHOR) - cpsDataService.saveData(CPS_PERFORMANCE_TEST_DATASPACE, WRITE_TEST_ANCHOR, - '{ "openroadm-devices": { "openroadm-device": []}}', now) - and: 'a list of device nodes to add' - def innerNode = readResourceDataFile('openroadm/innerNode.json') - def multipleJsonData = (1..totalNodes).collect { - '{ "openroadm-device": [' + innerNode.replace('NODE_ID_HERE', it.toString()) + ']}' } - when: 'device nodes are added' - resourceMeter.start() - cpsDataService.saveListElementsBatch(CPS_PERFORMANCE_TEST_DATASPACE, WRITE_TEST_ANCHOR, '/openroadm-devices', multipleJsonData, OffsetDateTime.now()) - resourceMeter.stop() - then: 'the operation takes less than #expectedDuration and memory used is within limit' - recordAndAssertResourceUsage("Saving batch of ${totalNodes} lists", - expectedDuration, resourceMeter.getTotalTimeInSeconds(), - memoryLimit, resourceMeter.getTotalMemoryUsageInMB()) - cleanup: - cpsDataService.deleteDataNodes(CPS_PERFORMANCE_TEST_DATASPACE, WRITE_TEST_ANCHOR, OffsetDateTime.now()) - cpsAnchorService.deleteAnchor(CPS_PERFORMANCE_TEST_DATASPACE, WRITE_TEST_ANCHOR) - where: - totalNodes || expectedDuration | memoryLimit - 50 || 16 | 500 - 100 || 32 | 500 - 200 || 64 | 1000 - 400 || 128 | 1250 - } - } -- cgit 1.2.3-korg