2 * ============LICENSE_START=======================================================
3 * Copyright (C) 2022 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.api.impl;
23 import static org.onap.cps.ncmp.api.impl.utils.RestQueryParametersValidator.validateCpsPathConditionProperties;
24 import static org.onap.cps.ncmp.api.impl.utils.RestQueryParametersValidator.validateModuleNameConditionProperties;
25 import static org.onap.cps.ncmp.api.impl.utils.YangDataConverter.convertYangModelCmHandleToNcmpServiceCmHandle;
26 import static org.onap.cps.spi.FetchDescendantsOption.FETCH_DIRECT_CHILDREN_ONLY;
27 import static org.onap.cps.spi.FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS;
29 import java.util.ArrayList;
30 import java.util.Collection;
31 import java.util.Collections;
32 import java.util.HashMap;
33 import java.util.HashSet;
34 import java.util.List;
37 import java.util.function.Function;
38 import java.util.stream.Collectors;
39 import lombok.RequiredArgsConstructor;
40 import lombok.extern.slf4j.Slf4j;
41 import org.onap.cps.cpspath.parser.PathParsingException;
42 import org.onap.cps.ncmp.api.NetworkCmProxyCmHandlerQueryService;
43 import org.onap.cps.ncmp.api.impl.utils.CmHandleQueryConditions;
44 import org.onap.cps.ncmp.api.impl.utils.InventoryQueryConditions;
45 import org.onap.cps.ncmp.api.impl.utils.YangDataConverter;
46 import org.onap.cps.ncmp.api.inventory.CmHandleQueries;
47 import org.onap.cps.ncmp.api.inventory.InventoryPersistence;
48 import org.onap.cps.ncmp.api.inventory.enums.PropertyType;
49 import org.onap.cps.ncmp.api.models.CmHandleQueryServiceParameters;
50 import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle;
51 import org.onap.cps.spi.exceptions.DataValidationException;
52 import org.onap.cps.spi.model.Anchor;
53 import org.onap.cps.spi.model.ConditionProperties;
54 import org.onap.cps.spi.model.DataNode;
55 import org.springframework.stereotype.Service;
59 @RequiredArgsConstructor
60 public class NetworkCmProxyCmHandlerQueryServiceImpl implements NetworkCmProxyCmHandlerQueryService {
62 private static final Map<String, NcmpServiceCmHandle> NO_QUERY_TO_EXECUTE = null;
63 private final CmHandleQueries cmHandleQueries;
64 private final InventoryPersistence inventoryPersistence;
67 * Query and return cm handles that match the given query parameters.
69 * @param cmHandleQueryServiceParameters the cm handle query parameters
70 * @return collection of cm handles
73 public Set<NcmpServiceCmHandle> queryCmHandles(
74 final CmHandleQueryServiceParameters cmHandleQueryServiceParameters) {
76 if (cmHandleQueryServiceParameters.getCmHandleQueryParameters().isEmpty()) {
77 return getAllCmHandles();
80 final Map<String, NcmpServiceCmHandle> combinedQueryResult = executeInventoryQueries(
81 cmHandleQueryServiceParameters);
83 return new HashSet<>(combineWithModuleNameQuery(cmHandleQueryServiceParameters, combinedQueryResult).values());
87 * Query and return cm handles that match the given query parameters.
89 * @param cmHandleQueryServiceParameters the cm handle query parameters
90 * @return collection of cm handle ids
93 public Set<String> queryCmHandleIds(
94 final CmHandleQueryServiceParameters cmHandleQueryServiceParameters) {
96 if (cmHandleQueryServiceParameters.getCmHandleQueryParameters().isEmpty()) {
97 return getAllCmHandleIds();
100 final Map<String, NcmpServiceCmHandle> combinedQueryResult = executeInventoryQueries(
101 cmHandleQueryServiceParameters);
103 final Collection<String> moduleNamesForQuery =
104 getModuleNamesForQuery(cmHandleQueryServiceParameters.getCmHandleQueryParameters());
105 if (moduleNamesForQuery.isEmpty()) {
106 return combinedQueryResult.keySet();
108 final Set<String> moduleNameQueryResult = getNamesOfAnchorsWithGivenModules(moduleNamesForQuery);
110 if (combinedQueryResult == NO_QUERY_TO_EXECUTE) {
111 return moduleNameQueryResult;
114 moduleNameQueryResult.retainAll(combinedQueryResult.keySet());
115 return moduleNameQueryResult;
119 public Set<String> queryCmHandleIdsForInventory(
120 final CmHandleQueryServiceParameters cmHandleQueryServiceParameters) {
122 if (cmHandleQueryServiceParameters.getCmHandleQueryParameters().isEmpty()) {
123 return getAllCmHandleIds();
126 final Map<String, NcmpServiceCmHandle> publicPropertiesQueryResult = queryCmHandlesByPublicProperties(
127 cmHandleQueryServiceParameters);
128 if (publicPropertiesQueryResult != null && publicPropertiesQueryResult.isEmpty()) {
129 return Collections.emptySet();
132 final Map<String, NcmpServiceCmHandle> privatePropertiesQueryResult = queryCmHandlesByPrivateProperties(
133 cmHandleQueryServiceParameters);
134 if (privatePropertiesQueryResult != null && privatePropertiesQueryResult.isEmpty()) {
135 return Collections.emptySet();
138 final Map<String, NcmpServiceCmHandle> dmiPropertiesQueryResult = queryCmHandlesByDmiPlugin(
139 cmHandleQueryServiceParameters);
140 if (dmiPropertiesQueryResult != null && dmiPropertiesQueryResult.isEmpty()) {
141 return Collections.emptySet();
144 final Map<String, NcmpServiceCmHandle> combinedResult =
145 combineQueryResults(publicPropertiesQueryResult, privatePropertiesQueryResult, dmiPropertiesQueryResult);
147 return combinedResult.keySet();
150 private Map<String, NcmpServiceCmHandle> queryCmHandlesByDmiPlugin(
151 final CmHandleQueryServiceParameters cmHandleQueryServiceParameters) {
152 final Map<String, String> dmiPropertyQueryPairs =
153 getPropertyPairs(cmHandleQueryServiceParameters.getCmHandleQueryParameters(),
154 InventoryQueryConditions.CM_HANDLE_WITH_DMI_PLUGIN.getName());
155 if (dmiPropertyQueryPairs.isEmpty()) {
156 return NO_QUERY_TO_EXECUTE;
159 final String dmiPluginIdentifierValue = dmiPropertyQueryPairs.get(
160 PropertyType.DMI_PLUGIN.getYangContainerName());
162 final Set<NcmpServiceCmHandle> cmHandlesByDmiPluginIdentifier = cmHandleQueries
163 .getCmHandlesByDmiPluginIdentifier(dmiPluginIdentifierValue);
165 return cmHandlesByDmiPluginIdentifier.stream()
166 .collect(Collectors.toMap(NcmpServiceCmHandle::getCmHandleId, cmH -> cmH));
169 private Map<String, NcmpServiceCmHandle> queryCmHandlesByPrivateProperties(
170 final CmHandleQueryServiceParameters cmHandleQueryServiceParameters) {
172 final Map<String, String> privatePropertyQueryPairs =
173 getPropertyPairs(cmHandleQueryServiceParameters.getCmHandleQueryParameters(),
174 InventoryQueryConditions.HAS_ALL_ADDITIONAL_PROPERTIES.getName());
176 return privatePropertyQueryPairs.isEmpty()
177 ? NO_QUERY_TO_EXECUTE
178 : cmHandleQueries.queryCmHandleAdditionalProperties(privatePropertyQueryPairs);
181 private Map<String, NcmpServiceCmHandle> queryCmHandlesByPublicProperties(
182 final CmHandleQueryServiceParameters cmHandleQueryServiceParameters) {
184 final Map<String, String> publicPropertyQueryPairs =
185 getPropertyPairs(cmHandleQueryServiceParameters.getCmHandleQueryParameters(),
186 CmHandleQueryConditions.HAS_ALL_PROPERTIES.getConditionName());
188 return publicPropertyQueryPairs.isEmpty()
189 ? NO_QUERY_TO_EXECUTE
190 : cmHandleQueries.queryCmHandlePublicProperties(publicPropertyQueryPairs);
193 private Map<String, NcmpServiceCmHandle> combineQueryResults(
194 final Map<String, NcmpServiceCmHandle> publicPropertiesQueryResult,
195 final Map<String, NcmpServiceCmHandle> privatePropertiesQueryResult,
196 final Map<String, NcmpServiceCmHandle> dmiPropertiesQueryResult) {
198 final Map<String, NcmpServiceCmHandle> propertiesCombinedResult = cmHandleQueries
199 .combineCmHandleQueries(publicPropertiesQueryResult, privatePropertiesQueryResult);
200 return cmHandleQueries
201 .combineCmHandleQueries(propertiesCombinedResult, dmiPropertiesQueryResult);
204 private Map<String, NcmpServiceCmHandle> combineWithModuleNameQuery(
205 final CmHandleQueryServiceParameters cmHandleQueryServiceParameters,
206 final Map<String, NcmpServiceCmHandle> previousQueryResult) {
207 final Collection<String> moduleNamesForQuery =
208 getModuleNamesForQuery(cmHandleQueryServiceParameters.getCmHandleQueryParameters());
209 if (moduleNamesForQuery.isEmpty()) {
210 return previousQueryResult;
212 final Collection<String> cmHandleIdsByModuleName = getNamesOfAnchorsWithGivenModules(moduleNamesForQuery);
213 if (cmHandleIdsByModuleName.isEmpty()) {
214 return Collections.emptyMap();
216 final Map<String, NcmpServiceCmHandle> queryResult = new HashMap<>(cmHandleIdsByModuleName.size());
217 if (previousQueryResult == NO_QUERY_TO_EXECUTE) {
218 cmHandleIdsByModuleName.forEach(cmHandleId ->
219 queryResult.put(cmHandleId, createNcmpServiceCmHandle(
220 inventoryPersistence.getDataNode("/dmi-registry/cm-handles[@id='" + cmHandleId + "']")))
224 previousQueryResult.keySet().retainAll(cmHandleIdsByModuleName);
225 queryResult.putAll(previousQueryResult);
229 private Map<String, NcmpServiceCmHandle> executeInventoryQueries(
230 final CmHandleQueryServiceParameters cmHandleQueryServiceParameters) {
231 final Map<String, String> cpsPath = getCpsPath(cmHandleQueryServiceParameters.getCmHandleQueryParameters());
232 if (!validateCpsPathConditionProperties(cpsPath)) {
233 return Collections.emptyMap();
235 final Map<String, NcmpServiceCmHandle> cpsPathQueryResult;
236 if (cpsPath.isEmpty()) {
237 cpsPathQueryResult = NO_QUERY_TO_EXECUTE;
240 cpsPathQueryResult = cmHandleQueries.queryCmHandleDataNodesByCpsPath(
241 cpsPath.get("cpsPath"), INCLUDE_ALL_DESCENDANTS)
242 .stream().map(this::createNcmpServiceCmHandle)
243 .collect(Collectors.toMap(NcmpServiceCmHandle::getCmHandleId,
244 Function.identity()));
245 } catch (final PathParsingException pathParsingException) {
246 throw new DataValidationException(pathParsingException.getMessage(), pathParsingException.getDetails(),
247 pathParsingException);
249 if (cpsPathQueryResult.isEmpty()) {
250 return Collections.emptyMap();
254 final Map<String, String> publicPropertyQueryPairs =
255 getPropertyPairs(cmHandleQueryServiceParameters.getCmHandleQueryParameters(),
256 CmHandleQueryConditions.HAS_ALL_PROPERTIES.getConditionName());
257 final Map<String, NcmpServiceCmHandle> propertiesQueryResult = publicPropertyQueryPairs.isEmpty()
258 ? NO_QUERY_TO_EXECUTE : cmHandleQueries.queryCmHandlePublicProperties(publicPropertyQueryPairs);
260 return cmHandleQueries.combineCmHandleQueries(cpsPathQueryResult, propertiesQueryResult);
263 private Set<String> getNamesOfAnchorsWithGivenModules(final Collection<String> moduleNamesForQuery) {
264 final Collection<Anchor> anchors = inventoryPersistence.queryAnchors(moduleNamesForQuery);
265 return anchors.parallelStream().map(Anchor::getName).collect(Collectors.toSet());
268 private Collection<String> getModuleNamesForQuery(final List<ConditionProperties> conditionProperties) {
269 final List<String> result = new ArrayList<>();
270 getConditions(conditionProperties, CmHandleQueryConditions.HAS_ALL_MODULES.getConditionName())
271 .parallelStream().forEach(
272 conditionProperty -> {
273 validateModuleNameConditionProperties(conditionProperty);
274 result.add(conditionProperty.get("moduleName"));
280 private Map<String, String> getCpsPath(final List<ConditionProperties> conditionProperties) {
281 final Map<String, String> result = new HashMap<>();
282 getConditions(conditionProperties, CmHandleQueryConditions.WITH_CPS_PATH.getConditionName()).forEach(
287 private Map<String, String> getPropertyPairs(final List<ConditionProperties> conditionProperties,
288 final String queryProperty) {
289 final Map<String, String> result = new HashMap<>();
290 getConditions(conditionProperties, queryProperty).forEach(result::putAll);
294 private List<Map<String, String>> getConditions(final List<ConditionProperties> conditionProperties,
296 for (final ConditionProperties conditionProperty : conditionProperties) {
297 if (conditionProperty.getConditionName().equals(name)) {
298 return conditionProperty.getConditionParameters();
301 return Collections.emptyList();
304 private Set<NcmpServiceCmHandle> getAllCmHandles() {
305 return inventoryPersistence.getDataNode("/dmi-registry")
306 .getChildDataNodes().stream().map(this::createNcmpServiceCmHandle).collect(Collectors.toSet());
309 private Set<String> getAllCmHandleIds() {
310 return inventoryPersistence.getDataNode("/dmi-registry", FETCH_DIRECT_CHILDREN_ONLY)
311 .getChildDataNodes().stream().map(dataNode -> dataNode.getLeaves().get("id").toString())
312 .collect(Collectors.toSet());
315 private NcmpServiceCmHandle createNcmpServiceCmHandle(final DataNode dataNode) {
316 return convertYangModelCmHandleToNcmpServiceCmHandle(YangDataConverter
317 .convertCmHandleToYangModel(dataNode, dataNode.getLeaves().get("id").toString()));