2  * ============LICENSE_START=======================================================
 
   3  * Copyright (c) 2024 Nordix Foundation.
 
   4  *  ================================================================================
 
   5  *  Licensed under the Apache License, Version 2.0 (the "License");
 
   6  *  you may not use this file except in compliance with the License.
 
   7  *  You may obtain a copy of the License at
 
   9  *        http://www.apache.org/licenses/LICENSE-2.0
 
  11  *  Unless required by applicable law or agreed to in writing, software
 
  12  *  distributed under the License is distributed on an 'AS IS' BASIS,
 
  13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
  14  *  See the License for the specific language governing permissions and
 
  15  *  limitations under the License.
 
  17  *  SPDX-License-Identifier: Apache-2.0
 
  18  *  ============LICENSE_END=========================================================
 
  21 package org.onap.cps.ncmp.impl.cmnotificationsubscription.dmi
 
  23 import ch.qos.logback.classic.Level
 
  24 import ch.qos.logback.classic.Logger
 
  25 import ch.qos.logback.classic.spi.ILoggingEvent
 
  26 import ch.qos.logback.core.read.ListAppender
 
  27 import com.fasterxml.jackson.databind.ObjectMapper
 
  28 import io.cloudevents.CloudEvent
 
  29 import io.cloudevents.core.builder.CloudEventBuilder
 
  30 import org.apache.kafka.clients.consumer.ConsumerRecord
 
  31 import org.onap.cps.ncmp.api.kafka.MessagingBaseSpec
 
  32 import org.onap.cps.ncmp.impl.cmnotificationsubscription.cache.DmiCacheHandler
 
  33 import org.onap.cps.ncmp.impl.cmnotificationsubscription.ncmp.NcmpOutEventMapper
 
  34 import org.onap.cps.ncmp.impl.cmnotificationsubscription.ncmp.NcmpOutEventProducer
 
  35 import org.onap.cps.ncmp.impl.cmnotificationsubscription_1_0_0.dmi_to_ncmp.Data
 
  36 import org.onap.cps.ncmp.impl.cmnotificationsubscription_1_0_0.dmi_to_ncmp.DmiOutEvent
 
  37 import org.onap.cps.ncmp.utils.TestUtils
 
  38 import org.onap.cps.utils.JsonObjectMapper
 
  39 import org.slf4j.LoggerFactory
 
  40 import org.springframework.beans.factory.annotation.Autowired
 
  41 import org.springframework.boot.test.context.SpringBootTest
 
  43 import static org.onap.cps.ncmp.impl.cmnotificationsubscription.models.CmSubscriptionStatus.ACCEPTED
 
  44 import static org.onap.cps.ncmp.impl.cmnotificationsubscription.models.CmSubscriptionStatus.REJECTED
 
  46 @SpringBootTest(classes = [ObjectMapper, JsonObjectMapper])
 
  47 class DmiOutEventConsumerSpec extends MessagingBaseSpec {
 
  50     JsonObjectMapper jsonObjectMapper
 
  53     ObjectMapper objectMapper
 
  55     def mockDmiCacheHandler = Mock(DmiCacheHandler)
 
  56     def mockNcmpOutEventProducer = Mock(NcmpOutEventProducer)
 
  57     def mockNcmpOutEventMapper = Mock(NcmpOutEventMapper)
 
  59     def objectUnderTest = new DmiOutEventConsumer(mockDmiCacheHandler, mockNcmpOutEventProducer, mockNcmpOutEventMapper)
 
  60     def logger = Spy(ListAppender<ILoggingEvent>)
 
  63         ((Logger) LoggerFactory.getLogger(DmiOutEventConsumer.class)).addAppender(logger)
 
  68         ((Logger) LoggerFactory.getLogger(DmiOutEventConsumer.class)).detachAndStopAllAppenders()
 
  72     def 'Consume valid CM Subscription response from DMI Plugin'() {
 
  73         given: 'a cmsubscription event'
 
  74             def jsonData = TestUtils.getResourceFileContent('cmSubscription/cmNotificationSubscriptionDmiOutEvent.json')
 
  75             def testEventSent = jsonObjectMapper.convertJsonString(jsonData, DmiOutEvent.class)
 
  76             def testCloudEventSent = CloudEventBuilder.v1()
 
  77                 .withData(objectMapper.writeValueAsBytes(testEventSent))
 
  78                 .withId('random-uuid')
 
  79                 .withType('subscriptionCreateResponse')
 
  80                 .withSource(URI.create('test-dmi-plugin-name'))
 
  81                 .withExtension('correlationid', 'sub-1#test-dmi-plugin-name').build()
 
  82             def consumerRecord = new ConsumerRecord<String, CloudEvent>('topic-name', 0, 0, 'event-key', testCloudEventSent)
 
  83         when: 'the valid event is consumed'
 
  84             objectUnderTest.consumeDmiOutEvent(consumerRecord)
 
  85         then: 'an event is logged with level INFO'
 
  86             def loggingEvent = getLoggingEvent()
 
  87             assert loggingEvent.level == Level.INFO
 
  88         and: 'the log indicates the task completed successfully'
 
  89             assert loggingEvent.formattedMessage == 'Cm Subscription with id : sub-1 handled by the dmi-plugin : test-dmi-plugin-name has the status : accepted'
 
  92     def 'Consume a valid CM Notification Subscription Event and perform correct actions base on status'() {
 
  93         given: 'a cmNotificationSubscription event'
 
  94             def dmiOutEventData = new Data(statusCode: statusCode, statusMessage: subscriptionStatus.toString())
 
  95             def dmiOutEvent = new DmiOutEvent().withData(dmiOutEventData)
 
  96             def testCloudEventSent = CloudEventBuilder.v1()
 
  97                 .withData(objectMapper.writeValueAsBytes(dmiOutEvent))
 
  98                 .withId('random-uuid')
 
  99                 .withType('subscriptionCreateResponse')
 
 100                 .withSource(URI.create('test-dmi-plugin-name'))
 
 101                 .withExtension('correlationid', 'sub-1#test-dmi-plugin-name').build()
 
 102             def consumerRecord = new ConsumerRecord<String, CloudEvent>('topic-name', 0, 0, 'event-key', testCloudEventSent)
 
 103         when: 'the event is consumed'
 
 104             objectUnderTest.consumeDmiOutEvent(consumerRecord)
 
 105         then: 'correct number of calls to cache'
 
 106             expectedCacheCalls * mockDmiCacheHandler.updateDmiSubscriptionStatusPerDmi('sub-1','test-dmi-plugin-name', subscriptionStatus)
 
 107         and: 'correct number of calls to persist cache'
 
 108             expectedPersistenceCalls * mockDmiCacheHandler.persistIntoDatabasePerDmi('sub-1','test-dmi-plugin-name')
 
 109         and: 'correct number of calls to map the ncmp out event'
 
 110             1 * mockNcmpOutEventMapper.toNcmpOutEvent('sub-1', _)
 
 111         and: 'correct number of calls to publish the ncmp out event to client'
 
 112             1 * mockNcmpOutEventProducer.publishNcmpOutEvent('sub-1', 'subscriptionCreateResponse', _, false)
 
 113         where: 'the following parameters are used'
 
 114             scenario          | subscriptionStatus | statusCode || expectedCacheCalls | expectedPersistenceCalls
 
 115             'Accepted Status' | ACCEPTED           | '1'        || 1                  | 1
 
 116             'Rejected Status' | REJECTED           | '104'      || 1                  | 0
 
 119     def getLoggingEvent() {
 
 120         return logger.list[0]