e3315c9abade99a7fde83737c64d93b07b0554e8
[cps.git] / cps-service / src / main / java / org / onap / cps / events / CpsDataUpdateEventsService.java
1 /*
2  * ============LICENSE_START=======================================================
3  * Copyright (C) 2024 TechMahindra Ltd.
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.events;
22
23 import io.cloudevents.CloudEvent;
24 import io.micrometer.core.annotation.Timed;
25 import java.time.OffsetDateTime;
26 import java.util.HashMap;
27 import java.util.Map;
28 import lombok.RequiredArgsConstructor;
29 import lombok.extern.slf4j.Slf4j;
30 import org.onap.cps.events.model.CpsDataUpdatedEvent;
31 import org.onap.cps.events.model.Data;
32 import org.onap.cps.events.model.Data.Operation;
33 import org.onap.cps.spi.model.Anchor;
34 import org.springframework.beans.factory.annotation.Value;
35 import org.springframework.stereotype.Service;
36
37 @Slf4j
38 @Service
39 @RequiredArgsConstructor
40 public class CpsDataUpdateEventsService {
41
42     private final EventsPublisher<CpsDataUpdatedEvent> eventsPublisher;
43
44     @Value("${app.cps.data-updated.topic:cps-data-updated-events}")
45     private String topicName;
46
47     @Value("${notification.enabled:false}")
48     private boolean notificationsEnabled;
49
50     /**
51      * Publish the cps data update event with header to the public topic.
52      *
53      * @param anchor Anchor of the updated data
54      * @param xpath  xpath of the updated data
55      * @param operation operation performed on the data
56      * @param observedTimestamp timestamp when data was updated.
57      */
58     @Timed(value = "cps.dataupdate.events.publish", description = "Time taken to publish Data Update event")
59     public void publishCpsDataUpdateEvent(final Anchor anchor, final String xpath,
60                                           final Operation operation, final OffsetDateTime observedTimestamp) {
61         if (notificationsEnabled) {
62             final CpsDataUpdatedEvent cpsDataUpdatedEvent = createCpsDataUpdatedEvent(anchor,
63                     observedTimestamp, xpath, operation);
64             final String updateEventId = anchor.getDataspaceName() + ":" + anchor.getName();
65             final Map<String, String> extensions = createUpdateEventExtensions(updateEventId);
66             final CloudEvent cpsDataUpdatedEventAsCloudEvent =
67                     CpsEvent.builder().type(CpsDataUpdatedEvent.class.getTypeName()).data(cpsDataUpdatedEvent)
68                             .extensions(extensions).build().asCloudEvent();
69             eventsPublisher.publishCloudEvent(topicName, updateEventId, cpsDataUpdatedEventAsCloudEvent);
70         } else {
71             log.debug("Notifications disabled.");
72         }
73     }
74
75     private CpsDataUpdatedEvent createCpsDataUpdatedEvent(final Anchor anchor, final OffsetDateTime observedTimestamp,
76                                                           final String xpath,
77                                                           final Operation rootNodeOperation) {
78         final CpsDataUpdatedEvent cpsDataUpdatedEvent = new CpsDataUpdatedEvent();
79         final Data updateEventData = new Data();
80         updateEventData.setObservedTimestamp(observedTimestamp.toString());
81         updateEventData.setDataspaceName(anchor.getDataspaceName());
82         updateEventData.setAnchorName(anchor.getName());
83         updateEventData.setSchemaSetName(anchor.getSchemaSetName());
84         updateEventData.setOperation(getRootNodeOperation(xpath, rootNodeOperation));
85         updateEventData.setXpath(xpath);
86         cpsDataUpdatedEvent.setData(updateEventData);
87         return cpsDataUpdatedEvent;
88     }
89
90     private Map<String, String> createUpdateEventExtensions(final String eventKey) {
91         final Map<String, String> extensions = new HashMap<>();
92         extensions.put("correlationid", eventKey);
93         return extensions;
94     }
95
96     private Operation getRootNodeOperation(final String xpath, final Operation operation) {
97         return isRootXpath(xpath) || isRootContainerNodeXpath(xpath) ? operation : Operation.UPDATE;
98     }
99
100     private static boolean isRootXpath(final String xpath) {
101         return "/".equals(xpath) || "".equals(xpath);
102     }
103
104     private static boolean isRootContainerNodeXpath(final String xpath) {
105         return 0 == xpath.lastIndexOf('/');
106     }
107 }