061fe56c8a45eede1ebc63ddaeb0657456dd0ffe
[cps.git] /
1 /*
2  * ============LICENSE_START=======================================================
3  * Copyright (c) 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.cmnotificationsubscription.cmavc;
22
23 import static org.onap.cps.cpspath.parser.CpsPathUtil.NO_PARENT_PATH;
24 import static org.onap.cps.cpspath.parser.CpsPathUtil.getNormalizedParentXpath;
25 import static org.onap.cps.ncmp.impl.inventory.NcmpPersistence.NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME;
26 import static org.onap.cps.utils.ContentType.JSON;
27
28 import java.time.OffsetDateTime;
29 import java.util.List;
30 import lombok.RequiredArgsConstructor;
31 import lombok.extern.slf4j.Slf4j;
32 import org.onap.cps.api.CpsAnchorService;
33 import org.onap.cps.api.CpsDataService;
34 import org.onap.cps.api.model.Anchor;
35 import org.onap.cps.cpspath.parser.CpsPathUtil;
36 import org.onap.cps.ncmp.events.avc1_0_0.AvcEvent;
37 import org.onap.cps.ncmp.events.avc1_0_0.Edit;
38 import org.onap.cps.utils.JsonObjectMapper;
39 import org.onap.cps.utils.YangParser;
40 import org.springframework.stereotype.Service;
41
42 @Slf4j
43 @Service
44 @RequiredArgsConstructor
45 public class CmAvcEventService {
46
47     private static final OffsetDateTime NO_TIMESTAMP = null;
48
49     private final CpsDataService cpsDataService;
50     private final CpsAnchorService cpsAnchorService;
51     private final JsonObjectMapper jsonObjectMapper;
52     private final YangParser yangParser;
53
54     /**
55      * Process the incoming AvcEvent and apply the changes to the cache.
56      *
57      * @param cmHandleId cm handle identifier
58      * @param cmAvcEvent cm avc event
59      */
60     public void processCmAvcEvent(final String cmHandleId, final AvcEvent cmAvcEvent) {
61
62         final List<Edit> edits =
63                 cmAvcEvent.getData().getPushChangeUpdate().getDatastoreChanges().getIetfYangPatchYangPatch().getEdit();
64
65         edits.forEach(
66                 edit -> handleCmAvcEventOperation(CmAvcOperationEnum.fromValue(edit.getOperation()), cmHandleId, edit));
67     }
68
69     private void handleCmAvcEventOperation(final CmAvcOperationEnum cmAvcOperation, final String cmHandleId,
70             final Edit cmAvcEventEdit) {
71
72         log.info("Operation : {} requested for cmHandleId : {}", cmAvcOperation.getValue(), cmHandleId);
73
74         switch (cmAvcOperation) {
75             case CREATE:
76                 handleCreate(cmHandleId, cmAvcEventEdit);
77                 break;
78
79             case UPDATE:
80                 handleUpdate(cmHandleId, cmAvcEventEdit);
81                 break;
82
83             case PATCH:
84                 handlePatch(cmHandleId, cmAvcEventEdit);
85                 break;
86
87             case DELETE:
88                 handleDelete(cmHandleId, cmAvcEventEdit);
89                 break;
90
91             default:
92                 log.error("Unhandled operation : {} for cmHandleId : {}", cmAvcOperation, cmHandleId);
93         }
94     }
95
96     private void handleCreate(final String cmHandleId, final Edit cmAvcEventEdit) {
97         log.debug("Handling create operation for cmHandleId : {}", cmHandleId);
98         final String jsonData = extractNodeData(cmAvcEventEdit);
99         cpsDataService.saveData(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, cmHandleId, jsonData, NO_TIMESTAMP);
100     }
101
102     private void handleUpdate(final String cmHandleId, final Edit cmAvcEventEdit) {
103         final String jsonData = extractNodeData(cmAvcEventEdit);
104         final String cpsPathFromRestConfStylePath = getCpsPath(cmHandleId, cmAvcEventEdit.getTarget());
105         final String parentXpath = getNormalizedParentXpath(cpsPathFromRestConfStylePath);
106         log.debug("Handling update operation for cmHandleId : {} , cpsPath : {} and parent-xpath : {}", cmHandleId,
107                 cpsPathFromRestConfStylePath, parentXpath);
108         cpsDataService.updateDataNodeAndDescendants(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, cmHandleId,
109                 resolveParentNodeXpath(parentXpath), jsonData, NO_TIMESTAMP, JSON);
110     }
111
112     private void handlePatch(final String cmHandleId, final Edit cmAvcEventEdit) {
113         final String jsonData = extractNodeData(cmAvcEventEdit);
114         final String cpsPathFromRestConfStylePath = getCpsPath(cmHandleId, cmAvcEventEdit.getTarget());
115         final String parentXpath = getNormalizedParentXpath(cpsPathFromRestConfStylePath);
116         log.debug("Handling patch operation for cmHandleId : {} , cpsPath : {} and parent-xpath : {}", cmHandleId,
117                 cpsPathFromRestConfStylePath, parentXpath);
118         cpsDataService.updateNodeLeaves(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, cmHandleId,
119                 resolveParentNodeXpath(parentXpath), jsonData, NO_TIMESTAMP, JSON);
120
121     }
122
123     private void handleDelete(final String cmHandleId, final Edit cmAvcEventEdit) {
124         if (NO_PARENT_PATH.equals(cmAvcEventEdit.getTarget()) || cmAvcEventEdit.getTarget() == null) {
125             log.debug("Deleting all the entries for cmHandleId : {}", cmHandleId);
126             cpsDataService.deleteDataNodes(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, cmHandleId, NO_TIMESTAMP);
127         } else {
128             final String cpsPathFromRestConfStylePath = getCpsPath(cmHandleId, cmAvcEventEdit.getTarget());
129             log.debug("Deleting data for xpath : {}", cpsPathFromRestConfStylePath);
130             cpsDataService.deleteDataNode(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, cmHandleId,
131                     cpsPathFromRestConfStylePath, NO_TIMESTAMP);
132
133         }
134     }
135
136     private String extractNodeData(final Edit cmAvcEventEdit) {
137         return jsonObjectMapper.convertJsonString(jsonObjectMapper.asJsonString(cmAvcEventEdit.getValue()),
138                 String.class);
139     }
140
141     private String getCpsPath(final String cmHandleId, final String restConfStylePath) {
142         log.debug("Getting cps path from the restconfpath : {}", restConfStylePath);
143         final Anchor anchor = cpsAnchorService.getAnchor(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, cmHandleId);
144         return yangParser.getCpsPathFromRestConfStylePath(anchor, restConfStylePath);
145     }
146
147     private String resolveParentNodeXpath(final String parentNodeXpath) {
148         return parentNodeXpath.isEmpty() ? CpsPathUtil.ROOT_NODE_XPATH : parentNodeXpath;
149     }
150
151 }