bacbbe0c959cb9a8a62d579f07684091be6117e7
[cps.git] /
1 /*
2  *  ============LICENSE_START=======================================================
3  *  Copyright (C) 2022-2024 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.ncmp.impl.inventory.CmHandleQueryParametersValidator.validateCpsPathConditionProperties;
24 import static org.onap.cps.ncmp.impl.inventory.CmHandleQueryParametersValidator.validateModuleNameConditionProperties;
25 import static org.onap.cps.ncmp.impl.inventory.NcmpPersistence.NCMP_DMI_REGISTRY_PARENT;
26 import static org.onap.cps.ncmp.impl.inventory.models.CmHandleQueryConditions.HAS_ALL_MODULES;
27 import static org.onap.cps.ncmp.impl.inventory.models.CmHandleQueryConditions.HAS_ALL_PROPERTIES;
28 import static org.onap.cps.ncmp.impl.inventory.models.CmHandleQueryConditions.WITH_CPS_PATH;
29 import static org.onap.cps.ncmp.impl.inventory.models.CmHandleQueryConditions.WITH_TRUST_LEVEL;
30 import static org.onap.cps.ncmp.impl.utils.YangDataConverter.toNcmpServiceCmHandle;
31 import static org.onap.cps.spi.FetchDescendantsOption.DIRECT_CHILDREN_ONLY;
32 import static org.onap.cps.spi.FetchDescendantsOption.OMIT_DESCENDANTS;
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.cpspath.parser.PathParsingException;
44 import org.onap.cps.ncmp.api.inventory.models.CmHandleQueryServiceParameters;
45 import org.onap.cps.ncmp.api.inventory.models.NcmpServiceCmHandle;
46 import org.onap.cps.ncmp.impl.inventory.models.InventoryQueryConditions;
47 import org.onap.cps.ncmp.impl.inventory.models.PropertyType;
48 import org.onap.cps.ncmp.impl.inventory.models.YangModelCmHandle;
49 import org.onap.cps.ncmp.impl.utils.YangDataConverter;
50 import org.onap.cps.spi.exceptions.DataValidationException;
51 import org.onap.cps.spi.model.ConditionProperties;
52 import org.onap.cps.spi.model.DataNode;
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         final DataNode dataNode = inventoryPersistence.getDataNode(NCMP_DMI_REGISTRY_PARENT).iterator().next();
101         return dataNode.getChildDataNodes().stream().map(this::createNcmpServiceCmHandle).collect(Collectors.toSet());
102     }
103
104     private Collection<String> queryCmHandlesByDmiPlugin(
105             final CmHandleQueryServiceParameters cmHandleQueryServiceParameters, final Boolean outputAlternateId) {
106         final Map<String, String> dmiPropertyQueryPairs =
107                 getPropertyPairs(cmHandleQueryServiceParameters.getCmHandleQueryParameters(),
108                         InventoryQueryConditions.CM_HANDLE_WITH_DMI_PLUGIN.getName());
109         if (dmiPropertyQueryPairs.isEmpty()) {
110             return NO_QUERY_TO_EXECUTE;
111         }
112
113         final String dmiPluginIdentifierValue = dmiPropertyQueryPairs
114             .get(PropertyType.DMI_PLUGIN.getYangContainerName());
115
116         if (Boolean.TRUE.equals(outputAlternateId)) {
117             return cmHandleQueryService.getCmHandleReferencesByDmiPluginIdentifier(dmiPluginIdentifierValue).values();
118         } else {
119             return cmHandleQueryService.getCmHandleIdsByDmiPluginIdentifier(dmiPluginIdentifierValue);
120         }
121     }
122
123     private Collection<String> queryCmHandlesByPrivateProperties(
124             final CmHandleQueryServiceParameters cmHandleQueryServiceParameters, final Boolean outputAlternateId) {
125
126         final Map<String, String> privatePropertyQueryPairs =
127                 getPropertyPairs(cmHandleQueryServiceParameters.getCmHandleQueryParameters(),
128                         InventoryQueryConditions.HAS_ALL_ADDITIONAL_PROPERTIES.getName());
129
130         if (privatePropertyQueryPairs.isEmpty()) {
131             return NO_QUERY_TO_EXECUTE;
132         }
133         return cmHandleQueryService.queryCmHandleAdditionalProperties(privatePropertyQueryPairs, outputAlternateId);
134     }
135
136     private Collection<String> queryCmHandlesByPublicProperties(
137             final CmHandleQueryServiceParameters cmHandleQueryServiceParameters, final Boolean outputAlternateId) {
138
139         final Map<String, String> publicPropertyQueryPairs =
140                 getPropertyPairs(cmHandleQueryServiceParameters.getCmHandleQueryParameters(),
141                         HAS_ALL_PROPERTIES.getConditionName());
142
143         if (publicPropertyQueryPairs.isEmpty()) {
144             return NO_QUERY_TO_EXECUTE;
145         }
146         return cmHandleQueryService.queryCmHandlePublicProperties(publicPropertyQueryPairs, outputAlternateId);
147     }
148
149     private Collection<String> queryCmHandlesByTrustLevel(final CmHandleQueryServiceParameters
150                                                                   cmHandleQueryServiceParameters,
151                                                           final Boolean outputAlternateId) {
152
153         final Map<String, String> trustLevelPropertyQueryPairs =
154                 getPropertyPairs(cmHandleQueryServiceParameters.getCmHandleQueryParameters(),
155                         WITH_TRUST_LEVEL.getConditionName());
156
157         if (trustLevelPropertyQueryPairs.isEmpty()) {
158             return NO_QUERY_TO_EXECUTE;
159         }
160         return cmHandleQueryService.queryCmHandlesByTrustLevel(trustLevelPropertyQueryPairs, outputAlternateId);
161     }
162
163     private Collection<String> executeModuleNameQuery(
164             final CmHandleQueryServiceParameters cmHandleQueryServiceParameters, final Boolean outputAlternateId) {
165         final Collection<String> moduleNamesForQuery =
166                 getModuleNamesForQuery(cmHandleQueryServiceParameters.getCmHandleQueryParameters());
167         if (moduleNamesForQuery.isEmpty()) {
168             return NO_QUERY_TO_EXECUTE;
169         }
170         return inventoryPersistence.getCmHandleReferencesWithGivenModules(moduleNamesForQuery, outputAlternateId);
171     }
172
173     private Collection<String> executeCpsPathQuery(
174             final CmHandleQueryServiceParameters cmHandleQueryServiceParameters, final Boolean outputAlternateId) {
175         final Map<String, String> cpsPathCondition
176             = getCpsPathCondition(cmHandleQueryServiceParameters.getCmHandleQueryParameters());
177         if (!validateCpsPathConditionProperties(cpsPathCondition)) {
178             return Collections.emptySet();
179         }
180         final Collection<String> cpsPathQueryResult;
181         if (cpsPathCondition.isEmpty()) {
182             return NO_QUERY_TO_EXECUTE;
183         }
184         try {
185             cpsPathQueryResult = collectCmHandleReferencesFromDataNodes(
186                 cmHandleQueryService.queryCmHandleAncestorsByCpsPath(cpsPathCondition.get("cpsPath"), OMIT_DESCENDANTS),
187                 outputAlternateId);
188         } catch (final PathParsingException pathParsingException) {
189             throw new DataValidationException(pathParsingException.getMessage(), pathParsingException.getDetails(),
190                     pathParsingException);
191         }
192         return cpsPathQueryResult;
193     }
194
195     private Collection<String> getModuleNamesForQuery(final List<ConditionProperties> conditionProperties) {
196         final List<String> result = new ArrayList<>();
197         getConditions(conditionProperties, HAS_ALL_MODULES.getConditionName()).forEach(
198                 conditionProperty -> {
199                     validateModuleNameConditionProperties(conditionProperty);
200                     result.add(conditionProperty.get("moduleName"));
201                 });
202         return result;
203     }
204
205     private Map<String, String> getCpsPathCondition(final List<ConditionProperties> conditionProperties) {
206         final Map<String, String> result = new HashMap<>();
207         getConditions(conditionProperties, WITH_CPS_PATH.getConditionName()).forEach(result::putAll);
208         return result;
209     }
210
211     private Map<String, String> getPropertyPairs(final List<ConditionProperties> conditionProperties,
212                                                        final String queryProperty) {
213         final Map<String, String> result = new HashMap<>();
214         getConditions(conditionProperties, queryProperty).forEach(result::putAll);
215         return result;
216     }
217
218     private List<Map<String, String>> getConditions(final List<ConditionProperties> conditionProperties,
219                                                     final String name) {
220         for (final ConditionProperties conditionProperty : conditionProperties) {
221             if (conditionProperty.getConditionName().equals(name)) {
222                 return conditionProperty.getConditionParameters();
223             }
224         }
225         return Collections.emptyList();
226     }
227
228     private Collection<String> getAllCmHandleReferences(final Boolean outputAlternateId) {
229         final DataNode dataNode = inventoryPersistence.getDataNode(NCMP_DMI_REGISTRY_PARENT, DIRECT_CHILDREN_ONLY)
230             .iterator().next();
231         return collectCmHandleReferencesFromDataNodes(dataNode.getChildDataNodes(), outputAlternateId);
232     }
233
234     private Collection<NcmpServiceCmHandle> getNcmpServiceCmHandles(final Collection<String> cmHandleIds) {
235         final Collection<YangModelCmHandle> yangModelcmHandles
236             = inventoryPersistence.getYangModelCmHandles(cmHandleIds);
237
238         final Collection<NcmpServiceCmHandle> ncmpServiceCmHandles = new ArrayList<>(yangModelcmHandles.size());
239
240         yangModelcmHandles.forEach(yangModelcmHandle ->
241             ncmpServiceCmHandles.add(YangDataConverter.toNcmpServiceCmHandle(yangModelcmHandle))
242         );
243         return ncmpServiceCmHandles;
244     }
245
246     private NcmpServiceCmHandle createNcmpServiceCmHandle(final DataNode dataNode) {
247         return toNcmpServiceCmHandle(YangDataConverter.toYangModelCmHandle(dataNode));
248     }
249
250     private Collection<String> executeQueries(final CmHandleQueryServiceParameters cmHandleQueryServiceParameters,
251                                               final Boolean outputAlternateId,
252                                               final BiFunction<CmHandleQueryServiceParameters, Boolean,
253                                                   Collection<String>>... queryFunctions) {
254         if (cmHandleQueryServiceParameters.getCmHandleQueryParameters().isEmpty()) {
255             return getAllCmHandleReferences(outputAlternateId);
256         }
257         Collection<String> combinedQueryResult = NO_QUERY_TO_EXECUTE;
258         for (final BiFunction<CmHandleQueryServiceParameters, Boolean,
259             Collection<String>> queryFunction : queryFunctions) {
260             final Collection<String> queryResult = queryFunction.apply(cmHandleQueryServiceParameters,
261                 outputAlternateId);
262             if (noEntriesFoundCanStopQuerying(queryResult)) {
263                 return Collections.emptySet();
264             }
265             combinedQueryResult = combineCmHandleQueryResults(combinedQueryResult, queryResult);
266         }
267         return combinedQueryResult;
268     }
269
270     private boolean noEntriesFoundCanStopQuerying(final Collection<String> queryResult) {
271         return queryResult != NO_QUERY_TO_EXECUTE && queryResult.isEmpty();
272     }
273
274     private Collection<String> combineCmHandleQueryResults(final Collection<String> firstQuery,
275                                                            final Collection<String> secondQuery) {
276         if (firstQuery == NO_QUERY_TO_EXECUTE && secondQuery == NO_QUERY_TO_EXECUTE) {
277             return NO_QUERY_TO_EXECUTE;
278         } else if (firstQuery == NO_QUERY_TO_EXECUTE) {
279             return secondQuery;
280         } else if (secondQuery == NO_QUERY_TO_EXECUTE) {
281             return firstQuery;
282         } else {
283             firstQuery.retainAll(secondQuery);
284             return firstQuery;
285         }
286     }
287
288     private Collection<String> collectCmHandleReferencesFromDataNodes(final Collection<DataNode> dataNodes,
289                                                                final Boolean outputAlternateId) {
290         if (Boolean.TRUE.equals(outputAlternateId)) {
291             return dataNodes.stream().map(dataNode ->
292                 (String) dataNode.getLeaves().get("alternate-id")).collect(Collectors.toSet());
293         } else {
294             return dataNodes.stream().map(dataNode ->
295                 (String) dataNode.getLeaves().get("id")).collect(Collectors.toSet());
296         }
297     }
298 }