2 * ============LICENSE_START=======================================================
3 * Copyright (C) 2024 TechMahindra Ltd.
4 * Copyright (C) 2024 Nordix Foundation.
5 * ================================================================================
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
18 * SPDX-License-Identifier: Apache-2.0
19 * ============LICENSE_END=========================================================
22 package org.onap.cps.events
24 import static org.onap.cps.events.model.Data.Operation.CREATE
25 import static org.onap.cps.events.model.Data.Operation.DELETE
26 import static org.onap.cps.events.model.Data.Operation.UPDATE
28 import com.fasterxml.jackson.databind.ObjectMapper
29 import io.cloudevents.CloudEvent
30 import io.cloudevents.core.CloudEventUtils
31 import io.cloudevents.jackson.PojoCloudEventDataMapper
32 import org.onap.cps.events.model.CpsDataUpdatedEvent
33 import org.onap.cps.spi.model.Anchor
34 import org.onap.cps.utils.JsonObjectMapper
35 import org.springframework.test.context.ContextConfiguration
36 import spock.lang.Specification
38 import java.time.OffsetDateTime
40 @ContextConfiguration(classes = [ObjectMapper, JsonObjectMapper])
41 class CpsDataUpdateEventsServiceSpec extends Specification {
42 def mockEventsPublisher = Mock(EventsPublisher)
43 def objectMapper = new ObjectMapper();
45 def objectUnderTest = new CpsDataUpdateEventsService(mockEventsPublisher)
47 def 'Create and Publish cps update event where events are #scenario'() {
48 given: 'an anchor, operation and observed timestamp'
49 def anchor = new Anchor('anchor01', 'dataspace01', 'schema01');
50 def operation = operationInRequest
51 def observedTimestamp = OffsetDateTime.now()
52 and: 'notificationsEnabled is #notificationsEnabled and it will be true as default'
53 objectUnderTest.notificationsEnabled = true
54 and: 'cpsChangeEventNotificationsEnabled is also true'
55 objectUnderTest.cpsChangeEventNotificationsEnabled = true
56 when: 'service is called to publish data update event'
57 objectUnderTest.topicName = "cps-core-event"
58 objectUnderTest.publishCpsDataUpdateEvent(anchor, xpath, operation, observedTimestamp)
59 then: 'the event contains the required attributes'
60 1 * mockEventsPublisher.publishCloudEvent('cps-core-event', 'dataspace01:anchor01', _) >> {
63 def cpsDataUpdatedEvent = (args[2] as CloudEvent)
64 assert cpsDataUpdatedEvent.getExtension('correlationid') == 'dataspace01:anchor01'
65 assert cpsDataUpdatedEvent.type == 'org.onap.cps.events.model.CpsDataUpdatedEvent'
66 assert cpsDataUpdatedEvent.source.toString() == 'CPS'
67 def actualEventOperation = CloudEventUtils.mapData(cpsDataUpdatedEvent, PojoCloudEventDataMapper.from(objectMapper, CpsDataUpdatedEvent.class)).getValue().data.operation
68 assert actualEventOperation == expectedOperation
71 where: 'the following values are used'
72 scenario | xpath | operationInRequest || expectedOperation
73 'empty xpath' | '' | CREATE || CREATE
74 'root xpath and create operation' | '/' | CREATE || CREATE
75 'root xpath and update operation' | '/' | UPDATE || UPDATE
76 'root xpath and delete operation' | '/' | DELETE || DELETE
77 'not root xpath and update operation' | 'test' | UPDATE || UPDATE
78 'root node xpath and create operation' | '/test' | CREATE || CREATE
79 'non root node xpath and update operation' | '/test/path' | CREATE || UPDATE
80 'non root node xpath and delete operation' | '/test/path' | DELETE || UPDATE
83 def 'publish cps update event when #scenario'() {
84 given: 'an anchor, operation and observed timestamp'
85 def anchor = new Anchor('anchor01', 'dataspace01', 'schema01');
86 def operation = CREATE
87 def observedTimestamp = OffsetDateTime.now()
88 and: 'notificationsEnabled is #notificationsEnabled'
89 objectUnderTest.notificationsEnabled = notificationsEnabled
90 and: 'cpsChangeEventNotificationsEnabled is #cpsChangeEventNotificationsEnabled'
91 objectUnderTest.cpsChangeEventNotificationsEnabled = cpsChangeEventNotificationsEnabled
92 when: 'service is called to publish data update event'
93 objectUnderTest.topicName = "cps-core-event"
94 objectUnderTest.publishCpsDataUpdateEvent(anchor, '/', operation, observedTimestamp)
95 then: 'the event contains the required attributes'
96 expectedCallToPublisher * mockEventsPublisher.publishCloudEvent('cps-core-event', 'dataspace01:anchor01', _)
97 where: 'below scenarios are present'
98 scenario | notificationsEnabled | cpsChangeEventNotificationsEnabled || expectedCallToPublisher
99 'both notifications enabled' | true | true || 1
100 'both notifications disabled' | false | false || 0
101 'only CPS change event notification enabled' | false | true || 0
102 'only overall notification enabled' | true | false || 0
106 def 'publish cps update event when no timestamp provided'() {
107 given: 'an anchor, operation and null timestamp'
108 def anchor = new Anchor('anchor01', 'dataspace01', 'schema01');
109 def operation = CREATE
110 def observedTimestamp = null
111 and: 'notificationsEnabled is true'
112 objectUnderTest.notificationsEnabled = true
113 and: 'cpsChangeEventNotificationsEnabled is true'
114 objectUnderTest.cpsChangeEventNotificationsEnabled = true
115 when: 'service is called to publish data update event'
116 objectUnderTest.topicName = "cps-core-event"
117 objectUnderTest.publishCpsDataUpdateEvent(anchor, '/', operation, observedTimestamp)
118 then: 'the event is published'
119 1 * mockEventsPublisher.publishCloudEvent('cps-core-event', 'dataspace01:anchor01', _)