2 * ============LICENSE_START=======================================================
3 * Copyright (C) 2022-2025 Nordix Foundation
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.inventory;
23 import static org.onap.cps.api.parameters.FetchDescendantsOption.DIRECT_CHILDREN_ONLY;
24 import static org.onap.cps.api.parameters.FetchDescendantsOption.OMIT_DESCENDANTS;
25 import static org.onap.cps.ncmp.impl.inventory.CmHandleQueryParametersValidator.validateCpsPathConditionProperties;
26 import static org.onap.cps.ncmp.impl.inventory.CmHandleQueryParametersValidator.validateModuleNameConditionProperties;
27 import static org.onap.cps.ncmp.impl.inventory.NcmpPersistence.NCMP_DMI_REGISTRY_PARENT;
28 import static org.onap.cps.ncmp.impl.inventory.models.CmHandleQueryConditions.HAS_ALL_MODULES;
29 import static org.onap.cps.ncmp.impl.inventory.models.CmHandleQueryConditions.HAS_ALL_PROPERTIES;
30 import static org.onap.cps.ncmp.impl.inventory.models.CmHandleQueryConditions.WITH_CPS_PATH;
31 import static org.onap.cps.ncmp.impl.inventory.models.CmHandleQueryConditions.WITH_TRUST_LEVEL;
32 import static org.onap.cps.ncmp.impl.utils.YangDataConverter.toNcmpServiceCmHandle;
34 import java.util.ArrayList;
35 import java.util.Collection;
36 import java.util.Collections;
37 import java.util.HashMap;
38 import java.util.List;
40 import java.util.function.BiFunction;
41 import java.util.stream.Collectors;
42 import lombok.RequiredArgsConstructor;
43 import org.onap.cps.api.exceptions.DataValidationException;
44 import org.onap.cps.api.model.ConditionProperties;
45 import org.onap.cps.api.model.DataNode;
46 import org.onap.cps.cpspath.parser.PathParsingException;
47 import org.onap.cps.ncmp.api.inventory.models.CmHandleQueryServiceParameters;
48 import org.onap.cps.ncmp.api.inventory.models.NcmpServiceCmHandle;
49 import org.onap.cps.ncmp.impl.inventory.models.InventoryQueryConditions;
50 import org.onap.cps.ncmp.impl.inventory.models.PropertyType;
51 import org.onap.cps.ncmp.impl.inventory.models.YangModelCmHandle;
52 import org.onap.cps.ncmp.impl.utils.YangDataConverter;
53 import org.springframework.stereotype.Service;
56 @RequiredArgsConstructor
57 public class ParameterizedCmHandleQueryServiceImpl implements ParameterizedCmHandleQueryService {
59 private static final Collection<String> NO_QUERY_TO_EXECUTE = null;
60 private final CmHandleQueryService cmHandleQueryService;
61 private final InventoryPersistence inventoryPersistence;
64 public Collection<String> queryCmHandleReferenceIds(
65 final CmHandleQueryServiceParameters cmHandleQueryServiceParameters,
66 final boolean outputAlternateId) {
67 return executeQueries(cmHandleQueryServiceParameters, outputAlternateId,
68 this::executeCpsPathQuery,
69 this::queryCmHandlesByPublicProperties,
70 this::executeModuleNameQuery,
71 this::queryCmHandlesByTrustLevel);
75 public Collection<String> queryCmHandleIdsForInventory(
76 final CmHandleQueryServiceParameters cmHandleQueryServiceParameters,
77 final boolean outputAlternateId) {
78 return executeQueries(cmHandleQueryServiceParameters, outputAlternateId,
79 this::executeCpsPathQuery,
80 this::queryCmHandlesByPublicProperties,
81 this::queryCmHandlesByPrivateProperties,
82 this::queryCmHandlesByDmiPlugin);
86 public Collection<NcmpServiceCmHandle> queryCmHandles(
87 final CmHandleQueryServiceParameters cmHandleQueryServiceParameters) {
89 if (cmHandleQueryServiceParameters.getCmHandleQueryParameters().isEmpty()) {
90 return getAllCmHandles();
93 final Collection<String> cmHandleIds = queryCmHandleReferenceIds(cmHandleQueryServiceParameters, false);
95 return getNcmpServiceCmHandles(cmHandleIds);
99 public Collection<NcmpServiceCmHandle> getAllCmHandles() {
100 return toNcmpServiceCmHandles(inventoryPersistence.getDataNode(NCMP_DMI_REGISTRY_PARENT));
104 public Collection<NcmpServiceCmHandle> getAllCmHandlesWithoutProperties() {
105 return toNcmpServiceCmHandles(inventoryPersistence.getDataNode(NCMP_DMI_REGISTRY_PARENT, DIRECT_CHILDREN_ONLY));
108 private Collection<NcmpServiceCmHandle> toNcmpServiceCmHandles(final Collection<DataNode> dataNodes) {
109 final DataNode dataNode = dataNodes.iterator().next();
110 return dataNode.getChildDataNodes().stream().map(this::createNcmpServiceCmHandle).collect(Collectors.toSet());
113 private Collection<String> queryCmHandlesByDmiPlugin(
114 final CmHandleQueryServiceParameters cmHandleQueryServiceParameters, final boolean outputAlternateId) {
115 final Map<String, String> dmiPropertyQueryPairs =
116 getPropertyPairs(cmHandleQueryServiceParameters.getCmHandleQueryParameters(),
117 InventoryQueryConditions.CM_HANDLE_WITH_DMI_PLUGIN.getName());
118 if (dmiPropertyQueryPairs.isEmpty()) {
119 return NO_QUERY_TO_EXECUTE;
122 final String dmiPluginIdentifierValue = dmiPropertyQueryPairs
123 .get(PropertyType.DMI_PLUGIN.getYangContainerName());
125 return cmHandleQueryService.getCmHandleReferencesByDmiPluginIdentifier(
126 dmiPluginIdentifierValue, outputAlternateId);
130 private Collection<String> queryCmHandlesByPrivateProperties(
131 final CmHandleQueryServiceParameters cmHandleQueryServiceParameters, final boolean outputAlternateId) {
133 final Map<String, String> privatePropertyQueryPairs =
134 getPropertyPairs(cmHandleQueryServiceParameters.getCmHandleQueryParameters(),
135 InventoryQueryConditions.HAS_ALL_ADDITIONAL_PROPERTIES.getName());
137 if (privatePropertyQueryPairs.isEmpty()) {
138 return NO_QUERY_TO_EXECUTE;
140 return cmHandleQueryService.queryCmHandleAdditionalProperties(privatePropertyQueryPairs, outputAlternateId);
143 private Collection<String> queryCmHandlesByPublicProperties(
144 final CmHandleQueryServiceParameters cmHandleQueryServiceParameters, final boolean outputAlternateId) {
146 final Map<String, String> publicPropertyQueryPairs =
147 getPropertyPairs(cmHandleQueryServiceParameters.getCmHandleQueryParameters(),
148 HAS_ALL_PROPERTIES.getConditionName());
150 if (publicPropertyQueryPairs.isEmpty()) {
151 return NO_QUERY_TO_EXECUTE;
153 return cmHandleQueryService.queryCmHandlePublicProperties(publicPropertyQueryPairs, outputAlternateId);
156 private Collection<String> queryCmHandlesByTrustLevel(final CmHandleQueryServiceParameters
157 cmHandleQueryServiceParameters,
158 final boolean outputAlternateId) {
160 final Map<String, String> trustLevelPropertyQueryPairs =
161 getPropertyPairs(cmHandleQueryServiceParameters.getCmHandleQueryParameters(),
162 WITH_TRUST_LEVEL.getConditionName());
164 if (trustLevelPropertyQueryPairs.isEmpty()) {
165 return NO_QUERY_TO_EXECUTE;
167 return cmHandleQueryService.queryCmHandlesByTrustLevel(trustLevelPropertyQueryPairs, outputAlternateId);
170 private Collection<String> executeModuleNameQuery(
171 final CmHandleQueryServiceParameters cmHandleQueryServiceParameters, final boolean outputAlternateId) {
172 final Collection<String> moduleNamesForQuery =
173 getModuleNamesForQuery(cmHandleQueryServiceParameters.getCmHandleQueryParameters());
174 if (moduleNamesForQuery.isEmpty()) {
175 return NO_QUERY_TO_EXECUTE;
177 return inventoryPersistence.getCmHandleReferencesWithGivenModules(moduleNamesForQuery, outputAlternateId);
180 private Collection<String> executeCpsPathQuery(
181 final CmHandleQueryServiceParameters cmHandleQueryServiceParameters, final boolean outputAlternateId) {
182 final Map<String, String> cpsPathCondition
183 = getCpsPathCondition(cmHandleQueryServiceParameters.getCmHandleQueryParameters());
184 if (!validateCpsPathConditionProperties(cpsPathCondition)) {
185 return Collections.emptySet();
187 final Collection<String> cpsPathQueryResult;
188 if (cpsPathCondition.isEmpty()) {
189 return NO_QUERY_TO_EXECUTE;
192 cpsPathQueryResult = collectCmHandleReferencesFromDataNodes(
193 cmHandleQueryService.queryCmHandleAncestorsByCpsPath(cpsPathCondition.get("cpsPath"),
194 OMIT_DESCENDANTS), outputAlternateId);
195 } catch (final PathParsingException pathParsingException) {
196 throw new DataValidationException(pathParsingException.getMessage(), pathParsingException.getDetails(),
197 pathParsingException);
199 return cpsPathQueryResult;
202 private Collection<String> getModuleNamesForQuery(final List<ConditionProperties> conditionProperties) {
203 final List<String> result = new ArrayList<>();
204 getConditions(conditionProperties, HAS_ALL_MODULES.getConditionName()).forEach(
205 conditionProperty -> {
206 validateModuleNameConditionProperties(conditionProperty);
207 result.add(conditionProperty.get("moduleName"));
212 private Map<String, String> getCpsPathCondition(final List<ConditionProperties> conditionProperties) {
213 final Map<String, String> result = new HashMap<>();
214 getConditions(conditionProperties, WITH_CPS_PATH.getConditionName()).forEach(result::putAll);
218 private Map<String, String> getPropertyPairs(final List<ConditionProperties> conditionProperties,
219 final String queryProperty) {
220 final Map<String, String> result = new HashMap<>();
221 getConditions(conditionProperties, queryProperty).forEach(result::putAll);
225 private List<Map<String, String>> getConditions(final List<ConditionProperties> conditionProperties,
227 for (final ConditionProperties conditionProperty : conditionProperties) {
228 if (conditionProperty.getConditionName().equals(name)) {
229 return conditionProperty.getConditionParameters();
232 return Collections.emptyList();
235 private Collection<String> getAllCmHandleReferences(final boolean outputAlternateId) {
236 return cmHandleQueryService.getAllCmHandleReferences(outputAlternateId);
239 private Collection<NcmpServiceCmHandle> getNcmpServiceCmHandles(final Collection<String> cmHandleIds) {
240 final Collection<YangModelCmHandle> yangModelcmHandles
241 = inventoryPersistence.getYangModelCmHandles(cmHandleIds);
243 final Collection<NcmpServiceCmHandle> ncmpServiceCmHandles = new ArrayList<>(yangModelcmHandles.size());
245 yangModelcmHandles.forEach(yangModelcmHandle ->
246 ncmpServiceCmHandles.add(YangDataConverter.toNcmpServiceCmHandle(yangModelcmHandle))
248 return ncmpServiceCmHandles;
251 private NcmpServiceCmHandle createNcmpServiceCmHandle(final DataNode dataNode) {
252 return toNcmpServiceCmHandle(YangDataConverter.toYangModelCmHandle(dataNode));
255 private Collection<String> executeQueries(final CmHandleQueryServiceParameters cmHandleQueryServiceParameters,
256 final boolean outputAlternateId,
257 final BiFunction<CmHandleQueryServiceParameters, Boolean,
258 Collection<String>>... queryFunctions) {
259 if (cmHandleQueryServiceParameters.getCmHandleQueryParameters().isEmpty()) {
260 return getAllCmHandleReferences(outputAlternateId);
262 Collection<String> combinedQueryResult = NO_QUERY_TO_EXECUTE;
263 for (final BiFunction<CmHandleQueryServiceParameters, Boolean,
264 Collection<String>> queryFunction : queryFunctions) {
265 final Collection<String> queryResult = queryFunction.apply(cmHandleQueryServiceParameters,
267 if (noEntriesFoundCanStopQuerying(queryResult)) {
268 return Collections.emptySet();
270 combinedQueryResult = combineCmHandleQueryResults(combinedQueryResult, queryResult);
272 return combinedQueryResult;
275 private boolean noEntriesFoundCanStopQuerying(final Collection<String> queryResult) {
276 return queryResult != NO_QUERY_TO_EXECUTE && queryResult.isEmpty();
279 private Collection<String> combineCmHandleQueryResults(final Collection<String> firstQuery,
280 final Collection<String> secondQuery) {
281 if (firstQuery == NO_QUERY_TO_EXECUTE && secondQuery == NO_QUERY_TO_EXECUTE) {
282 return NO_QUERY_TO_EXECUTE;
283 } else if (firstQuery == NO_QUERY_TO_EXECUTE) {
285 } else if (secondQuery == NO_QUERY_TO_EXECUTE) {
288 firstQuery.retainAll(secondQuery);
293 private Collection<String> collectCmHandleReferencesFromDataNodes(final Collection<DataNode> dataNodes,
294 final boolean outputAlternateId) {
295 if (outputAlternateId) {
296 return dataNodes.stream().map(dataNode ->
297 (String) dataNode.getLeaves().get("alternate-id")).collect(Collectors.toSet());
299 return dataNodes.stream().map(dataNode ->
300 (String) dataNode.getLeaves().get("id")).collect(Collectors.toSet());