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
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.
17 * SPDX-License-Identifier: Apache-2.0
18 * ============LICENSE_END=========================================================
21 package org.onap.cps.ncmp.impl.cmnotificationsubscription.cmavc;
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;
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;
44 @RequiredArgsConstructor
45 public class CmAvcEventService {
47 private static final OffsetDateTime NO_TIMESTAMP = null;
49 private final CpsDataService cpsDataService;
50 private final CpsAnchorService cpsAnchorService;
51 private final JsonObjectMapper jsonObjectMapper;
52 private final YangParser yangParser;
55 * Process the incoming AvcEvent and apply the changes to the cache.
57 * @param cmHandleId cm handle identifier
58 * @param cmAvcEvent cm avc event
60 public void processCmAvcEvent(final String cmHandleId, final AvcEvent cmAvcEvent) {
62 final List<Edit> edits =
63 cmAvcEvent.getData().getPushChangeUpdate().getDatastoreChanges().getIetfYangPatchYangPatch().getEdit();
66 edit -> handleCmAvcEventOperation(CmAvcOperationEnum.fromValue(edit.getOperation()), cmHandleId, edit));
69 private void handleCmAvcEventOperation(final CmAvcOperationEnum cmAvcOperation, final String cmHandleId,
70 final Edit cmAvcEventEdit) {
72 log.info("Operation : {} requested for cmHandleId : {}", cmAvcOperation.getValue(), cmHandleId);
74 switch (cmAvcOperation) {
76 handleCreate(cmHandleId, cmAvcEventEdit);
80 handleUpdate(cmHandleId, cmAvcEventEdit);
84 handlePatch(cmHandleId, cmAvcEventEdit);
88 handleDelete(cmHandleId, cmAvcEventEdit);
92 log.error("Unhandled operation : {} for cmHandleId : {}", cmAvcOperation, cmHandleId);
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);
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);
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);
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);
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);
136 private String extractNodeData(final Edit cmAvcEventEdit) {
137 return jsonObjectMapper.convertJsonString(jsonObjectMapper.asJsonString(cmAvcEventEdit.getValue()),
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);
147 private String resolveParentNodeXpath(final String parentNodeXpath) {
148 return parentNodeXpath.isEmpty() ? CpsPathUtil.ROOT_NODE_XPATH : parentNodeXpath;