9ce0e04ed2b275b4d05268a57e3cc7ca49f0e5bc
[cps.git] /
1 /*
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
8  *
9  *        http://www.apache.org/licenses/LICENSE-2.0
10  *
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.
16  *
17  *  SPDX-License-Identifier: Apache-2.0
18  *  ============LICENSE_END=========================================================
19  */
20
21 package org.onap.cps.ncmp.impl.inventory;
22
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;
33
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;
39 import java.util.Map;
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;
54
55 @Service
56 @RequiredArgsConstructor
57 public class ParameterizedCmHandleQueryServiceImpl implements ParameterizedCmHandleQueryService {
58
59     private static final Collection<String> NO_QUERY_TO_EXECUTE = null;
60     private final CmHandleQueryService cmHandleQueryService;
61     private final InventoryPersistence inventoryPersistence;
62
63     @Override
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);
72     }
73
74     @Override
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);
83     }
84
85     @Override
86     public Collection<NcmpServiceCmHandle> queryCmHandles(
87             final CmHandleQueryServiceParameters cmHandleQueryServiceParameters) {
88
89         if (cmHandleQueryServiceParameters.getCmHandleQueryParameters().isEmpty()) {
90             return getAllCmHandles();
91         }
92
93         final Collection<String> cmHandleIds = queryCmHandleReferenceIds(cmHandleQueryServiceParameters, false);
94
95         return getNcmpServiceCmHandles(cmHandleIds);
96     }
97
98     @Override
99     public Collection<NcmpServiceCmHandle> getAllCmHandles() {
100         return toNcmpServiceCmHandles(inventoryPersistence.getDataNode(NCMP_DMI_REGISTRY_PARENT));
101     }
102
103     @Override
104     public Collection<NcmpServiceCmHandle> getAllCmHandlesWithoutProperties() {
105         return toNcmpServiceCmHandles(inventoryPersistence.getDataNode(NCMP_DMI_REGISTRY_PARENT, DIRECT_CHILDREN_ONLY));
106     }
107
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());
111     }
112
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;
120         }
121
122         final String dmiPluginIdentifierValue = dmiPropertyQueryPairs
123                 .get(PropertyType.DMI_PLUGIN.getYangContainerName());
124
125         return cmHandleQueryService.getCmHandleReferencesByDmiPluginIdentifier(
126                 dmiPluginIdentifierValue, outputAlternateId);
127
128     }
129
130     private Collection<String> queryCmHandlesByPrivateProperties(
131             final CmHandleQueryServiceParameters cmHandleQueryServiceParameters, final boolean outputAlternateId) {
132
133         final Map<String, String> privatePropertyQueryPairs =
134                 getPropertyPairs(cmHandleQueryServiceParameters.getCmHandleQueryParameters(),
135                         InventoryQueryConditions.HAS_ALL_ADDITIONAL_PROPERTIES.getName());
136
137         if (privatePropertyQueryPairs.isEmpty()) {
138             return NO_QUERY_TO_EXECUTE;
139         }
140         return cmHandleQueryService.queryCmHandleAdditionalProperties(privatePropertyQueryPairs, outputAlternateId);
141     }
142
143     private Collection<String> queryCmHandlesByPublicProperties(
144             final CmHandleQueryServiceParameters cmHandleQueryServiceParameters, final boolean outputAlternateId) {
145
146         final Map<String, String> publicPropertyQueryPairs =
147                 getPropertyPairs(cmHandleQueryServiceParameters.getCmHandleQueryParameters(),
148                         HAS_ALL_PROPERTIES.getConditionName());
149
150         if (publicPropertyQueryPairs.isEmpty()) {
151             return NO_QUERY_TO_EXECUTE;
152         }
153         return cmHandleQueryService.queryCmHandlePublicProperties(publicPropertyQueryPairs, outputAlternateId);
154     }
155
156     private Collection<String> queryCmHandlesByTrustLevel(final CmHandleQueryServiceParameters
157                                                                   cmHandleQueryServiceParameters,
158                                                           final boolean outputAlternateId) {
159
160         final Map<String, String> trustLevelPropertyQueryPairs =
161                 getPropertyPairs(cmHandleQueryServiceParameters.getCmHandleQueryParameters(),
162                         WITH_TRUST_LEVEL.getConditionName());
163
164         if (trustLevelPropertyQueryPairs.isEmpty()) {
165             return NO_QUERY_TO_EXECUTE;
166         }
167         return cmHandleQueryService.queryCmHandlesByTrustLevel(trustLevelPropertyQueryPairs, outputAlternateId);
168     }
169
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;
176         }
177         return inventoryPersistence.getCmHandleReferencesWithGivenModules(moduleNamesForQuery, outputAlternateId);
178     }
179
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();
186         }
187         final Collection<String> cpsPathQueryResult;
188         if (cpsPathCondition.isEmpty()) {
189             return NO_QUERY_TO_EXECUTE;
190         }
191         try {
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);
198         }
199         return cpsPathQueryResult;
200     }
201
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"));
208                 });
209         return result;
210     }
211
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);
215         return result;
216     }
217
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);
222         return result;
223     }
224
225     private List<Map<String, String>> getConditions(final List<ConditionProperties> conditionProperties,
226                                                     final String name) {
227         for (final ConditionProperties conditionProperty : conditionProperties) {
228             if (conditionProperty.getConditionName().equals(name)) {
229                 return conditionProperty.getConditionParameters();
230             }
231         }
232         return Collections.emptyList();
233     }
234
235     private Collection<String> getAllCmHandleReferences(final boolean outputAlternateId) {
236         return cmHandleQueryService.getAllCmHandleReferences(outputAlternateId);
237     }
238
239     private Collection<NcmpServiceCmHandle> getNcmpServiceCmHandles(final Collection<String> cmHandleIds) {
240         final Collection<YangModelCmHandle> yangModelcmHandles
241                 = inventoryPersistence.getYangModelCmHandles(cmHandleIds);
242
243         final Collection<NcmpServiceCmHandle> ncmpServiceCmHandles = new ArrayList<>(yangModelcmHandles.size());
244
245         yangModelcmHandles.forEach(yangModelcmHandle ->
246                 ncmpServiceCmHandles.add(YangDataConverter.toNcmpServiceCmHandle(yangModelcmHandle))
247         );
248         return ncmpServiceCmHandles;
249     }
250
251     private NcmpServiceCmHandle createNcmpServiceCmHandle(final DataNode dataNode) {
252         return toNcmpServiceCmHandle(YangDataConverter.toYangModelCmHandle(dataNode));
253     }
254
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);
261         }
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,
266                     outputAlternateId);
267             if (noEntriesFoundCanStopQuerying(queryResult)) {
268                 return Collections.emptySet();
269             }
270             combinedQueryResult = combineCmHandleQueryResults(combinedQueryResult, queryResult);
271         }
272         return combinedQueryResult;
273     }
274
275     private boolean noEntriesFoundCanStopQuerying(final Collection<String> queryResult) {
276         return queryResult != NO_QUERY_TO_EXECUTE && queryResult.isEmpty();
277     }
278
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) {
284             return secondQuery;
285         } else if (secondQuery == NO_QUERY_TO_EXECUTE) {
286             return firstQuery;
287         } else {
288             firstQuery.retainAll(secondQuery);
289             return firstQuery;
290         }
291     }
292
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());
298         } else {
299             return dataNodes.stream().map(dataNode ->
300                     (String) dataNode.getLeaves().get("id")).collect(Collectors.toSet());
301         }
302     }
303 }