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.constants.DmiRegistryConstants.NCMP_DATASPACE_NAME;
24 import static org.onap.cps.ncmp.api.impl.constants.DmiRegistryConstants.NCMP_DMI_REGISTRY_ANCHOR;
25 import static org.onap.cps.ncmp.api.impl.utils.YangDataConverter.convertYangModelCmHandleToNcmpServiceCmHandle;
26 import static org.onap.cps.spi.FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS;
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.stream.Collectors;
38 import lombok.RequiredArgsConstructor;
39 import lombok.extern.slf4j.Slf4j;
40 import org.onap.cps.ncmp.api.NetworkCmProxyCmHandlerQueryService;
41 import org.onap.cps.ncmp.api.impl.utils.YangDataConverter;
42 import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle;
43 import org.onap.cps.spi.CpsAdminPersistenceService;
44 import org.onap.cps.spi.CpsDataPersistenceService;
45 import org.onap.cps.spi.model.Anchor;
46 import org.onap.cps.spi.model.CmHandleQueryServiceParameters;
47 import org.onap.cps.spi.model.ConditionProperties;
48 import org.onap.cps.spi.model.DataNode;
49 import org.springframework.stereotype.Service;
53 @RequiredArgsConstructor
54 public class NetworkCmProxyCmHandlerQueryServiceImpl implements NetworkCmProxyCmHandlerQueryService {
56 private static final String PROPERTY_QUERY_NAME = "hasAllProperties";
57 private static final String MODULE_QUERY_NAME = "hasAllModules";
58 private static final Map<String, NcmpServiceCmHandle> NO_QUERY_EXECUTED = null;
59 private final CpsDataPersistenceService cpsDataPersistenceService;
60 private final CpsAdminPersistenceService cpsAdminPersistenceService;
63 * Query and return cm handles that match the given query parameters.
65 * @param cmHandleQueryServiceParameters the cm handle query parameters
66 * @return collection of cm handles
69 public Set<NcmpServiceCmHandle> queryCmHandles(
70 final CmHandleQueryServiceParameters cmHandleQueryServiceParameters) {
72 if (cmHandleQueryServiceParameters.getCmHandleQueryParameters().isEmpty()) {
73 return getAllCmHandles();
76 final Map<String, NcmpServiceCmHandle> publicPropertyQueryResult
77 = executePublicPropertyQueries(cmHandleQueryServiceParameters);
79 final Map<String, NcmpServiceCmHandle> combinedQueryResult =
80 combineWithModuleNameQuery(cmHandleQueryServiceParameters, publicPropertyQueryResult);
82 return combinedQueryResult == NO_QUERY_EXECUTED
83 ? Collections.emptySet() : new HashSet<>(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> publicPropertyQueryResult
101 = executePublicPropertyQueries(cmHandleQueryServiceParameters);
103 final Collection<String> moduleNamesForQuery =
104 getModuleNamesForQuery(cmHandleQueryServiceParameters.getCmHandleQueryParameters());
105 if (moduleNamesForQuery.isEmpty()) {
106 return publicPropertyQueryResult == NO_QUERY_EXECUTED
107 ? Collections.emptySet() : publicPropertyQueryResult.keySet();
109 final Set<String> moduleNameQueryResult = getNamesOfAnchorsWithGivenModules(moduleNamesForQuery);
111 if (publicPropertyQueryResult == NO_QUERY_EXECUTED) {
112 return moduleNameQueryResult;
115 moduleNameQueryResult.retainAll(publicPropertyQueryResult.keySet());
116 return moduleNameQueryResult;
119 private Map<String, NcmpServiceCmHandle> executePublicPropertyQueries(
120 final CmHandleQueryServiceParameters cmHandleQueryServiceParameters) {
121 final Map<String, String> publicPropertyQueryPairs =
122 getPublicPropertyPairs(cmHandleQueryServiceParameters.getCmHandleQueryParameters());
123 if (publicPropertyQueryPairs.isEmpty()) {
124 return NO_QUERY_EXECUTED;
126 Map<String, NcmpServiceCmHandle> cmHandleIdToNcmpServiceCmHandles = null;
127 for (final Map.Entry<String, String> entry : publicPropertyQueryPairs.entrySet()) {
128 final String cpsPath = "//public-properties[@name='" + entry.getKey() + "' and @value='"
129 + entry.getValue() + "']/ancestor::cm-handles";
131 final Collection<DataNode> dataNodes = queryDataNodes(cpsPath);
132 if (cmHandleIdToNcmpServiceCmHandles == NO_QUERY_EXECUTED) {
133 cmHandleIdToNcmpServiceCmHandles = collectDataNodesToNcmpServiceCmHandles(dataNodes);
135 final Collection<String> cmHandleIdsToRetain = dataNodes.parallelStream()
136 .map(dataNode -> dataNode.getLeaves().get("id").toString()).collect(Collectors.toSet());
137 cmHandleIdToNcmpServiceCmHandles.keySet().retainAll(cmHandleIdsToRetain);
139 if (cmHandleIdToNcmpServiceCmHandles.isEmpty()) {
143 return cmHandleIdToNcmpServiceCmHandles;
146 private Map<String, NcmpServiceCmHandle> combineWithModuleNameQuery(
147 final CmHandleQueryServiceParameters cmHandleQueryServiceParameters,
148 final Map<String, NcmpServiceCmHandle> previousQueryResult) {
149 final Collection<String> moduleNamesForQuery =
150 getModuleNamesForQuery(cmHandleQueryServiceParameters.getCmHandleQueryParameters());
151 if (moduleNamesForQuery.isEmpty()) {
152 return previousQueryResult;
154 final Collection<String> cmHandleIdsByModuleName = getNamesOfAnchorsWithGivenModules(moduleNamesForQuery);
155 if (cmHandleIdsByModuleName.isEmpty()) {
156 return Collections.emptyMap();
158 final Map<String, NcmpServiceCmHandle> queryResult = new HashMap<>(cmHandleIdsByModuleName.size());
159 if (previousQueryResult == NO_QUERY_EXECUTED) {
160 cmHandleIdsByModuleName.forEach(cmHandleId ->
161 queryResult.put(cmHandleId, createNcmpServiceCmHandle(
162 getDataNode("/dmi-registry/cm-handles[@id='" + cmHandleId + "']")))
166 previousQueryResult.keySet().retainAll(cmHandleIdsByModuleName);
167 queryResult.putAll(previousQueryResult);
171 private Set<String> getNamesOfAnchorsWithGivenModules(final Collection<String> moduleNamesForQuery) {
172 final Collection<Anchor> anchors =
173 cpsAdminPersistenceService.queryAnchors("NFP-Operational", moduleNamesForQuery);
174 return anchors.parallelStream().map(Anchor::getName).collect(Collectors.toSet());
177 private Map<String, NcmpServiceCmHandle> collectDataNodesToNcmpServiceCmHandles(
178 final Collection<DataNode> dataNodes) {
179 final Map<String, NcmpServiceCmHandle> cmHandleIdToNcmpServiceCmHandle = new HashMap<>();
180 dataNodes.forEach(dataNode -> {
181 final NcmpServiceCmHandle ncmpServiceCmHandle = createNcmpServiceCmHandle(dataNode);
182 cmHandleIdToNcmpServiceCmHandle.put(ncmpServiceCmHandle.getCmHandleId(), ncmpServiceCmHandle);
184 return cmHandleIdToNcmpServiceCmHandle;
187 private List<Map<String, String>> getConditions(final List<ConditionProperties> conditionProperties,
189 for (final ConditionProperties conditionProperty : conditionProperties) {
190 if (conditionProperty.getConditionName().equals(name)) {
191 return conditionProperty.getConditionParameters();
194 return Collections.emptyList();
197 private Collection<String> getModuleNamesForQuery(final List<ConditionProperties> conditionProperties) {
198 final List<String> result = new ArrayList<>();
199 getConditions(conditionProperties, MODULE_QUERY_NAME).parallelStream().forEach(
200 conditionProperty -> {
201 validateModuleNameConditionProperties(conditionProperty);
202 result.add(conditionProperty.get("moduleName"));
208 private Map<String, String> getPublicPropertyPairs(final List<ConditionProperties> conditionProperties) {
209 final Map<String, String> result = new HashMap<>();
210 getConditions(conditionProperties, PROPERTY_QUERY_NAME).forEach(result::putAll);
214 private Set<NcmpServiceCmHandle> getAllCmHandles() {
215 return getDataNode("/dmi-registry").getChildDataNodes().stream()
216 .map(this::createNcmpServiceCmHandle).collect(Collectors.toSet());
219 private Set<String> getAllCmHandleIds() {
220 return cpsAdminPersistenceService.getAnchors("NFP-Operational")
221 .parallelStream().map(Anchor::getName).collect(Collectors.toSet());
224 private List<DataNode> queryDataNodes(final String cpsPath) {
225 return cpsDataPersistenceService.queryDataNodes(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR,
226 cpsPath, INCLUDE_ALL_DESCENDANTS);
229 private DataNode getDataNode(final String cpsPath) {
230 return cpsDataPersistenceService.getDataNode(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR,
231 cpsPath, INCLUDE_ALL_DESCENDANTS);
234 private NcmpServiceCmHandle createNcmpServiceCmHandle(final DataNode dataNode) {
235 return convertYangModelCmHandleToNcmpServiceCmHandle(YangDataConverter
236 .convertCmHandleToYangModel(dataNode, dataNode.getLeaves().get("id").toString()));