summaryrefslogtreecommitdiffstats
path: root/cps-ncmp-service/src/test/groovy/org/onap
diff options
context:
space:
mode:
authorLuke Gleeson <luke.gleeson@est.tech>2023-07-27 10:20:54 +0000
committerGerrit Code Review <gerrit@onap.org>2023-07-27 10:20:54 +0000
commit113a61880e3188ddb45c938576f6a1ff9b309528 (patch)
tree995c957b01695a325e44edcea78fd635a7002551 /cps-ncmp-service/src/test/groovy/org/onap
parentad6c8d4483ee93405f0bdcb175bfcfe9fa0dccb3 (diff)
parentd789956fbf88f856472f975487c1975df91dbe3e (diff)
Merge "Subscription Creation: NCMP to Client CloudEvent transformation"
Diffstat (limited to 'cps-ncmp-service/src/test/groovy/org/onap')
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/avcsubscription/SubscriptionEventConsumerSpec.groovy25
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/avcsubscription/SubscriptionEventForwarderSpec.groovy35
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/avcsubscription/SubscriptionEventResponseConsumerSpec.groovy120
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/avcsubscription/SubscriptionEventResponseMapperSpec.groovy14
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/avcsubscription/SubscriptionEventResponseOutcomeSpec.groovy116
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/avcsubscription/SubscriptionOutcomeMapperSpec.groovy50
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/subscriptions/SubscriptionPersistenceSpec.groovy9
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/utils/DataNodeBaseSpec.groovy6
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/utils/DataNodeHelperSpec.groovy39
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/utils/SubscriptionEventCloudMapperSpec.groovy26
10 files changed, 248 insertions, 192 deletions
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/avcsubscription/SubscriptionEventConsumerSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/avcsubscription/SubscriptionEventConsumerSpec.groovy
index d4ab1e88ad..5f6077351d 100644
--- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/avcsubscription/SubscriptionEventConsumerSpec.groovy
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/avcsubscription/SubscriptionEventConsumerSpec.groovy
@@ -58,7 +58,7 @@ class SubscriptionEventConsumerSpec extends MessagingBaseSpec {
testEventSent.getData().getDataType().setDataCategory(dataCategory)
def testCloudEventSent = CloudEventBuilder.v1()
.withData(objectMapper.writeValueAsBytes(testEventSent))
- .withId('some-event-id')
+ .withId('subscriptionCreated')
.withType(dataType)
.withSource(URI.create('some-resource'))
.withExtension('correlationid', 'test-cmhandle1').build()
@@ -74,34 +74,35 @@ class SubscriptionEventConsumerSpec extends MessagingBaseSpec {
and: 'the event is persisted'
numberOfTimesToPersist * mockSubscriptionPersistence.saveSubscriptionEvent(yangModelSubscriptionEvent)
and: 'the event is forwarded'
- numberOfTimesToForward * mockSubscriptionEventForwarder.forwardCreateSubscriptionEvent(testEventSent)
+ numberOfTimesToForward * mockSubscriptionEventForwarder.forwardCreateSubscriptionEvent(testEventSent, 'subscriptionCreated')
where: 'given values are used'
- scenario | dataCategory | dataType | isNotificationEnabled | isModelLoaderEnabled || numberOfTimesToForward || numberOfTimesToPersist
- 'Both model loader and notification are enabled' | 'CM' | 'CREATE' | true | true || 1 || 1
- 'Both model loader and notification are disabled' | 'CM' | 'CREATE' | false | false || 0 || 0
- 'Model loader enabled and notification disabled' | 'CM' | 'CREATE' | false | true || 0 || 1
- 'Model loader disabled and notification enabled' | 'CM' | 'CREATE' | true | false || 1 || 0
- 'Flags are enabled but data category is FM' | 'FM' | 'CREATE' | true | true || 0 || 0
- 'Flags are enabled but data type is UPDATE' | 'CM' | 'UPDATE' | true | true || 0 || 1
+ scenario | dataCategory | dataType | isNotificationEnabled | isModelLoaderEnabled || numberOfTimesToForward || numberOfTimesToPersist
+ 'Both model loader and notification are enabled' | 'CM' | 'subscriptionCreated' | true | true || 1 || 1
+ 'Both model loader and notification are disabled' | 'CM' | 'subscriptionCreated' | false | false || 0 || 0
+ 'Model loader enabled and notification disabled' | 'CM' | 'subscriptionCreated' | false | true || 0 || 1
+ 'Model loader disabled and notification enabled' | 'CM' | 'subscriptionCreated' | true | false || 1 || 0
+ 'Flags are enabled but data category is FM' | 'FM' | 'subscriptionCreated' | true | true || 0 || 0
+ 'Flags are enabled but data type is UPDATE' | 'CM' | 'subscriptionUpdated' | true | true || 0 || 1
}
def 'Consume event with wrong datastore causes an exception'() {
given: 'an event'
def jsonData = TestUtils.getResourceFileContent('avcSubscriptionCreationEvent.json')
def testEventSent = jsonObjectMapper.convertJsonString(jsonData, SubscriptionEvent.class)
- and: 'datastore is set to a non passthrough datastore'
+ and: 'datastore is set to a passthrough-running datastore'
testEventSent.getData().getPredicates().setDatastore('operational')
def testCloudEventSent = CloudEventBuilder.v1()
.withData(objectMapper.writeValueAsBytes(testEventSent))
.withId('some-event-id')
- .withType('CREATE')
+ .withType('some-event-type')
.withSource(URI.create('some-resource'))
.withExtension('correlationid', 'test-cmhandle1').build()
def consumerRecord = new ConsumerRecord<String, SubscriptionEvent>('topic-name', 0, 0, 'event-key', testCloudEventSent)
when: 'the valid event is consumed'
objectUnderTest.consumeSubscriptionEvent(consumerRecord)
then: 'an operation not yet supported exception is thrown'
- thrown(OperationNotYetSupportedException)
+ def exception = thrown(OperationNotYetSupportedException)
+ exception.details == 'passthrough-running datastores are currently only supported for event subscriptions'
}
}
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/avcsubscription/SubscriptionEventForwarderSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/avcsubscription/SubscriptionEventForwarderSpec.groovy
index 2af32c20e9..4343c23c96 100644
--- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/avcsubscription/SubscriptionEventForwarderSpec.groovy
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/avcsubscription/SubscriptionEventForwarderSpec.groovy
@@ -35,6 +35,8 @@ import org.onap.cps.ncmp.api.impl.yangmodels.YangModelSubscriptionEvent.TargetCm
import org.onap.cps.ncmp.api.inventory.InventoryPersistence
import org.onap.cps.ncmp.api.kafka.MessagingBaseSpec
import org.onap.cps.ncmp.events.avcsubscription1_0_0.client_to_ncmp.SubscriptionEvent
+import org.onap.cps.ncmp.events.avcsubscription1_0_0.dmi_to_ncmp.Data
+import org.onap.cps.ncmp.events.avcsubscription1_0_0.dmi_to_ncmp.SubscriptionEventResponse
import org.onap.cps.ncmp.events.avcsubscription1_0_0.ncmp_to_dmi.CmHandle;
import org.onap.cps.ncmp.utils.TestUtils
import org.onap.cps.spi.exceptions.OperationNotYetSupportedException
@@ -75,13 +77,6 @@ class SubscriptionEventForwarderSpec extends MessagingBaseSpec {
given: 'an event'
def jsonData = TestUtils.getResourceFileContent('avcSubscriptionCreationEvent.json')
def testEventSent = jsonObjectMapper.convertJsonString(jsonData, SubscriptionEvent.class)
- and: 'the some of the cm handles will be accepted and some of rejected'
- def cmHandlesToBeSavedInDb = [new TargetCmHandle('CMHandle1', SubscriptionStatus.ACCEPTED),
- new TargetCmHandle('CMHandle2',SubscriptionStatus.ACCEPTED),
- new TargetCmHandle('CMHandle3',SubscriptionStatus.REJECTED)]
- and: 'a yang model subscription event will be saved into the db'
- def yangModelSubscriptionEventWithAcceptedAndRejectedCmHandles = subscriptionEventMapper.toYangModelSubscriptionEvent(testEventSent)
- yangModelSubscriptionEventWithAcceptedAndRejectedCmHandles.getPredicates().setTargetCmHandles(cmHandlesToBeSavedInDb)
and: 'the InventoryPersistence returns private properties for the supplied CM Handles'
1 * mockInventoryPersistence.getYangModelCmHandles(["CMHandle1", "CMHandle2", "CMHandle3"]) >> [
createYangModelCmHandleWithDmiProperty(1, 1,"shape","circle"),
@@ -92,7 +87,7 @@ class SubscriptionEventForwarderSpec extends MessagingBaseSpec {
and: 'a Blocking Variable is used for the Asynchronous call with a timeout of 5 seconds'
def block = new BlockingVariable<Object>(5)
when: 'the valid event is forwarded'
- objectUnderTest.forwardCreateSubscriptionEvent(testEventSent)
+ objectUnderTest.forwardCreateSubscriptionEvent(testEventSent, 'subscriptionCreated')
then: 'An asynchronous call is made to the blocking variable'
block.get()
then: 'the event is added to the forwarded subscription event cache'
@@ -106,8 +101,6 @@ class SubscriptionEventForwarderSpec extends MessagingBaseSpec {
targets == [cmHandle2, cmHandle1]
}
)
- and: 'the persistence service save the yang model subscription event'
- 1 * mockSubscriptionPersistence.saveSubscriptionEvent(yangModelSubscriptionEventWithAcceptedAndRejectedCmHandles)
and: 'a separate thread has been created where the map is polled'
1 * mockForwardedSubscriptionEventCache.containsKey("SCO-9989752cm-subscription-001") >> true
1 * mockSubscriptionEventResponseOutcome.sendResponse(*_)
@@ -122,7 +115,7 @@ class SubscriptionEventForwarderSpec extends MessagingBaseSpec {
and: 'the target CMHandles are set to #scenario'
testEventSent.getData().getPredicates().setTargets(invalidTargets)
when: 'the event is forwarded'
- objectUnderTest.forwardCreateSubscriptionEvent(testEventSent)
+ objectUnderTest.forwardCreateSubscriptionEvent(testEventSent, 'some-event-type')
then: 'an operation not yet supported exception is thrown'
thrown(OperationNotYetSupportedException)
where:
@@ -136,13 +129,17 @@ class SubscriptionEventForwarderSpec extends MessagingBaseSpec {
given: 'an event'
def jsonData = TestUtils.getResourceFileContent('avcSubscriptionCreationEvent.json')
def testEventSent = jsonObjectMapper.convertJsonString(jsonData, SubscriptionEvent.class)
+ and: 'a subscription event response'
+ def emptySubscriptionEventResponse = new SubscriptionEventResponse().withData(new Data());
+ emptySubscriptionEventResponse.getData().setSubscriptionName('cm-subscription-001');
+ emptySubscriptionEventResponse.getData().setClientId('SCO-9989752');
and: 'the cm handles will be rejected'
- def rejectedCmHandles = [new TargetCmHandle('CMHandle1', SubscriptionStatus.REJECTED),
- new TargetCmHandle('CMHandle2',SubscriptionStatus.REJECTED),
- new TargetCmHandle('CMHandle3',SubscriptionStatus.REJECTED)]
+ def rejectedCmHandles = [new TargetCmHandle('CMHandle1', SubscriptionStatus.REJECTED, 'Cm handle does not exist'),
+ new TargetCmHandle('CMHandle2',SubscriptionStatus.REJECTED, 'Cm handle does not exist'),
+ new TargetCmHandle('CMHandle3',SubscriptionStatus.REJECTED, 'Cm handle does not exist')]
and: 'a yang model subscription event will be saved into the db with rejected cm handles'
- def yangModelSubscriptionEventWithRejectedCmHandles = subscriptionEventMapper.toYangModelSubscriptionEvent(testEventSent)
- yangModelSubscriptionEventWithRejectedCmHandles.getPredicates().setTargetCmHandles(rejectedCmHandles)
+ def yangModelSubscriptionEvent = subscriptionEventMapper.toYangModelSubscriptionEvent(testEventSent)
+ yangModelSubscriptionEvent.getPredicates().setTargetCmHandles(rejectedCmHandles)
and: 'the InventoryPersistence returns no private properties for the supplied CM Handles'
1 * mockInventoryPersistence.getYangModelCmHandles(["CMHandle1", "CMHandle2", "CMHandle3"]) >> []
and: 'the thread creation delay is reduced to 2 seconds for testing'
@@ -150,7 +147,7 @@ class SubscriptionEventForwarderSpec extends MessagingBaseSpec {
and: 'a Blocking Variable is used for the Asynchronous call with a timeout of 5 seconds'
def block = new BlockingVariable<Object>(5)
when: 'the valid event is forwarded'
- objectUnderTest.forwardCreateSubscriptionEvent(testEventSent)
+ objectUnderTest.forwardCreateSubscriptionEvent(testEventSent, 'subscriptionCreatedStatus')
then: 'the event is not added to the forwarded subscription event cache'
0 * mockForwardedSubscriptionEventCache.put("SCO-9989752cm-subscription-001", ["DMIName1", "DMIName2"] as Set)
and: 'the event is not being forwarded with the CMHandle private properties and does not provides a valid listenable future'
@@ -175,9 +172,9 @@ class SubscriptionEventForwarderSpec extends MessagingBaseSpec {
and: 'the subscription id is removed from the event cache map returning the asynchronous blocking variable'
0 * mockForwardedSubscriptionEventCache.remove("SCO-9989752cm-subscription-001") >> {block.set(_)}
and: 'the persistence service save target cm handles of the yang model subscription event as rejected '
- 1 * mockSubscriptionPersistence.saveSubscriptionEvent(yangModelSubscriptionEventWithRejectedCmHandles)
+ 1 * mockSubscriptionPersistence.saveSubscriptionEvent(yangModelSubscriptionEvent)
and: 'subscription outcome has been sent'
- 1 * mockSubscriptionEventResponseOutcome.sendResponse('SCO-9989752', 'cm-subscription-001')
+ 1 * mockSubscriptionEventResponseOutcome.sendResponse(emptySubscriptionEventResponse, 'subscriptionCreatedStatus')
}
static def createYangModelCmHandleWithDmiProperty(id, dmiId,propertyName, propertyValue) {
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/avcsubscription/SubscriptionEventResponseConsumerSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/avcsubscription/SubscriptionEventResponseConsumerSpec.groovy
index 5355dd8b9a..7cc40cc90e 100644
--- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/avcsubscription/SubscriptionEventResponseConsumerSpec.groovy
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/avcsubscription/SubscriptionEventResponseConsumerSpec.groovy
@@ -22,17 +22,27 @@ package org.onap.cps.ncmp.api.impl.events.avcsubscription
import com.fasterxml.jackson.databind.ObjectMapper
import com.hazelcast.map.IMap
+import io.cloudevents.CloudEvent
+import io.cloudevents.core.builder.CloudEventBuilder
import org.apache.kafka.clients.consumer.ConsumerRecord
import org.onap.cps.ncmp.api.impl.subscriptions.SubscriptionPersistenceImpl
import org.onap.cps.ncmp.api.kafka.MessagingBaseSpec
-import org.onap.cps.ncmp.api.models.SubscriptionEventResponse
+import org.onap.cps.ncmp.events.avcsubscription1_0_0.dmi_to_ncmp.SubscriptionEventResponse
+import org.onap.cps.ncmp.utils.TestUtils
import org.onap.cps.spi.model.DataNodeBuilder
import org.onap.cps.utils.JsonObjectMapper
+import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.context.SpringBootTest
@SpringBootTest(classes = [ObjectMapper, JsonObjectMapper])
class SubscriptionEventResponseConsumerSpec extends MessagingBaseSpec {
+ @Autowired
+ JsonObjectMapper jsonObjectMapper
+
+ @Autowired
+ ObjectMapper objectMapper
+
IMap<String, Set<String>> mockForwardedSubscriptionEventCache = Mock(IMap<String, Set<String>>)
def mockSubscriptionPersistence = Mock(SubscriptionPersistenceImpl)
def mockSubscriptionEventResponseMapper = Mock(SubscriptionEventResponseMapper)
@@ -41,72 +51,90 @@ class SubscriptionEventResponseConsumerSpec extends MessagingBaseSpec {
def objectUnderTest = new SubscriptionEventResponseConsumer(mockForwardedSubscriptionEventCache,
mockSubscriptionPersistence, mockSubscriptionEventResponseMapper, mockSubscriptionEventResponseOutcome)
- def cmHandleToStatusMap = [CMHandle1: 'PENDING', CMHandle2: 'ACCEPTED'] as Map
- def testEventReceived = new SubscriptionEventResponse(clientId: 'some-client-id',
- subscriptionName: 'some-subscription-name', dmiName: 'some-dmi-name', cmHandleIdToStatus: cmHandleToStatusMap)
- def consumerRecord = new ConsumerRecord<String, SubscriptionEventResponse>('topic-name', 0, 0, 'event-key', testEventReceived)
-
def 'Consume Subscription Event Response where all DMIs have responded'() {
- given: 'a subscription event response and notifications are enabled'
- objectUnderTest.notificationFeatureEnabled = isNotificationFeatureEnabled
+ given: 'a consumer record including cloud event having subscription response'
+ def consumerRecordWithCloudEventAndSubscriptionResponse = getConsumerRecord()
+ and: 'a subscription response event'
+ def subscriptionResponseEvent = getSubscriptionResponseEvent()
+ and: 'a subscription event response and notifications are enabled'
+ objectUnderTest.notificationFeatureEnabled = notificationEnabled
and: 'subscription model loader is enabled'
- objectUnderTest.subscriptionModelLoaderEnabled = true
- and: 'a data node exist in db'
- def leaves1 = [status:'ACCEPTED', cmHandleId:'cmhandle1'] as Map
- def dataNode = new DataNodeBuilder().withDataspace('NCMP-Admin')
- .withAnchor('AVC-Subscriptions').withXpath('/subscription-registry/subscription')
- .withLeaves(leaves1).build()
- and: 'subscription persistence service returns data node'
- mockSubscriptionPersistence.getCmHandlesForSubscriptionEvent(*_) >> [dataNode]
+ objectUnderTest.subscriptionModelLoaderEnabled = modelLoaderEnabled
+ and: 'subscription persistence service returns data node includes no pending cm handle'
+ mockSubscriptionPersistence.getCmHandlesForSubscriptionEvent(*_) >> [getDataNode()]
when: 'the valid event is consumed'
- objectUnderTest.consumeSubscriptionEventResponse(consumerRecord)
+ objectUnderTest.consumeSubscriptionEventResponse(consumerRecordWithCloudEventAndSubscriptionResponse)
then: 'the forwarded subscription event cache returns only the received dmiName existing for the subscription create event'
- 1 * mockForwardedSubscriptionEventCache.containsKey('some-client-idsome-subscription-name') >> true
- 1 * mockForwardedSubscriptionEventCache.get('some-client-idsome-subscription-name') >> (['some-dmi-name'] as Set)
+ 1 * mockForwardedSubscriptionEventCache.containsKey('SCO-9989752cm-subscription-001') >> true
+ 1 * mockForwardedSubscriptionEventCache.get('SCO-9989752cm-subscription-001') >> (['some-dmi-name'] as Set)
and: 'the forwarded subscription event cache returns an empty Map when the dmiName has been removed'
- 1 * mockForwardedSubscriptionEventCache.get('some-client-idsome-subscription-name') >> ([] as Set)
+ 1 * mockForwardedSubscriptionEventCache.get('SCO-9989752cm-subscription-001') >> ([] as Set)
+ and: 'the response event is map to yang model'
+ numberOfTimeToPersist * mockSubscriptionEventResponseMapper.toYangModelSubscriptionEvent(_)
+ and: 'the response event is persisted into the db'
+ numberOfTimeToPersist * mockSubscriptionPersistence.saveSubscriptionEvent(_)
and: 'the subscription event is removed from the map'
- numberOfExpectedCallToRemove * mockForwardedSubscriptionEventCache.remove('some-client-idsome-subscription-name')
+ numberOfTimeToRemove * mockForwardedSubscriptionEventCache.remove('SCO-9989752cm-subscription-001')
and: 'a response outcome has been created'
- numberOfExpectedCallToSendResponse * mockSubscriptionEventResponseOutcome.sendResponse('some-client-id', 'some-subscription-name')
+ numberOfTimeToResponse * mockSubscriptionEventResponseOutcome.sendResponse(subscriptionResponseEvent, 'subscriptionCreated')
where: 'the following values are used'
- scenario | isNotificationFeatureEnabled || numberOfExpectedCallToRemove || numberOfExpectedCallToSendResponse
- 'Response sent' | true || 1 || 1
- 'Response not sent' | false || 0 || 0
+ scenario | modelLoaderEnabled | notificationEnabled || numberOfTimeToPersist || numberOfTimeToRemove || numberOfTimeToResponse
+ 'Both model loader and notification are enabled' | true | true || 1 || 1 || 1
+ 'Both model loader and notification are disabled' | false | false || 0 || 0 || 0
+ 'Model loader enabled and notification disabled' | true | false || 1 || 0 || 0
+ 'Model loader disabled and notification enabled' | false | true || 0 || 1 || 1
}
def 'Consume Subscription Event Response where another DMI has not yet responded'() {
given: 'a subscription event response and notifications are enabled'
- objectUnderTest.notificationFeatureEnabled = true
+ objectUnderTest.notificationFeatureEnabled = notificationEnabled
and: 'subscription model loader is enabled'
- objectUnderTest.subscriptionModelLoaderEnabled = true
+ objectUnderTest.subscriptionModelLoaderEnabled = modelLoaderEnabled
when: 'the valid event is consumed'
- objectUnderTest.consumeSubscriptionEventResponse(consumerRecord)
+ objectUnderTest.consumeSubscriptionEventResponse(getConsumerRecord())
then: 'the forwarded subscription event cache returns only the received dmiName existing for the subscription create event'
- 1 * mockForwardedSubscriptionEventCache.containsKey('some-client-idsome-subscription-name') >> true
- 1 * mockForwardedSubscriptionEventCache.get('some-client-idsome-subscription-name') >> (['some-dmi-name', 'non-responded-dmi'] as Set)
+ 1 * mockForwardedSubscriptionEventCache.containsKey('SCO-9989752cm-subscription-001') >> true
+ 1 * mockForwardedSubscriptionEventCache.get('SCO-9989752cm-subscription-001') >> (['responded-dmi', 'non-responded-dmi'] as Set)
and: 'the forwarded subscription event cache returns an empty Map when the dmiName has been removed'
- 1 * mockForwardedSubscriptionEventCache.get('some-client-idsome-subscription-name') >> (['non-responded-dmi'] as Set)
+ 1 * mockForwardedSubscriptionEventCache.get('SCO-9989752cm-subscription-001') >> (['non-responded-dmi'] as Set)
+ and: 'the response event is map to yang model'
+ numberOfTimeToPersist * mockSubscriptionEventResponseMapper.toYangModelSubscriptionEvent(_)
+ and: 'the response event is persisted into the db'
+ numberOfTimeToPersist * mockSubscriptionPersistence.saveSubscriptionEvent(_)
+ and: 'the subscription event is removed from the map'
and: 'the subscription event is not removed from the map'
0 * mockForwardedSubscriptionEventCache.remove(_)
and: 'a response outcome has not been created'
0 * mockSubscriptionEventResponseOutcome.sendResponse(*_)
+ where: 'the following values are used'
+ scenario | modelLoaderEnabled | notificationEnabled || numberOfTimeToPersist
+ 'Both model loader and notification are enabled' | true | true || 1
+ 'Both model loader and notification are disabled' | false | false || 0
+ 'Model loader enabled and notification disabled' | true | false || 1
+ 'Model loader disabled and notification enabled' | false | true || 0
}
- def 'Update subscription event when the model loader flag is enabled'() {
- given: 'subscription model loader is enabled as per #scenario'
- objectUnderTest.subscriptionModelLoaderEnabled = isSubscriptionModelLoaderEnabled
- when: 'the valid event is consumed'
- objectUnderTest.consumeSubscriptionEventResponse(consumerRecord)
- then: 'the forwarded subscription event cache does not return dmiName for the subscription create event'
- 1 * mockForwardedSubscriptionEventCache.containsKey('some-client-idsome-subscription-name') >> false
- and: 'the mapper returns yang model subscription event with #numberOfExpectedCall'
- numberOfExpectedCall * mockSubscriptionEventResponseMapper.toYangModelSubscriptionEvent(_)
- and: 'subscription event has been updated into DB with #numberOfExpectedCall'
- numberOfExpectedCall * mockSubscriptionPersistence.saveSubscriptionEvent(_)
- where: 'the following values are used'
- scenario | isSubscriptionModelLoaderEnabled || numberOfExpectedCall
- 'The event is updated' | true || 1
- 'The event is not updated' | false || 0
+ def getSubscriptionResponseEvent() {
+ def subscriptionResponseJsonData = TestUtils.getResourceFileContent('avcSubscriptionEventResponse.json')
+ return jsonObjectMapper.convertJsonString(subscriptionResponseJsonData, SubscriptionEventResponse.class)
+ }
+
+ def getCloudEventHavingSubscriptionResponseEvent() {
+ return CloudEventBuilder.v1()
+ .withData(objectMapper.writeValueAsBytes(getSubscriptionResponseEvent()))
+ .withId('some-id')
+ .withType('subscriptionCreated')
+ .withSource(URI.create('NCMP')).build()
+ }
+
+ def getConsumerRecord() {
+ return new ConsumerRecord<String, CloudEvent>('topic-name', 0, 0, 'event-key', getCloudEventHavingSubscriptionResponseEvent())
+ }
+
+ def getDataNode() {
+ def leaves = [status:'ACCEPTED', cmHandleId:'cmhandle1'] as Map
+ return new DataNodeBuilder().withDataspace('NCMP-Admin')
+ .withAnchor('AVC-Subscriptions').withXpath('/subscription-registry/subscription')
+ .withLeaves(leaves).build()
}
}
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/avcsubscription/SubscriptionEventResponseMapperSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/avcsubscription/SubscriptionEventResponseMapperSpec.groovy
index 00412aa933..4c60281f85 100644
--- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/avcsubscription/SubscriptionEventResponseMapperSpec.groovy
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/avcsubscription/SubscriptionEventResponseMapperSpec.groovy
@@ -22,9 +22,8 @@ package org.onap.cps.ncmp.api.impl.events.avcsubscription
import com.fasterxml.jackson.databind.ObjectMapper
import org.mapstruct.factory.Mappers
-import org.onap.cps.ncmp.api.impl.events.avcsubscription.SubscriptionEventResponseMapper
import org.onap.cps.ncmp.api.impl.subscriptions.SubscriptionStatus
-import org.onap.cps.ncmp.api.models.SubscriptionEventResponse
+import org.onap.cps.ncmp.events.avcsubscription1_0_0.dmi_to_ncmp.SubscriptionEventResponse;
import org.onap.cps.ncmp.utils.TestUtils
import org.onap.cps.utils.JsonObjectMapper
import org.springframework.beans.factory.annotation.Autowired
@@ -50,13 +49,12 @@ class SubscriptionEventResponseMapperSpec extends Specification {
assert result.clientId == "SCO-9989752"
and: 'subscription name'
assert result.subscriptionName == "cm-subscription-001"
- and: 'predicate targets '
- assert result.predicates.targetCmHandles.cmHandleId == ["CMHandle1", "CMHandle3", "CMHandle4", "CMHandle5"]
+ and: 'predicate targets cm handle size as expected'
+ assert result.predicates.targetCmHandles.size() == 7
+ and: 'predicate targets cm handle ids as expected'
+ assert result.predicates.targetCmHandles.cmHandleId == ["CMHandle1", "CMHandle2", "CMHandle3", "CMHandle4", "CMHandle5", "CMHandle6", "CMHandle7"]
and: 'the status for these targets is set to expected values'
- assert result.predicates.targetCmHandles.status == [SubscriptionStatus.ACCEPTED, SubscriptionStatus.REJECTED,
- SubscriptionStatus.PENDING, SubscriptionStatus.PENDING]
- and: 'the topic is null'
- assert result.topic == null
+ assert result.predicates.targetCmHandles.status == [SubscriptionStatus.REJECTED, SubscriptionStatus.REJECTED, SubscriptionStatus.REJECTED, SubscriptionStatus.REJECTED, SubscriptionStatus.PENDING, SubscriptionStatus.PENDING, SubscriptionStatus.PENDING]
}
} \ No newline at end of file
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/avcsubscription/SubscriptionEventResponseOutcomeSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/avcsubscription/SubscriptionEventResponseOutcomeSpec.groovy
index bb0e7b73a0..c1c428b13f 100644
--- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/avcsubscription/SubscriptionEventResponseOutcomeSpec.groovy
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/avcsubscription/SubscriptionEventResponseOutcomeSpec.groovy
@@ -21,13 +21,16 @@
package org.onap.cps.ncmp.api.impl.events.avcsubscription
import com.fasterxml.jackson.databind.ObjectMapper
-import org.apache.kafka.common.header.internals.RecordHeaders
+import io.cloudevents.CloudEvent
+import io.cloudevents.core.builder.CloudEventBuilder
import org.mapstruct.factory.Mappers
+import org.onap.cps.ncmp.api.NcmpEventResponseCode
import org.onap.cps.ncmp.api.impl.events.EventsPublisher
import org.onap.cps.ncmp.api.impl.subscriptions.SubscriptionPersistence
-import org.onap.cps.ncmp.api.impl.subscriptions.SubscriptionStatus
import org.onap.cps.ncmp.api.impl.utils.DataNodeBaseSpec
-import org.onap.cps.ncmp.events.avc.subscription.v1.SubscriptionEventOutcome
+import org.onap.cps.ncmp.api.impl.utils.SubscriptionOutcomeCloudMapper
+import org.onap.cps.ncmp.events.avcsubscription1_0_0.dmi_to_ncmp.SubscriptionEventResponse
+import org.onap.cps.ncmp.events.avcsubscription1_0_0.ncmp_to_client.SubscriptionEventOutcome;
import org.onap.cps.ncmp.utils.TestUtils
import org.onap.cps.utils.JsonObjectMapper
import org.spockframework.spring.SpringBean
@@ -43,72 +46,77 @@ class SubscriptionEventResponseOutcomeSpec extends DataNodeBaseSpec {
@SpringBean
SubscriptionPersistence mockSubscriptionPersistence = Mock(SubscriptionPersistence)
@SpringBean
- EventsPublisher<SubscriptionEventOutcome> mockSubscriptionEventOutcomePublisher = Mock(EventsPublisher<SubscriptionEventOutcome>)
+ EventsPublisher<CloudEvent> mockSubscriptionEventOutcomePublisher = Mock(EventsPublisher<CloudEvent>)
@SpringBean
SubscriptionOutcomeMapper subscriptionOutcomeMapper = Mappers.getMapper(SubscriptionOutcomeMapper)
@Autowired
JsonObjectMapper jsonObjectMapper
+ @Autowired
+ ObjectMapper objectMapper
+
def 'Send response to the client apps successfully'() {
- given: 'a subscription client id and subscription name'
- def clientId = 'some-client-id'
- def subscriptionName = 'some-subscription-name'
- and: 'the persistence service return a data node'
+ given: 'a subscription response event'
+ def subscriptionResponseJsonData = TestUtils.getResourceFileContent('avcSubscriptionEventResponse.json')
+ def subscriptionResponseEvent = jsonObjectMapper.convertJsonString(subscriptionResponseJsonData, SubscriptionEventResponse.class)
+ and: 'a subscription outcome event'
+ def subscriptionOutcomeJsonData = TestUtils.getResourceFileContent('avcSubscriptionOutcomeEvent2.json')
+ def subscriptionOutcomeEvent = jsonObjectMapper.convertJsonString(subscriptionOutcomeJsonData, SubscriptionEventOutcome.class)
+ and: 'a random id for the cloud event'
+ SubscriptionOutcomeCloudMapper.randomId = 'some-id'
+ and: 'a cloud event containing the outcome event'
+ def testCloudEventSent = CloudEventBuilder.v1()
+ .withData(objectMapper.writeValueAsBytes(subscriptionOutcomeEvent))
+ .withId('some-id')
+ .withType('subscriptionCreatedStatus')
+ .withDataSchema(URI.create('urn:cps:' + 'org.onap.cps.ncmp.events.avcsubscription1_0_0.ncmp_to_client.SubscriptionEventOutcome' + ':1.0.0'))
+ .withExtension("correlationid", 'SCO-9989752cm-subscription-001')
+ .withSource(URI.create('NCMP')).build()
+ and: 'the persistence service return a data node that includes pending cm handles that makes it partial success'
mockSubscriptionPersistence.getCmHandlesForSubscriptionEvent(*_) >> [dataNode4]
- and: 'the response is being generated from the db'
- def eventOutcome = objectUnderTest.generateResponse(clientId, subscriptionName)
when: 'the response is being sent'
- objectUnderTest.sendResponse(clientId, subscriptionName)
- then: 'the publisher publish the response with expected parameters'
- 1 * mockSubscriptionEventOutcomePublisher.publishEvent('cm-avc-subscription-response', clientId + subscriptionName, new RecordHeaders(), eventOutcome)
+ objectUnderTest.sendResponse(subscriptionResponseEvent, 'subscriptionCreatedStatus')
+ then: 'the publisher publish the cloud event with itself and expected parameters'
+ 1 * mockSubscriptionEventOutcomePublisher.publishCloudEvent('subscription-response', 'SCO-9989752cm-subscription-001', testCloudEventSent)
+ }
+
+ def 'Create subscription outcome message as expected'() {
+ given: 'a subscription response event'
+ def subscriptionResponseJsonData = TestUtils.getResourceFileContent('avcSubscriptionEventResponse.json')
+ def subscriptionResponseEvent = jsonObjectMapper.convertJsonString(subscriptionResponseJsonData, SubscriptionEventResponse.class)
+ and: 'a subscription outcome event'
+ def subscriptionOutcomeJsonData = TestUtils.getResourceFileContent('avcSubscriptionOutcomeEvent.json')
+ def subscriptionOutcomeEvent = jsonObjectMapper.convertJsonString(subscriptionOutcomeJsonData, SubscriptionEventOutcome.class)
+ and: 'a status code and status message a per #scenarios'
+ subscriptionOutcomeEvent.getData().setStatusCode(statusCode)
+ subscriptionOutcomeEvent.getData().setStatusMessage(statusMessage)
+ when: 'a subscription event outcome message is being formed'
+ def result = objectUnderTest.fromSubscriptionEventResponse(subscriptionResponseEvent, ncmpEventResponseCode)
+ then: 'the result will be equal to event outcome'
+ result == subscriptionOutcomeEvent
+ where: 'the following values are used'
+ scenario | ncmpEventResponseCode || statusMessage || statusCode
+ 'is full outcome' | NcmpEventResponseCode.SUCCESSFULLY_APPLIED_SUBSCRIPTION || 'successfully applied subscription' || 1
+ 'is partial outcome' | NcmpEventResponseCode.PARTIALLY_APPLIED_SUBSCRIPTION || 'partially applied subscription' || 104
}
def 'Check cm handle id to status map to see if it is a full outcome response'() {
when: 'is full outcome response evaluated'
- def response = objectUnderTest.isFullOutcomeResponse(cmHandleIdToStatusMap)
+ def response = objectUnderTest.decideOnNcmpEventResponseCodeForSubscription(cmHandleIdToStatusAndDetailsAsMap)
then: 'the result will be as expected'
- response == expectedResult
+ response == expectedOutcomeResponseDecision
where: 'the following values are used'
- scenario | cmHandleIdToStatusMap || expectedResult
- 'The map contains PENDING status' | ['CMHandle1': SubscriptionStatus.PENDING] as Map || false
- 'The map contains ACCEPTED status' | ['CMHandle1': SubscriptionStatus.ACCEPTED] as Map || true
- 'The map contains REJECTED status' | ['CMHandle1': SubscriptionStatus.REJECTED] as Map || true
- 'The map contains PENDING and ACCEPTED statuses' | ['CMHandle1': SubscriptionStatus.PENDING,'CMHandle2': SubscriptionStatus.ACCEPTED] as Map || false
- 'The map contains REJECTED and ACCEPTED statuses' | ['CMHandle1': SubscriptionStatus.REJECTED,'CMHandle2': SubscriptionStatus.ACCEPTED] as Map || true
- 'The map contains PENDING and REJECTED statuses' | ['CMHandle1': SubscriptionStatus.PENDING,'CMHandle2': SubscriptionStatus.REJECTED] as Map || false
+ scenario | cmHandleIdToStatusAndDetailsAsMap || expectedOutcomeResponseDecision
+ 'The map contains PENDING status' | [CMHandle1: [details:'Subscription forwarded to dmi plugin',status:'PENDING'] as Map] as Map || NcmpEventResponseCode.SUBSCRIPTION_PENDING
+ 'The map contains ACCEPTED status' | [CMHandle1: [details:'',status:'ACCEPTED'] as Map] as Map || NcmpEventResponseCode.SUCCESSFULLY_APPLIED_SUBSCRIPTION
+ 'The map contains REJECTED status' | [CMHandle1: [details:'Cm handle does not exist',status:'REJECTED'] as Map] as Map || NcmpEventResponseCode.SUBSCRIPTION_NOT_APPLICABLE
+ 'The map contains PENDING and PENDING statuses' | [CMHandle1: [details:'Some details',status:'PENDING'] as Map, CMHandle2: [details:'Some details',status:'PENDING'] as Map as Map] as Map || NcmpEventResponseCode.SUBSCRIPTION_PENDING
+ 'The map contains ACCEPTED and ACCEPTED statuses' | [CMHandle1: [details:'',status:'ACCEPTED'] as Map, CMHandle2: [details:'',status:'ACCEPTED'] as Map as Map] as Map || NcmpEventResponseCode.SUCCESSFULLY_APPLIED_SUBSCRIPTION
+ 'The map contains REJECTED and REJECTED statuses' | [CMHandle1: [details:'Reject details',status:'REJECTED'] as Map, CMHandle2: [details:'Reject details',status:'REJECTED'] as Map as Map] as Map || NcmpEventResponseCode.SUBSCRIPTION_NOT_APPLICABLE
+ 'The map contains PENDING and ACCEPTED statuses' | [CMHandle1: [details:'Some details',status:'PENDING'] as Map, CMHandle2: [details:'',status:'ACCEPTED'] as Map as Map] as Map || NcmpEventResponseCode.PARTIALLY_APPLIED_SUBSCRIPTION
+ 'The map contains REJECTED and ACCEPTED statuses' | [CMHandle1: [details:'Cm handle does not exist',status:'REJECTED'] as Map, CMHandle2: [details:'',status:'ACCEPTED'] as Map as Map] as Map || NcmpEventResponseCode.PARTIALLY_APPLIED_SUBSCRIPTION
+ 'The map contains PENDING and REJECTED statuses' | [CMHandle1: [details:'Subscription forwarded to dmi plugin',status:'PENDING'] as Map, CMHandle2: [details:'Cm handle does not exist',status:'REJECTED'] as Map as Map] as Map || NcmpEventResponseCode.PARTIALLY_APPLIED_SUBSCRIPTION
}
- def 'Generate response via fetching data nodes from database.'() {
- given: 'a db call to get data nodes for subscription event'
- 1 * mockSubscriptionPersistence.getCmHandlesForSubscriptionEvent(*_) >> [dataNode4]
- when: 'a response is generated'
- def result = objectUnderTest.generateResponse('some-client-id', 'some-subscription-name')
- then: 'the result will have the same values as same as in dataNode4'
- result.eventType == SubscriptionEventOutcome.EventType.PARTIAL_OUTCOME
- result.getEvent().getSubscription().getClientID() == 'some-client-id'
- result.getEvent().getSubscription().getName() == 'some-subscription-name'
- result.getEvent().getPredicates().getPendingTargets() == ['CMHandle3']
- result.getEvent().getPredicates().getRejectedTargets() == ['CMHandle1']
- result.getEvent().getPredicates().getAcceptedTargets() == ['CMHandle2']
- }
-
- def 'Form subscription outcome message with a list of cm handle id to status mapping'() {
- given: 'a list of collection including cm handle id to status'
- def cmHandleIdToStatus = [['PENDING', 'CMHandle5'], ['PENDING', 'CMHandle4'], ['ACCEPTED', 'CMHandle1'], ['REJECTED', 'CMHandle3']]
- and: 'an outcome event'
- def jsonData = TestUtils.getResourceFileContent('avcSubscriptionOutcomeEvent.json')
- def eventOutcome = jsonObjectMapper.convertJsonString(jsonData, SubscriptionEventOutcome.class)
- eventOutcome.setEventType(expectedEventType)
- when: 'a subscription outcome message formed'
- def result = objectUnderTest.formSubscriptionOutcomeMessage(cmHandleIdToStatus, 'SCO-9989752',
- 'cm-subscription-001', isFullOutcomeResponse)
- result.getEvent().getPredicates().getPendingTargets().sort()
- then: 'the result will be equal to event outcome'
- result == eventOutcome
- where: 'the following values are used'
- scenario | isFullOutcomeResponse || expectedEventType
- 'is full outcome' | true || SubscriptionEventOutcome.EventType.COMPLETE_OUTCOME
- 'is partial outcome' | false || SubscriptionEventOutcome.EventType.PARTIAL_OUTCOME
- }
}
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/avcsubscription/SubscriptionOutcomeMapperSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/avcsubscription/SubscriptionOutcomeMapperSpec.groovy
index 7f1a628291..f5fbdfcb56 100644
--- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/avcsubscription/SubscriptionOutcomeMapperSpec.groovy
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/avcsubscription/SubscriptionOutcomeMapperSpec.groovy
@@ -22,9 +22,10 @@ package org.onap.cps.ncmp.api.impl.events.avcsubscription
import com.fasterxml.jackson.databind.ObjectMapper
import org.mapstruct.factory.Mappers
-import org.onap.cps.ncmp.api.models.SubscriptionEventResponse
-import org.onap.cps.ncmp.events.avc.subscription.v1.SubscriptionEventOutcome
+import org.onap.cps.ncmp.events.avcsubscription1_0_0.dmi_to_ncmp.SubscriptionEventResponse
+import org.onap.cps.ncmp.events.avcsubscription1_0_0.dmi_to_ncmp.SubscriptionStatus
import org.onap.cps.ncmp.utils.TestUtils
+import org.onap.cps.spi.exceptions.DataValidationException
import org.onap.cps.utils.JsonObjectMapper
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.context.SpringBootTest
@@ -43,19 +44,44 @@ class SubscriptionOutcomeMapperSpec extends Specification {
given: 'a Subscription Response Event'
def subscriptionResponseJsonData = TestUtils.getResourceFileContent('avcSubscriptionEventResponse.json')
def subscriptionResponseEvent = jsonObjectMapper.convertJsonString(subscriptionResponseJsonData, SubscriptionEventResponse.class)
- and: 'a Subscription Outcome Event'
- def jsonDataOutcome = TestUtils.getResourceFileContent('avcSubscriptionOutcomeEvent.json')
- def expectedEventOutcome = jsonObjectMapper.convertJsonString(jsonDataOutcome, SubscriptionEventOutcome.class)
- expectedEventOutcome.setEventType(expectedEventType)
when: 'the subscription response event is mapped to a subscription event outcome'
def result = objectUnderTest.toSubscriptionEventOutcome(subscriptionResponseEvent)
- result.setEventType(expectedEventType)
- then: 'the resulting subscription event outcome contains the correct clientId'
- assert result == expectedEventOutcome
+ then: 'the resulting subscription event outcome contains expected pending targets per details grouping'
+ def pendingCmHandleTargetsPerDetails = result.getData().getAdditionalInfo().getPending()
+ assert pendingCmHandleTargetsPerDetails.get(0).getDetails() == 'EMS or node connectivity issues, retrying'
+ assert pendingCmHandleTargetsPerDetails.get(0).getTargets() == ['CMHandle5', 'CMHandle6','CMHandle7']
+ and: 'the resulting subscription event outcome contains expected rejected targets per details grouping'
+ def rejectedCmHandleTargetsPerDetails = result.getData().getAdditionalInfo().getRejected()
+ assert rejectedCmHandleTargetsPerDetails.get(0).getDetails() == 'Target(s) do not exist'
+ assert rejectedCmHandleTargetsPerDetails.get(0).getTargets() == ['CMHandle4']
+ assert rejectedCmHandleTargetsPerDetails.get(1).getDetails() == 'Faulty subscription format for target(s)'
+ assert rejectedCmHandleTargetsPerDetails.get(1).getTargets() == ['CMHandle1', 'CMHandle2','CMHandle3']
+ }
+
+ def 'Map subscription event response with null of subscription status list to subscription event outcome causes an exception'() {
+ given: 'a Subscription Response Event'
+ def subscriptionResponseJsonData = TestUtils.getResourceFileContent('avcSubscriptionEventResponse.json')
+ def subscriptionResponseEvent = jsonObjectMapper.convertJsonString(subscriptionResponseJsonData, SubscriptionEventResponse.class)
+ and: 'set subscription status list to null'
+ subscriptionResponseEvent.getData().setSubscriptionStatus(subscriptionStatusList)
+ when: 'the subscription response event is mapped to a subscription event outcome'
+ objectUnderTest.toSubscriptionEventOutcome(subscriptionResponseEvent)
+ then: 'a DataValidationException is thrown with an expected exception details'
+ def exception = thrown(DataValidationException)
+ exception.details == 'SubscriptionStatus list cannot be null or empty'
where: 'the following values are used'
- scenario || expectedEventType
- 'is full outcome' || SubscriptionEventOutcome.EventType.COMPLETE_OUTCOME
- 'is partial outcome' || SubscriptionEventOutcome.EventType.PARTIAL_OUTCOME
+ scenario || subscriptionStatusList
+ 'A null subscription status list' || null
+ 'An empty subscription status list' || new ArrayList<SubscriptionStatus>()
}
+ def 'Map subscription event response with subscription status list to subscription event outcome without any exception'() {
+ given: 'a Subscription Response Event'
+ def subscriptionResponseJsonData = TestUtils.getResourceFileContent('avcSubscriptionEventResponse.json')
+ def subscriptionResponseEvent = jsonObjectMapper.convertJsonString(subscriptionResponseJsonData, SubscriptionEventResponse.class)
+ when: 'the subscription response event is mapped to a subscription event outcome'
+ objectUnderTest.toSubscriptionEventOutcome(subscriptionResponseEvent)
+ then: 'no exception thrown'
+ noExceptionThrown()
+ }
} \ No newline at end of file
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/subscriptions/SubscriptionPersistenceSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/subscriptions/SubscriptionPersistenceSpec.groovy
index ec54e8917a..7116a17862 100644
--- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/subscriptions/SubscriptionPersistenceSpec.groovy
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/subscriptions/SubscriptionPersistenceSpec.groovy
@@ -59,14 +59,15 @@ class SubscriptionPersistenceSpec extends Specification {
SUBSCRIPTION_REGISTRY_PARENT,
'{"subscription":[{' +
'"topic":"some-topic",' +
- '"predicates":{"datastore":"some-datastore","targetCmHandles":[{"cmHandleId":"cmhandle1","status":"PENDING"},{"cmHandleId":"cmhandle2","status":"PENDING"}]},' +
+ '"predicates":{"datastore":"some-datastore","targetCmHandles":[{"cmHandleId":"cmhandle1","status":"PENDING","details":"Subscription forwarded to dmi plugin"},' +
+ '{"cmHandleId":"cmhandle2","status":"PENDING","details":"Subscription forwarded to dmi plugin"}]},' +
'"clientID":"some-client-id","subscriptionName":"some-subscription-name","isTagged":true}]}',
NO_TIMESTAMP)
}
def 'add or replace cm handle list element into db' () {
given: 'a data node with child node exist in db'
- def leaves1 = [status:'PENDING', cmHandleId:'cmhandle1'] as Map
+ def leaves1 = [status:'REJECTED', cmHandleId:'cmhandle1', details:'Cm handle does not exist'] as Map
def childDataNode = new DataNodeBuilder().withDataspace('NCMP-Admin')
.withAnchor('AVC-Subscriptions').withXpath('/subscription-registry/subscription')
.withLeaves(leaves1).build()
@@ -81,11 +82,11 @@ class SubscriptionPersistenceSpec extends Specification {
objectUnderTest.saveSubscriptionEvent(yangModelSubscriptionEvent)
then: 'the cpsDataService save non-existing cm handle with the correct data'
1 * mockCpsDataService.saveListElements(SUBSCRIPTION_DATASPACE_NAME, SUBSCRIPTION_ANCHOR_NAME,
- SUBSCRIPTION_REGISTRY_PREDICATES_XPATH, '{"targetCmHandles":[{"cmHandleId":"cmhandle2","status":"PENDING"}]}',
+ SUBSCRIPTION_REGISTRY_PREDICATES_XPATH, '{"targetCmHandles":[{"cmHandleId":"cmhandle2","status":"PENDING","details":"Subscription forwarded to dmi plugin"}]}',
NO_TIMESTAMP)
and: 'the cpsDataService update existing cm handle with the correct data'
1 * mockCpsDataService.updateNodeLeaves(SUBSCRIPTION_DATASPACE_NAME, SUBSCRIPTION_ANCHOR_NAME,
- SUBSCRIPTION_REGISTRY_PREDICATES_XPATH, '{"targetCmHandles":[{"cmHandleId":"cmhandle1","status":"PENDING"}]}',
+ SUBSCRIPTION_REGISTRY_PREDICATES_XPATH, '{"targetCmHandles":[{"cmHandleId":"cmhandle1","status":"PENDING","details":"Subscription forwarded to dmi plugin"}]}',
NO_TIMESTAMP)
}
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/utils/DataNodeBaseSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/utils/DataNodeBaseSpec.groovy
index 7474166ffe..e28a10261e 100644
--- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/utils/DataNodeBaseSpec.groovy
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/utils/DataNodeBaseSpec.groovy
@@ -25,13 +25,13 @@ import spock.lang.Specification
class DataNodeBaseSpec extends Specification {
- def leaves1 = [status:'PENDING', cmHandleId:'CMHandle3'] as Map
+ def leaves1 = [status:'PENDING', cmHandleId:'CMHandle3', details:'Subscription forwarded to dmi plugin'] as Map
def dataNode1 = createDataNodeWithLeaves(leaves1)
- def leaves2 = [status:'ACCEPTED', cmHandleId:'CMHandle2'] as Map
+ def leaves2 = [status:'ACCEPTED', cmHandleId:'CMHandle2', details:''] as Map
def dataNode2 = createDataNodeWithLeaves(leaves2)
- def leaves3 = [status:'REJECTED', cmHandleId:'CMHandle1'] as Map
+ def leaves3 = [status:'REJECTED', cmHandleId:'CMHandle1', details:'Cm handle does not exist'] as Map
def dataNode3 = createDataNodeWithLeaves(leaves3)
def leaves4 = [datastore:'passthrough-running'] as Map
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/utils/DataNodeHelperSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/utils/DataNodeHelperSpec.groovy
index 819f1fa08e..28db7babf9 100644
--- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/utils/DataNodeHelperSpec.groovy
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/utils/DataNodeHelperSpec.groovy
@@ -20,7 +20,6 @@
package org.onap.cps.ncmp.api.impl.utils
-import org.onap.cps.ncmp.api.impl.subscriptions.SubscriptionStatus
import org.onap.cps.spi.model.DataNodeBuilder
class DataNodeHelperSpec extends DataNodeBaseSpec {
@@ -38,9 +37,9 @@ class DataNodeHelperSpec extends DataNodeBaseSpec {
and: 'all the leaves result list are equal to given leaves of data nodes'
result[0] == [clientID:'SCO-9989752', isTagged:false, subscriptionName:'cm-subscription-001']
result[1] == [datastore:'passthrough-running']
- result[2] == [status:'PENDING', cmHandleId:'CMHandle3']
- result[3] == [status:'ACCEPTED', cmHandleId:'CMHandle2']
- result[4] == [status:'REJECTED', cmHandleId:'CMHandle1']
+ result[2] == [status:'PENDING', cmHandleId:'CMHandle3', details:'Subscription forwarded to dmi plugin']
+ result[3] == [status:'ACCEPTED', cmHandleId:'CMHandle2', details:'']
+ result[4] == [status:'REJECTED', cmHandleId:'CMHandle1', details:'Cm handle does not exist']
}
def 'Get cm handle id to status as expected from a nested data node.'() {
@@ -52,26 +51,18 @@ class DataNodeHelperSpec extends DataNodeBaseSpec {
and: 'the nested data node is flatten and retrieves the leaves '
def leaves = DataNodeHelper.getDataNodeLeaves([dataNode])
when:'cm handle id to status is retrieved'
- def result = DataNodeHelper.getCmHandleIdToStatus(leaves)
+ def result = DataNodeHelper.cmHandleIdToStatusAndDetailsAsMap(leaves)
then: 'the result list size is 3'
result.size() == 3
and: 'the result contains expected values'
- result[0] as List == ['PENDING', 'CMHandle3']
- result[1] as List == ['ACCEPTED', 'CMHandle2']
- result[2] as List == ['REJECTED', 'CMHandle1']
- }
+ result == [
+ CMHandle3: [details:'Subscription forwarded to dmi plugin',status:'PENDING'] as Map,
+ CMHandle2: [details:'',status:'ACCEPTED'] as Map,
+ CMHandle1: [details:'Cm handle does not exist',status:'REJECTED'] as Map
+ ] as Map
- def 'Get cm handle id to status map as expected from list of collection' () {
- given: 'a list of collection'
- def cmHandleCollection = [['PENDING', 'CMHandle3'], ['ACCEPTED', 'CMHandle2'], ['REJECTED', 'CMHandle1']]
- when: 'the map is formed up with a method call'
- def result = DataNodeHelper.getCmHandleIdToStatusMap(cmHandleCollection)
- then: 'the map values are as expected'
- result.keySet() == ['CMHandle3', 'CMHandle2', 'CMHandle1'] as Set
- result.values() as List == [SubscriptionStatus.PENDING, SubscriptionStatus.ACCEPTED, SubscriptionStatus.REJECTED]
}
-
def 'Get cm handle id to status map as expected from a nested data node.'() {
given: 'a nested data node'
def dataNode = new DataNodeBuilder().withDataspace('NCMP-Admin')
@@ -79,8 +70,14 @@ class DataNodeHelperSpec extends DataNodeBaseSpec {
.withLeaves([clientID:'SCO-9989752', isTagged:false, subscriptionName:'cm-subscription-001'])
.withChildDataNodes([dataNode4]).build()
when:'cm handle id to status is being extracted'
- def result = DataNodeHelper.getCmHandleIdToStatusMapFromDataNodes([dataNode]);
- then: 'the keys are retrieved as expected'
- result.keySet() == ['CMHandle3','CMHandle2','CMHandle1'] as Set
+ def result = DataNodeHelper.cmHandleIdToStatusAndDetailsAsMapFromDataNode([dataNode]);
+ then: 'the result list size is 3'
+ result.size() == 3
+ and: 'the result contains expected values'
+ result == [
+ CMHandle3: [details:'Subscription forwarded to dmi plugin',status:'PENDING'] as Map,
+ CMHandle2: [details:'',status:'ACCEPTED'] as Map,
+ CMHandle1: [details:'Cm handle does not exist',status:'REJECTED'] as Map
+ ] as Map
}
}
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/utils/SubscriptionEventCloudMapperSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/utils/SubscriptionEventCloudMapperSpec.groovy
index 61eb319101..bc19e2dde8 100644
--- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/utils/SubscriptionEventCloudMapperSpec.groovy
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/utils/SubscriptionEventCloudMapperSpec.groovy
@@ -24,6 +24,7 @@ import com.fasterxml.jackson.databind.ObjectMapper
import io.cloudevents.core.builder.CloudEventBuilder
import org.onap.cps.ncmp.events.avcsubscription1_0_0.client_to_ncmp.SubscriptionEvent
import org.onap.cps.ncmp.utils.TestUtils
+import org.onap.cps.spi.exceptions.CloudEventConstructionException
import org.onap.cps.utils.JsonObjectMapper
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.context.SpringBootTest
@@ -45,7 +46,7 @@ class SubscriptionEventCloudMapperSpec extends Specification {
def testCloudEvent = CloudEventBuilder.v1()
.withData(objectMapper.writeValueAsBytes(testEventData))
.withId('some-event-id')
- .withType('CREATE')
+ .withType('subscriptionCreated')
.withSource(URI.create('some-resource'))
.withExtension('correlationid', 'test-cmhandle1').build()
when: 'the cloud event map to subscription event'
@@ -59,7 +60,7 @@ class SubscriptionEventCloudMapperSpec extends Specification {
def testCloudEvent = CloudEventBuilder.v1()
.withData(null)
.withId('some-event-id')
- .withType('CREATE')
+ .withType('subscriptionCreated')
.withSource(URI.create('some-resource'))
.withExtension('correlationid', 'test-cmhandle1').build()
when: 'the cloud event map to subscription event'
@@ -75,30 +76,29 @@ class SubscriptionEventCloudMapperSpec extends Specification {
org.onap.cps.ncmp.events.avcsubscription1_0_0.ncmp_to_dmi.SubscriptionEvent.class)
def testCloudEvent = CloudEventBuilder.v1()
.withData(objectMapper.writeValueAsBytes(testEventData))
- .withId('some-event-key')
- .withType('CREATE')
- .withSource(URI.create('some-resource'))
+ .withId('some-id')
+ .withType('subscriptionCreated')
+ .withSource(URI.create('SCO-9989752'))
.withExtension('correlationid', 'test-cmhandle1').build()
when: 'the subscription event map to data of cloud event'
- def resultCloudEvent = SubscriptionEventCloudMapper.toCloudEvent(testEventData, 'some-event-key')
+ SubscriptionEventCloudMapper.randomId = 'some-id'
+ def resultCloudEvent = SubscriptionEventCloudMapper.toCloudEvent(testEventData, 'some-event-key', 'subscriptionCreated')
then: 'the subscription event resulted having expected values'
resultCloudEvent.getData() == testCloudEvent.getData()
resultCloudEvent.getId() == testCloudEvent.getId()
resultCloudEvent.getType() == testCloudEvent.getType()
+ resultCloudEvent.getSource() == URI.create('SCO-9989752')
+ resultCloudEvent.getDataSchema() == URI.create('urn:cps:org.onap.cps.ncmp.events.avcsubscription1_0_0.ncmp_to_dmi.SubscriptionEvent:1.0.0')
}
def 'Map the subscription event to data of the cloud event with wrong content causes an exception'() {
given: 'an empty ncmp subscription event'
def testNcmpSubscriptionEvent = new org.onap.cps.ncmp.events.avcsubscription1_0_0.ncmp_to_dmi.SubscriptionEvent()
when: 'the subscription event map to data of cloud event'
- def thrownException = null
- try {
- SubscriptionEventCloudMapper.toCloudEvent(testNcmpSubscriptionEvent, 'some-key')
- } catch (Exception e) {
- thrownException = e
- }
+ SubscriptionEventCloudMapper.toCloudEvent(testNcmpSubscriptionEvent, 'some-key', 'some-event-type')
then: 'a run time exception is thrown'
- assert thrownException instanceof RuntimeException
+ def exception = thrown(CloudEventConstructionException)
+ exception.details == 'Invalid object to serialize or required headers is missing'
}
}