2 * ============LICENSE_START=======================================================
3 * Copyright (C) 2022-2024 Nordix Foundation
4 * Modifications Copyright (C) 2022 Bell Canada
5 * Modifications Copyright (C) 2023 TechMahindra Ltd.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
19 * SPDX-License-Identifier: Apache-2.0
20 * ============LICENSE_END=========================================================
23 package org.onap.cps.ncmp.api.impl.inventory;
25 import static org.onap.cps.spi.FetchDescendantsOption.OMIT_DESCENDANTS;
27 import com.google.common.collect.Lists;
28 import java.time.OffsetDateTime;
29 import java.util.ArrayList;
30 import java.util.Collection;
31 import java.util.Collections;
32 import java.util.HashMap;
33 import java.util.List;
35 import lombok.extern.slf4j.Slf4j;
36 import org.onap.cps.api.CpsAnchorService;
37 import org.onap.cps.api.CpsDataService;
38 import org.onap.cps.api.CpsModuleService;
39 import org.onap.cps.ncmp.api.impl.utils.YangDataConverter;
40 import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle;
41 import org.onap.cps.spi.FetchDescendantsOption;
42 import org.onap.cps.spi.exceptions.DataNodeNotFoundException;
43 import org.onap.cps.spi.exceptions.DataValidationException;
44 import org.onap.cps.spi.model.DataNode;
45 import org.onap.cps.spi.model.ModuleDefinition;
46 import org.onap.cps.spi.model.ModuleReference;
47 import org.onap.cps.spi.utils.CpsValidator;
48 import org.onap.cps.utils.JsonObjectMapper;
49 import org.springframework.stereotype.Component;
53 public class InventoryPersistenceImpl extends NcmpPersistenceImpl implements InventoryPersistence {
55 private static final int CMHANDLE_BATCH_SIZE = 100;
57 private final CpsModuleService cpsModuleService;
58 private final CpsAnchorService cpsAnchorService;
59 private final CpsValidator cpsValidator;
60 private final CmHandleQueries cmHandleQueries;
63 * initialize an inventory persistence object.
65 * @param jsonObjectMapper json mapper object
66 * @param cpsDataService cps data service instance
67 * @param cpsModuleService cps module service instance
68 * @param cpsValidator cps validation service instance
69 * @param cpsAnchorService cps anchor service instance
71 public InventoryPersistenceImpl(final JsonObjectMapper jsonObjectMapper, final CpsDataService cpsDataService,
72 final CpsModuleService cpsModuleService, final CpsValidator cpsValidator,
73 final CpsAnchorService cpsAnchorService, final CmHandleQueries cmHandleQueries) {
74 super(jsonObjectMapper, cpsDataService, cpsModuleService, cpsValidator);
75 this.cpsModuleService = cpsModuleService;
76 this.cpsAnchorService = cpsAnchorService;
77 this.cpsValidator = cpsValidator;
78 this.cmHandleQueries = cmHandleQueries;
83 public CompositeState getCmHandleState(final String cmHandleId) {
84 final DataNode stateAsDataNode = cpsDataService.getDataNodes(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR,
85 getXPathForCmHandleById(cmHandleId) + "/state", FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS)
87 cpsValidator.validateNameCharacters(cmHandleId);
88 return new CompositeStateBuilder().fromDataNode(stateAsDataNode).build();
92 public void saveCmHandleState(final String cmHandleId, final CompositeState compositeState) {
93 final String cmHandleJsonData = createStateJsonData(jsonObjectMapper.asJsonString(compositeState));
94 cpsDataService.updateDataNodeAndDescendants(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR,
95 getXPathForCmHandleById(cmHandleId), cmHandleJsonData, OffsetDateTime.now());
99 public void saveCmHandleStateBatch(final Map<String, CompositeState> cmHandleStatePerCmHandleId) {
100 final Map<String, String> cmHandlesJsonDataMap = new HashMap<>();
101 cmHandleStatePerCmHandleId.forEach((cmHandleId, compositeState) -> cmHandlesJsonDataMap.put(
102 getXPathForCmHandleById(cmHandleId),
103 createStateJsonData(jsonObjectMapper.asJsonString(compositeState))));
104 cpsDataService.updateDataNodesAndDescendants(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR,
105 cmHandlesJsonDataMap, OffsetDateTime.now());
109 public YangModelCmHandle getYangModelCmHandle(final String cmHandleId) {
110 cpsValidator.validateNameCharacters(cmHandleId);
111 final DataNode dataNode = getCmHandleDataNodeByCmHandleId(cmHandleId).iterator().next();
112 return YangDataConverter.convertCmHandleToYangModel(dataNode);
116 public Collection<YangModelCmHandle> getYangModelCmHandles(final Collection<String> cmHandleIds) {
117 final Collection<String> validCmHandleIds = new ArrayList<>(cmHandleIds.size());
118 cmHandleIds.forEach(cmHandleId -> {
120 cpsValidator.validateNameCharacters(cmHandleId);
121 validCmHandleIds.add(cmHandleId);
122 } catch (final DataValidationException dataValidationException) {
123 log.error("DataValidationException in CmHandleId {} to be ignored",
124 dataValidationException.getMessage());
127 return YangDataConverter.convertDataNodesToYangModelCmHandles(getCmHandleDataNodes(validCmHandleIds));
131 public Collection<ModuleDefinition> getModuleDefinitionsByCmHandleId(final String cmHandleId) {
132 return cpsModuleService.getModuleDefinitionsByAnchorName(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, cmHandleId);
136 public Collection<ModuleDefinition> getModuleDefinitionsByCmHandleAndModule(final String cmHandleId,
137 final String moduleName,
138 final String moduleRevision) {
139 cpsValidator.validateNameCharacters(cmHandleId, moduleName);
140 return cpsModuleService.getModuleDefinitionsByAnchorAndModule(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME,
141 cmHandleId, moduleName, moduleRevision);
145 public Collection<ModuleReference> getYangResourcesModuleReferences(final String cmHandleId) {
146 cpsValidator.validateNameCharacters(cmHandleId);
147 return cpsModuleService.getYangResourcesModuleReferences(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, cmHandleId);
151 public void saveCmHandle(final YangModelCmHandle yangModelCmHandle) {
152 saveCmHandleBatch(Collections.singletonList(yangModelCmHandle));
156 public void saveCmHandleBatch(final List<YangModelCmHandle> yangModelCmHandles) {
157 for (final List<YangModelCmHandle> yangModelCmHandleBatch :
158 Lists.partition(yangModelCmHandles, CMHANDLE_BATCH_SIZE)) {
159 final String cmHandlesJsonData = createCmHandlesJsonData(yangModelCmHandleBatch);
160 cpsDataService.saveListElements(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR,
161 NCMP_DMI_REGISTRY_PARENT, cmHandlesJsonData, NO_TIMESTAMP);
166 public Collection<DataNode> getCmHandleDataNodeByCmHandleId(final String cmHandleId) {
167 return this.getDataNode(getXPathForCmHandleById(cmHandleId));
171 public DataNode getCmHandleDataNodeByAlternateId(final String alternateId) {
172 final String xPathForCmHandleByAlternateId = getXPathForCmHandleByAlternateId(alternateId);
173 final Collection<DataNode> dataNodes = cmHandleQueries
174 .queryNcmpRegistryByCpsPath(xPathForCmHandleByAlternateId, OMIT_DESCENDANTS);
175 if (dataNodes.isEmpty()) {
176 throw new DataNodeNotFoundException(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR,
177 xPathForCmHandleByAlternateId);
179 return dataNodes.iterator().next();
183 public Collection<DataNode> getCmHandleDataNodes(final Collection<String> cmHandleIds) {
184 final Collection<String> xpaths = new ArrayList<>(cmHandleIds.size());
185 cmHandleIds.forEach(cmHandleId -> xpaths.add(getXPathForCmHandleById(cmHandleId)));
186 return this.getDataNodes(xpaths);
190 public Collection<String> getCmHandleIdsWithGivenModules(final Collection<String> moduleNamesForQuery) {
191 return cpsAnchorService.queryAnchorNames(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, moduleNamesForQuery);
194 private static String getXPathForCmHandleById(final String cmHandleId) {
195 return NCMP_DMI_REGISTRY_PARENT + "/cm-handles[@id='" + cmHandleId + "']";
198 private static String getXPathForCmHandleByAlternateId(final String alternateId) {
199 return NCMP_DMI_REGISTRY_PARENT + "/cm-handles[@alternate-id='" + alternateId + "']";
202 private static String createStateJsonData(final String state) {
203 return "{\"state\":" + state + "}";
206 private String createCmHandlesJsonData(final List<YangModelCmHandle> yangModelCmHandles) {
207 return "{\"cm-handles\":" + jsonObjectMapper.asJsonString(yangModelCmHandles) + "}";