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.YangDataConverter.convertYangModelCmHandleToNcmpServiceCmHandle;
24 import static org.onap.cps.spi.FetchDescendantsOption.FETCH_DIRECT_CHILDREN_ONLY;
25 import static org.onap.cps.spi.FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS;
26 import static org.onap.cps.utils.CmHandleQueryRestParametersValidator.validateCpsPathConditionProperties;
27 import static org.onap.cps.utils.CmHandleQueryRestParametersValidator.validateModuleNameConditionProperties;
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.YangDataConverter;
44 import org.onap.cps.ncmp.api.inventory.CmHandleQueries;
45 import org.onap.cps.ncmp.api.inventory.InventoryPersistence;
46 import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle;
47 import org.onap.cps.spi.exceptions.DataValidationException;
48 import org.onap.cps.spi.model.Anchor;
49 import org.onap.cps.spi.model.CmHandleQueryServiceParameters;
50 import org.onap.cps.spi.model.ConditionProperties;
51 import org.onap.cps.spi.model.DataNode;
52 import org.onap.cps.utils.ValidQueryProperties;
53 import org.springframework.stereotype.Service;
57 @RequiredArgsConstructor
58 public class NetworkCmProxyCmHandlerQueryServiceImpl implements NetworkCmProxyCmHandlerQueryService {
60 private static final Map<String, NcmpServiceCmHandle> NO_QUERY_TO_EXECUTE = null;
61 private final CmHandleQueries cmHandleQueries;
62 private final InventoryPersistence inventoryPersistence;
65 * Query and return cm handles that match the given query parameters.
67 * @param cmHandleQueryServiceParameters the cm handle query parameters
68 * @return collection of cm handles
71 public Set<NcmpServiceCmHandle> queryCmHandles(
72 final CmHandleQueryServiceParameters cmHandleQueryServiceParameters) {
74 if (cmHandleQueryServiceParameters.getCmHandleQueryParameters().isEmpty()) {
75 return getAllCmHandles();
78 final Map<String, NcmpServiceCmHandle> combinedQueryResult = executeInventoryQueries(
79 cmHandleQueryServiceParameters);
81 return new HashSet<>(combineWithModuleNameQuery(cmHandleQueryServiceParameters, combinedQueryResult).values());
85 * Query and return cm handles that match the given query parameters.
87 * @param cmHandleQueryServiceParameters the cm handle query parameters
88 * @return collection of cm handle ids
91 public Set<String> queryCmHandleIds(
92 final CmHandleQueryServiceParameters cmHandleQueryServiceParameters) {
94 if (cmHandleQueryServiceParameters.getCmHandleQueryParameters().isEmpty()) {
95 return getAllCmHandleIds();
98 final Map<String, NcmpServiceCmHandle> combinedQueryResult = executeInventoryQueries(
99 cmHandleQueryServiceParameters);
101 final Collection<String> moduleNamesForQuery =
102 getModuleNamesForQuery(cmHandleQueryServiceParameters.getCmHandleQueryParameters());
103 if (moduleNamesForQuery.isEmpty()) {
104 return combinedQueryResult.keySet();
106 final Set<String> moduleNameQueryResult = getNamesOfAnchorsWithGivenModules(moduleNamesForQuery);
108 if (combinedQueryResult == NO_QUERY_TO_EXECUTE) {
109 return moduleNameQueryResult;
112 moduleNameQueryResult.retainAll(combinedQueryResult.keySet());
113 return moduleNameQueryResult;
116 private Map<String, NcmpServiceCmHandle> combineWithModuleNameQuery(
117 final CmHandleQueryServiceParameters cmHandleQueryServiceParameters,
118 final Map<String, NcmpServiceCmHandle> previousQueryResult) {
119 final Collection<String> moduleNamesForQuery =
120 getModuleNamesForQuery(cmHandleQueryServiceParameters.getCmHandleQueryParameters());
121 if (moduleNamesForQuery.isEmpty()) {
122 return previousQueryResult;
124 final Collection<String> cmHandleIdsByModuleName = getNamesOfAnchorsWithGivenModules(moduleNamesForQuery);
125 if (cmHandleIdsByModuleName.isEmpty()) {
126 return Collections.emptyMap();
128 final Map<String, NcmpServiceCmHandle> queryResult = new HashMap<>(cmHandleIdsByModuleName.size());
129 if (previousQueryResult == NO_QUERY_TO_EXECUTE) {
130 cmHandleIdsByModuleName.forEach(cmHandleId ->
131 queryResult.put(cmHandleId, createNcmpServiceCmHandle(
132 inventoryPersistence.getDataNode("/dmi-registry/cm-handles[@id='" + cmHandleId + "']")))
136 previousQueryResult.keySet().retainAll(cmHandleIdsByModuleName);
137 queryResult.putAll(previousQueryResult);
141 private Map<String, NcmpServiceCmHandle> executeInventoryQueries(
142 final CmHandleQueryServiceParameters cmHandleQueryServiceParameters) {
143 final Map<String, String> cpsPath = getCpsPath(cmHandleQueryServiceParameters.getCmHandleQueryParameters());
144 if (!validateCpsPathConditionProperties(cpsPath)) {
145 return Collections.emptyMap();
147 final Map<String, NcmpServiceCmHandle> cpsPathQueryResult;
148 if (cpsPath.isEmpty()) {
149 cpsPathQueryResult = NO_QUERY_TO_EXECUTE;
152 cpsPathQueryResult = cmHandleQueries.queryCmHandleDataNodesByCpsPath(
153 cpsPath.get("cpsPath"), INCLUDE_ALL_DESCENDANTS)
154 .stream().map(this::createNcmpServiceCmHandle)
155 .collect(Collectors.toMap(NcmpServiceCmHandle::getCmHandleId,
156 Function.identity()));
157 } catch (final PathParsingException pathParsingException) {
158 throw new DataValidationException(pathParsingException.getMessage(), pathParsingException.getDetails(),
159 pathParsingException);
161 if (cpsPathQueryResult.isEmpty()) {
162 return Collections.emptyMap();
166 final Map<String, String> publicPropertyQueryPairs =
167 getPublicPropertyPairs(cmHandleQueryServiceParameters.getCmHandleQueryParameters());
168 final Map<String, NcmpServiceCmHandle> propertiesQueryResult = publicPropertyQueryPairs.isEmpty()
169 ? NO_QUERY_TO_EXECUTE : cmHandleQueries.queryCmHandlePublicProperties(publicPropertyQueryPairs);
171 return cmHandleQueries.combineCmHandleQueries(cpsPathQueryResult, propertiesQueryResult);
174 private Set<String> getNamesOfAnchorsWithGivenModules(final Collection<String> moduleNamesForQuery) {
175 final Collection<Anchor> anchors = inventoryPersistence.queryAnchors(moduleNamesForQuery);
176 return anchors.parallelStream().map(Anchor::getName).collect(Collectors.toSet());
179 private Collection<String> getModuleNamesForQuery(final List<ConditionProperties> conditionProperties) {
180 final List<String> result = new ArrayList<>();
181 getConditions(conditionProperties, ValidQueryProperties.HAS_ALL_MODULES.getQueryProperty())
182 .parallelStream().forEach(
183 conditionProperty -> {
184 validateModuleNameConditionProperties(conditionProperty);
185 result.add(conditionProperty.get("moduleName"));
191 private Map<String, String> getCpsPath(final List<ConditionProperties> conditionProperties) {
192 final Map<String, String> result = new HashMap<>();
193 getConditions(conditionProperties, ValidQueryProperties.WITH_CPS_PATH.getQueryProperty()).forEach(
198 private Map<String, String> getPublicPropertyPairs(final List<ConditionProperties> conditionProperties) {
199 final Map<String, String> result = new HashMap<>();
200 getConditions(conditionProperties,
201 ValidQueryProperties.HAS_ALL_PROPERTIES.getQueryProperty()).forEach(result::putAll);
205 private List<Map<String, String>> getConditions(final List<ConditionProperties> conditionProperties,
207 for (final ConditionProperties conditionProperty : conditionProperties) {
208 if (conditionProperty.getConditionName().equals(name)) {
209 return conditionProperty.getConditionParameters();
212 return Collections.emptyList();
215 private Set<NcmpServiceCmHandle> getAllCmHandles() {
216 return inventoryPersistence.getDataNode("/dmi-registry")
217 .getChildDataNodes().stream().map(this::createNcmpServiceCmHandle).collect(Collectors.toSet());
220 private Set<String> getAllCmHandleIds() {
221 return inventoryPersistence.getDataNode("/dmi-registry", FETCH_DIRECT_CHILDREN_ONLY)
222 .getChildDataNodes().stream().map(dataNode -> dataNode.getLeaves().get("id").toString())
223 .collect(Collectors.toSet());
226 private NcmpServiceCmHandle createNcmpServiceCmHandle(final DataNode dataNode) {
227 return convertYangModelCmHandleToNcmpServiceCmHandle(YangDataConverter
228 .convertCmHandleToYangModel(dataNode, dataNode.getLeaves().get("id").toString()));