2 * ============LICENSE_START=======================================================
3 * Copyright (c) 2021 Bell Canada.
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.
16 * ============LICENSE_END=========================================================
19 package org.onap.cps.temporal.controller.event.listener.kafka
21 import org.mapstruct.factory.Mappers
22 import org.onap.cps.event.model.CpsDataUpdatedEvent
23 import org.onap.cps.temporal.controller.event.listener.exception.InvalidEventEnvelopException
24 import org.onap.cps.temporal.controller.event.model.CpsDataUpdatedEventMapper
25 import org.onap.cps.temporal.service.NetworkDataService
26 import spock.lang.Specification
28 import static org.onap.cps.temporal.controller.event.listener.exception.InvalidEventEnvelopException.InvalidField.ErrorType.MISSING
29 import static org.onap.cps.temporal.controller.event.listener.exception.InvalidEventEnvelopException.InvalidField.ErrorType.UNEXPECTED
32 * Test specification for data updated event listener.
34 class DataUpdatedEventListenerSpec extends Specification {
36 public static final String EXPECTED_SCHEMA_EXCEPTION_MESSAGE = 'urn:cps:org.onap.cps:data-updated-event-schema:v99'
39 def anEventType = 'my-event-type'
40 def anEventSchema = new URI('my-event-schema')
41 def anEventSource = new URI('my-event-source')
42 def aTimestamp = EventFixtures.currentIsoTimestamp()
43 def aDataspace = 'my-dataspace'
44 def aSchemaSet = 'my-schema-set'
45 def anAnchor = 'my-anchor'
46 def aDataName = 'my-data-name'
47 def aDataValue = 'my-data-value'
49 // Define service mock
50 def mockService = Mock(NetworkDataService)
53 def mapper = Mappers.getMapper(CpsDataUpdatedEventMapper.class)
55 // Define listener under test
56 def objectUnderTest = new DataUpdatedEventListener(mockService, mapper)
58 def 'Event message consumption'() {
59 when: 'an event is received'
61 EventFixtures.buildEvent(
62 timestamp: aTimestamp, dataspace: aDataspace, schemaSet: aSchemaSet, anchor: anAnchor,
63 dataName: aDataName, dataValue: aDataValue)
64 objectUnderTest.consume(event)
65 then: 'network data service is requested to persisted the data change'
66 1 * mockService.addNetworkData(
68 it.getObservedTimestamp() == EventFixtures.toOffsetDateTime(aTimestamp)
69 && it.getDataspace() == aDataspace
70 && it.getSchemaSet() == aSchemaSet
71 && it.getAnchor() == anAnchor
72 && it.getPayload() == String.format('{"%s":"%s"}', aDataName, aDataValue)
73 && it.getCreatedTimestamp() == null
78 def 'Event message consumption fails because of missing envelop'() {
79 when: 'an event without envelop information is received'
80 def invalidEvent = new CpsDataUpdatedEvent().withSchema(null)
81 objectUnderTest.consume(invalidEvent)
82 then: 'an exception is thrown with 4 invalid fields'
83 def e = thrown(InvalidEventEnvelopException)
84 e.getCpsDataUpdatedEvent() == invalidEvent
85 e.getInvalidFields().size() == 4
86 e.getInvalidFields().contains(
87 new InvalidEventEnvelopException.InvalidField(
88 UNEXPECTED,"schema", null, EXPECTED_SCHEMA_EXCEPTION_MESSAGE))
89 e.getInvalidFields().contains(
90 new InvalidEventEnvelopException.InvalidField(
91 MISSING, "id", null, null))
92 e.getInvalidFields().contains(
93 new InvalidEventEnvelopException.InvalidField(
94 UNEXPECTED, "source", null, EventFixtures.defaultEventSource.toString()))
95 e.getInvalidFields().contains(
96 new InvalidEventEnvelopException.InvalidField(
97 UNEXPECTED, "type", null, EventFixtures.defaultEventType))
98 e.getMessage().contains(e.getInvalidFields().toString())
101 def 'Event message consumption fails because of invalid envelop'() {
102 when: 'an event with an invalid envelop is received'
104 new CpsDataUpdatedEvent()
106 .withSchema(anEventSchema)
107 .withSource(anEventSource)
108 .withType(anEventType)
109 objectUnderTest.consume(invalidEvent)
110 then: 'an exception is thrown with 2 invalid fields'
111 def e = thrown(InvalidEventEnvelopException)
112 e.getCpsDataUpdatedEvent() == invalidEvent
113 e.getInvalidFields().size() == 3
114 e.getInvalidFields().contains(
115 new InvalidEventEnvelopException.InvalidField(
116 UNEXPECTED, "schema", anEventSchema.toString(),
117 EXPECTED_SCHEMA_EXCEPTION_MESSAGE))
118 e.getInvalidFields().contains(
119 new InvalidEventEnvelopException.InvalidField(
120 UNEXPECTED, "type", anEventType, EventFixtures.defaultEventType))
121 e.getInvalidFields().contains(
122 new InvalidEventEnvelopException.InvalidField(
123 UNEXPECTED, "source", anEventSource.toString(),
124 EventFixtures.defaultEventSource.toString()))