From 94a1c866d930309a01869bfbf5c3cae706e32d40 Mon Sep 17 00:00:00 2001 From: emaclee Date: Thu, 11 Jul 2024 11:50:08 +0100 Subject: Delete Subscription method Issue-ID: CPS-2253 Change-Id: I30768dc431e13d0bac0dcc7b9b16cb0854f06702 Signed-off-by: emaclee --- .../cache/DmiCacheHandlerSpec.groovy | 29 +++++++-- .../dmi/DmiOutEventConsumerSpec.groovy | 2 +- .../ncmp/CmSubscriptionHandlerImplSpec.groovy | 70 +++++++++++++++------- .../ncmp/NcmpInEventConsumerSpec.groovy | 2 +- .../CmSubscriptionPersistenceServiceSpec.groovy | 13 ++++ 5 files changed, 86 insertions(+), 30 deletions(-) (limited to 'cps-ncmp-service/src/test/groovy') diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/cmnotificationsubscription/cache/DmiCacheHandlerSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/cmnotificationsubscription/cache/DmiCacheHandlerSpec.groovy index 2d50e770dd..791a154608 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/cmnotificationsubscription/cache/DmiCacheHandlerSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/cmnotificationsubscription/cache/DmiCacheHandlerSpec.groovy @@ -65,17 +65,34 @@ class DmiCacheHandlerSpec extends MessagingBaseSpec { initialiseMockInventoryPersistenceResponses() } - def 'Load CM subscription event to cache'() { - given: 'a valid subscription event with Id' + def 'Load CM subscription event to cache with predicates'() { + given: 'a subscription event with id' def subscriptionId = ncmpInEvent.getData().getSubscriptionId() and: 'list of predicates' def predicates = ncmpInEvent.getData().getPredicates() - when: 'a valid event object loaded in cache' + when: 'subscription is loaded to cache with predicates' objectUnderTest.add(subscriptionId, predicates) - then: 'the cache contains the correct entry with #subscriptionId subscription ID' + then: 'the number of entries in cache is correct' + assert testCache.size() == 1 + and: 'the cache contains the correct entries' assert testCache.containsKey(subscriptionId) } + def 'Load CM subscription event to cache with dmi subscription details per dmi'() { + given: 'a subscription event with id' + def subscriptionId = ncmpInEvent.getData().getSubscriptionId() + and: 'dmi subscription details per dmi' + def dmiSubscriptionsPerDmi = [:] + when: 'subscription is loaded to cache with dmi subscription details per dmi' + objectUnderTest.add(subscriptionId, dmiSubscriptionsPerDmi) + then: 'the number of entries in cache is correct' + assert testCache.size() == 1 + and: 'the cache contains the correct entries' + assert testCache.containsKey(subscriptionId) + and: 'the entry for the subscription ID matches the provided DMI subscription details' + assert testCache.get(subscriptionId) == dmiSubscriptionsPerDmi + } + def 'Get cache entry via subscription id'() { given: 'the cache contains value for some-id' testCache.put('some-id',[:]) @@ -157,7 +174,7 @@ class DmiCacheHandlerSpec extends MessagingBaseSpec { def subscriptionId = ncmpInEvent.getData().getSubscriptionId() objectUnderTest.add(subscriptionId, predicates) when: 'subscription status per dmi is updated in cache' - objectUnderTest.updateDmiSubscriptionStatusPerDmi(subscriptionId,'dmi-1', CmSubscriptionStatus.ACCEPTED) + objectUnderTest.updateDmiSubscriptionStatus(subscriptionId,'dmi-1', CmSubscriptionStatus.ACCEPTED) then: 'verify status has been updated in cache' def predicate = testCache.get(subscriptionId) assert predicate.get('dmi-1').cmSubscriptionStatus == CmSubscriptionStatus.ACCEPTED @@ -180,7 +197,7 @@ class DmiCacheHandlerSpec extends MessagingBaseSpec { def subscriptionId = ncmpInEvent.getData().getSubscriptionId() objectUnderTest.add(subscriptionId, predicates) when: 'subscription is persisted in database' - objectUnderTest.removeFromDatabasePerDmi(subscriptionId,'dmi-1') + objectUnderTest.removeFromDatabase(subscriptionId,'dmi-1') then: 'persistence service is called the correct number of times per dmi' 4 * mockCmSubscriptionPersistenceService.removeCmSubscription(_,_,_,subscriptionId) } diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/cmnotificationsubscription/dmi/DmiOutEventConsumerSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/cmnotificationsubscription/dmi/DmiOutEventConsumerSpec.groovy index 6e28d14810..bcf8780873 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/cmnotificationsubscription/dmi/DmiOutEventConsumerSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/cmnotificationsubscription/dmi/DmiOutEventConsumerSpec.groovy @@ -103,7 +103,7 @@ class DmiOutEventConsumerSpec extends MessagingBaseSpec { when: 'the event is consumed' objectUnderTest.consumeDmiOutEvent(consumerRecord) then: 'correct number of calls to cache' - expectedCacheCalls * mockDmiCacheHandler.updateDmiSubscriptionStatusPerDmi('sub-1','test-dmi-plugin-name', subscriptionStatus) + expectedCacheCalls * mockDmiCacheHandler.updateDmiSubscriptionStatus('sub-1','test-dmi-plugin-name', subscriptionStatus) and: 'correct number of calls to persist cache' expectedPersistenceCalls * mockDmiCacheHandler.persistIntoDatabasePerDmi('sub-1','test-dmi-plugin-name') and: 'correct number of calls to map the ncmp out event' diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/cmnotificationsubscription/ncmp/CmSubscriptionHandlerImplSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/cmnotificationsubscription/ncmp/CmSubscriptionHandlerImplSpec.groovy index 3f6556d47e..f902c60482 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/cmnotificationsubscription/ncmp/CmSubscriptionHandlerImplSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/cmnotificationsubscription/ncmp/CmSubscriptionHandlerImplSpec.groovy @@ -22,6 +22,7 @@ package org.onap.cps.ncmp.impl.cmnotificationsubscription.ncmp import com.fasterxml.jackson.databind.ObjectMapper import org.onap.cps.ncmp.impl.cmnotificationsubscription.cache.DmiCacheHandler +import org.onap.cps.ncmp.impl.cmnotificationsubscription.dmi.DmiCmSubscriptionDetailsPerDmiMapper import org.onap.cps.ncmp.impl.cmnotificationsubscription.dmi.DmiInEventMapper import org.onap.cps.ncmp.impl.cmnotificationsubscription.dmi.DmiInEventProducer import org.onap.cps.ncmp.impl.cmnotificationsubscription.models.DmiCmSubscriptionDetails @@ -30,7 +31,10 @@ import org.onap.cps.ncmp.impl.cmnotificationsubscription.utils.CmSubscriptionPer import org.onap.cps.ncmp.impl.cmnotificationsubscription_1_0_0.client_to_ncmp.NcmpInEvent import org.onap.cps.ncmp.impl.cmnotificationsubscription_1_0_0.ncmp_to_client.NcmpOutEvent import org.onap.cps.ncmp.impl.cmnotificationsubscription_1_0_0.ncmp_to_dmi.DmiInEvent +import org.onap.cps.ncmp.impl.inventory.InventoryPersistence +import org.onap.cps.ncmp.impl.inventory.models.YangModelCmHandle import org.onap.cps.ncmp.utils.TestUtils +import org.onap.cps.spi.model.DataNode import org.onap.cps.utils.JsonObjectMapper import spock.lang.Specification @@ -45,13 +49,15 @@ class CmSubscriptionHandlerImplSpec extends Specification { def mockCmSubscriptionComparator = Mock(CmSubscriptionComparator) def mockNcmpOutEventMapper = Mock(NcmpOutEventMapper) def mockDmiInEventMapper = Mock(DmiInEventMapper) + def dmiCmSubscriptionDetailsPerDmiMapper = new DmiCmSubscriptionDetailsPerDmiMapper() def mockNcmpOutEventProducer = Mock(NcmpOutEventProducer) def mockDmiInEventProducer = Mock(DmiInEventProducer) def mockDmiCacheHandler = Mock(DmiCacheHandler) + def mockInventoryPersistence = Mock(InventoryPersistence) def objectUnderTest = new CmSubscriptionHandlerImpl(mockCmSubscriptionPersistenceService, - mockCmSubscriptionComparator, mockNcmpOutEventMapper, mockDmiInEventMapper, - mockNcmpOutEventProducer, mockDmiInEventProducer, mockDmiCacheHandler) + mockCmSubscriptionComparator, mockNcmpOutEventMapper, mockDmiInEventMapper, dmiCmSubscriptionDetailsPerDmiMapper, + mockNcmpOutEventProducer, mockDmiInEventProducer, mockDmiCacheHandler, mockInventoryPersistence) def testDmiSubscriptionsPerDmi = ["dmi-1": new DmiCmSubscriptionDetails([], PENDING)] @@ -97,7 +103,7 @@ class CmSubscriptionHandlerImplSpec extends Specification { then: 'the subscription cache handler is called once' 1 * mockDmiCacheHandler.add('test-id', _) and: 'the subscription details are updated in the cache' - 1 * mockDmiCacheHandler.updateDmiSubscriptionStatusPerDmi('test-id', _, ACCEPTED) + 1 * mockDmiCacheHandler.updateDmiSubscriptionStatus('test-id', _, ACCEPTED) and: 'we schedule to send the response after configured time from the cache' 1 * mockNcmpOutEventProducer.publishNcmpOutEvent('test-id', 'subscriptionCreateResponse', null, true) } @@ -123,24 +129,44 @@ class CmSubscriptionHandlerImplSpec extends Specification { } def 'Consume valid CmNotificationSubscriptionNcmpInEvent delete message'() { - given: 'a cmNotificationSubscriptionNcmp in event for delete' - def jsonData = TestUtils.getResourceFileContent('cmSubscription/cmNotificationSubscriptionNcmpInEvent.json') - def testEventConsumed = jsonObjectMapper.convertJsonString(jsonData, NcmpInEvent.class) - and: 'relevant details is extracted from the event' - def subscriptionId = testEventConsumed.getData().getSubscriptionId() - def predicates = testEventConsumed.getData().getPredicates() - and: 'the cache handler returns for relevant subscription id' - 1 * mockDmiCacheHandler.get('test-id') >> testDmiSubscriptionsPerDmi - when: 'the valid and unique event is consumed' - objectUnderTest.processSubscriptionDeleteRequest(subscriptionId, predicates) - then: 'the subscription cache handler is called once' - 1 * mockDmiCacheHandler.add('test-id', predicates) - and: 'the mapper handler to get DMI in event is called once' - 1 * mockDmiInEventMapper.toDmiInEvent(_) - and: 'the events handler method to publish DMI event is called correct number of times with the correct parameters' - testDmiSubscriptionsPerDmi.size() * mockDmiInEventProducer.publishDmiInEvent( - 'test-id', 'dmi-1', 'subscriptionDeleteRequest', _) - and: 'we schedule to send the response after configured time from the cache' - 1 * mockNcmpOutEventProducer.publishNcmpOutEvent('test-id', 'subscriptionDeleteResponse', null, true) + given: 'a test subscription id' + def subscriptionId = 'test-id' + and: 'the persistence service returns datanodes' + 1 * mockCmSubscriptionPersistenceService.getAllNodesForSubscriptionId(subscriptionId) >> + [new DataNode(xpath: "/datastores/datastore[@name='ncmp-datastore:passthrough-running']/cm-handles/cm-handle[@id='ch-1']/filters/filter[@xpath='x/y']", leaves: ['xpath': 'x/y', 'subscriptionIds': ['test-id']]), + new DataNode(xpath: "/datastores/datastore[@name='ncmp-datastore:passthrough-running']/cm-handles/cm-handle[@id='ch-2']/filters/filter[@xpath='y/z']", leaves: ['xpath': 'y/z', 'subscriptionIds': ['test-id']])] + and: 'the inventory persistence returns yang model cm handles' + 1 * mockInventoryPersistence.getYangModelCmHandle('ch-1') >> new YangModelCmHandle(dmiServiceName: 'dmi-1') + 1 * mockInventoryPersistence.getYangModelCmHandle('ch-2') >> new YangModelCmHandle(dmiServiceName: 'dmi-2') + when: 'the subscription delete request is processed' + objectUnderTest.processSubscriptionDeleteRequest(subscriptionId) + then: 'the method to publish a dmi event is called with correct parameters' + 1 * mockDmiInEventProducer.publishDmiInEvent(subscriptionId,'dmi-1','subscriptionDeleteRequest',_) + 1 * mockDmiInEventProducer.publishDmiInEvent(subscriptionId,'dmi-2','subscriptionDeleteRequest',_) + and: 'the method to publish nmcp out event is called with correct parameters' + 1 * mockNcmpOutEventProducer.publishNcmpOutEvent(subscriptionId, 'subscriptionDeleteResponse', null, true) + } + + def 'Delete a subscriber for fully overlapping subscriptions'() { + given: 'a test subscription id' + def subscriptionId = 'test-id' + and: 'the persistence service returns datanodes with multiple subscribers' + 1 * mockCmSubscriptionPersistenceService.getAllNodesForSubscriptionId(subscriptionId) >> + [new DataNode(xpath: "/datastores/datastore[@name='ncmp-datastore:passthrough-running']/cm-handles/cm-handle[@id='ch-1']/filters/filter[@xpath='x/y']", leaves: ['xpath': 'x/y', 'subscriptionIds': ['test-id','other-id']]), + new DataNode(xpath: "/datastores/datastore[@name='ncmp-datastore:passthrough-running']/cm-handles/cm-handle[@id='ch-2']/filters/filter[@xpath='y/z']", leaves: ['xpath': 'y/z', 'subscriptionIds': ['test-id','other-id']])] + and: 'the inventory persistence returns yang model cm handles' + 1 * mockInventoryPersistence.getYangModelCmHandle('ch-1') >> new YangModelCmHandle(dmiServiceName: 'dmi-1') + 1 * mockInventoryPersistence.getYangModelCmHandle('ch-2') >> new YangModelCmHandle(dmiServiceName: 'dmi-2') + and: 'the cache handler returns the relevant maps whenever called' + 2 * mockDmiCacheHandler.get(subscriptionId) >> ['dmi-1':[:],'dmi-2':[:]] + when: 'the subscription delete request is processed' + objectUnderTest.processSubscriptionDeleteRequest(subscriptionId) + then: 'the method to publish a dmi event is never called' + 0 * mockDmiInEventProducer.publishDmiInEvent(_,_,_,_) + and: 'the cache handler is called to remove subscriber from database per dmi' + 1 * mockDmiCacheHandler.removeFromDatabase('test-id', 'dmi-1') + 1 * mockDmiCacheHandler.removeFromDatabase('test-id', 'dmi-2') + and: 'the method to publish nmcp out event is called with correct parameters' + 1 * mockNcmpOutEventProducer.publishNcmpOutEvent(subscriptionId, 'subscriptionDeleteResponse', null, false) } } diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/cmnotificationsubscription/ncmp/NcmpInEventConsumerSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/cmnotificationsubscription/ncmp/NcmpInEventConsumerSpec.groovy index 2881737e82..9c24e2b005 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/cmnotificationsubscription/ncmp/NcmpInEventConsumerSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/cmnotificationsubscription/ncmp/NcmpInEventConsumerSpec.groovy @@ -100,7 +100,7 @@ class NcmpInEventConsumerSpec extends MessagingBaseSpec { and: 'the log indicates the task completed successfully' assert loggingEvent.formattedMessage == 'Subscription delete request for source some-resource with subscription id test-id ...' and: 'the subscription handler service is called once' - 1 * mockCmSubscriptionHandler.processSubscriptionDeleteRequest('test-id',_) + 1 * mockCmSubscriptionHandler.processSubscriptionDeleteRequest('test-id') } diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/cmnotificationsubscription/utils/CmSubscriptionPersistenceServiceSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/cmnotificationsubscription/utils/CmSubscriptionPersistenceServiceSpec.groovy index d32d143ade..354e2af937 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/cmnotificationsubscription/utils/CmSubscriptionPersistenceServiceSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/cmnotificationsubscription/utils/CmSubscriptionPersistenceServiceSpec.groovy @@ -188,4 +188,17 @@ class CmSubscriptionPersistenceServiceSpec extends Specification { 'cm handle in same datastore is NOT used for other subscriptions' | [] || 1 } + def 'Get all nodes for subscription id'() { + given: 'the query service returns nodes for subscription id' + def expectedDataNode = new DataNode(xpath: '/some/xpath') + def queryServiceResponse = [expectedDataNode].asCollection() + 1 * mockCpsQueryService.queryDataNodes('NCMP-Admin', 'cm-data-subscriptions', '//filter/subscriptionIds[text()=\'some-id\']', OMIT_DESCENDANTS) >> queryServiceResponse + when: 'retrieving all nodes for subscription id' + def result = objectUnderTest.getAllNodesForSubscriptionId('some-id') + then: 'the result returns correct number of datanodes' + assert result.size() == 1 + and: 'the attribute of the datanode is as expected' + assert result.iterator().next().xpath == expectedDataNode.xpath + } + } -- cgit 1.2.3-korg