a0b6de1aa4f1b2bfd02f2c9ad4766271447ed8d5
[cps.git] /
1 /*
2  * ============LICENSE_START=======================================================
3  * Copyright (C) 2022-2025 OpenInfra Foundation Europe. All rights reserved.
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
8  *
9  *       http://www.apache.org/licenses/LICENSE-2.0
10  *
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.
16  *
17  * SPDX-License-Identifier: Apache-2.0
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.onap.cps.ncmp.impl.inventory.sync.lcm
22
23 import static org.onap.cps.ncmp.events.lcm.v1.Values.CmHandleState.ADVISED
24 import static org.onap.cps.ncmp.events.lcm.v1.Values.CmHandleState.READY
25
26 import io.micrometer.core.instrument.Tag
27 import io.micrometer.core.instrument.simple.SimpleMeterRegistry
28 import org.onap.cps.events.EventsPublisher
29 import org.onap.cps.ncmp.events.lcm.v1.Event
30 import org.onap.cps.ncmp.events.lcm.v1.LcmEvent
31 import org.onap.cps.ncmp.events.lcm.v1.LcmEventHeader
32 import org.onap.cps.ncmp.events.lcm.v1.Values
33 import org.onap.cps.utils.JsonObjectMapper
34 import org.springframework.kafka.KafkaException
35 import spock.lang.Specification
36
37 class LcmEventsProducerSpec extends Specification {
38
39     def mockLcmEventsPublisher = Mock(EventsPublisher)
40     def mockJsonObjectMapper = Mock(JsonObjectMapper)
41     def meterRegistry = new SimpleMeterRegistry()
42
43     def objectUnderTest = new LcmEventsProducer(mockLcmEventsPublisher, mockJsonObjectMapper, meterRegistry)
44
45     def 'Create and Publish lcm event where events are #scenario'() {
46         given: 'a cm handle id, Lcm Event, and headers'
47             def cmHandleId = 'test-cm-handle-id'
48             def eventId = UUID.randomUUID().toString()
49             def event = getEventWithCmHandleState(ADVISED, READY)
50             def lcmEvent = new LcmEvent(event: event, eventId: eventId, eventCorrelationId: cmHandleId)
51         and: 'we also have a lcm event header'
52             def lcmEventHeader = new LcmEventHeader(eventId: eventId, eventCorrelationId: cmHandleId)
53         and: 'notificationsEnabled is #notificationsEnabled and it will be true as default'
54             objectUnderTest.notificationsEnabled = notificationsEnabled
55         and: 'lcm event header is transformed to headers map'
56             mockJsonObjectMapper.convertToValueType(lcmEventHeader, Map.class) >> ['eventId': eventId, 'eventCorrelationId': cmHandleId]
57         when: 'service is called to publish lcm event'
58             objectUnderTest.publishLcmEvent('test-cm-handle-id', lcmEvent, lcmEventHeader)
59         then: 'publisher is called #expectedTimesMethodCalled times'
60             expectedTimesMethodCalled * mockLcmEventsPublisher.publishEvent(_, cmHandleId, _, lcmEvent) >> {
61                 args -> {
62                     def eventHeaders = (args[2] as Map<String,Object>)
63                     assert eventHeaders.containsKey('eventId')
64                     assert eventHeaders.containsKey('eventCorrelationId')
65                     assert eventHeaders.get('eventId') == eventId
66                     assert eventHeaders.get('eventCorrelationId') == cmHandleId
67                 }
68             }
69         and: 'metrics are recorded with correct tags'
70             def timer = meterRegistry.find('cps.ncmp.lcm.events.publish').timer()
71             if (notificationsEnabled) {
72                 assert timer != null
73                 assert timer.count() == expectedTimesMethodCalled
74                 def tags = timer.getId().getTags()
75                 assert tags.containsAll(Tag.of('oldCmHandleState', ADVISED.value()), Tag.of('newCmHandleState', READY.value()))
76             } else {
77                 assert timer == null
78             }
79         where: 'the following values are used'
80             scenario   | notificationsEnabled || expectedTimesMethodCalled
81             'enabled'  | true                 || 1
82             'disabled' | false                || 0
83     }
84
85     def 'Unable to send message'(){
86         given: 'a cm handle id and Lcm Event and notification enabled'
87             def cmHandleId = 'test-cm-handle-id'
88             def eventId = UUID.randomUUID().toString()
89         and: 'event #event'
90             def lcmEvent = new LcmEvent(event: event, eventId: eventId, eventCorrelationId: cmHandleId)
91             def lcmEventHeader = new LcmEventHeader(eventId: eventId, eventCorrelationId: cmHandleId)
92             objectUnderTest.notificationsEnabled = true
93         when: 'publisher set to throw an exception'
94             mockLcmEventsPublisher.publishEvent(_, _, _, _) >> { throw new KafkaException('publishing failed')}
95         and: 'an event is publised'
96             objectUnderTest.publishLcmEvent(cmHandleId, lcmEvent, lcmEventHeader)
97         then: 'the exception is just logged and not bubbled up'
98             noExceptionThrown()
99         and: 'metrics are recorded with error tags'
100             def timer = meterRegistry.find('cps.ncmp.lcm.events.publish').timer()
101             assert timer != null
102             assert timer.count() == 1
103             def expectedTags = [Tag.of('oldCmHandleState', 'N/A'), Tag.of('newCmHandleState', 'N/A')]
104             def tags = timer.getId().getTags()
105             assert tags.containsAll(expectedTags)
106         where: 'the following values are used'
107             scenario                  | event
108             'without values'          | new Event()
109             'without cm handle state' | getEvent()
110     }
111
112     def getEvent() {
113         def event = new Event()
114         def values = new Values()
115         event.setOldValues(values)
116         event.setNewValues(values)
117         event
118     }
119
120     def getEventWithCmHandleState(oldCmHandleState, newCmHandleState) {
121         def event = new Event()
122         def advisedCmHandleStateValues = new Values()
123         advisedCmHandleStateValues.setCmHandleState(oldCmHandleState)
124         event.setOldValues(advisedCmHandleStateValues)
125         def readyCmHandleStateValues = new Values()
126         readyCmHandleStateValues.setCmHandleState(newCmHandleState)
127         event.setNewValues(readyCmHandleStateValues)
128         return event
129     }
130 }