51e403fd663c963f5741e8dc0aee6cc662fcfcbc
[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.convertYangModelCmHandleToNcmpServiceCmHandle;
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.Function;
41 import java.util.stream.Collectors;
42 import lombok.RequiredArgsConstructor;
43 import lombok.extern.slf4j.Slf4j;
44 import org.onap.cps.cpspath.parser.PathParsingException;
45 import org.onap.cps.ncmp.api.inventory.models.CmHandleQueryServiceParameters;
46 import org.onap.cps.ncmp.api.inventory.models.NcmpServiceCmHandle;
47 import org.onap.cps.ncmp.impl.inventory.models.InventoryQueryConditions;
48 import org.onap.cps.ncmp.impl.inventory.models.PropertyType;
49 import org.onap.cps.ncmp.impl.inventory.models.YangModelCmHandle;
50 import org.onap.cps.ncmp.impl.utils.YangDataConverter;
51 import org.onap.cps.spi.exceptions.DataValidationException;
52 import org.onap.cps.spi.model.ConditionProperties;
53 import org.onap.cps.spi.model.DataNode;
54 import org.springframework.stereotype.Service;
55
56 @Service
57 @Slf4j
58 @RequiredArgsConstructor
59 public class ParameterizedCmHandleQueryServiceImpl implements ParameterizedCmHandleQueryService {
60
61     private static final Collection<String> NO_QUERY_TO_EXECUTE = null;
62     private final CmHandleQueryService cmHandleQueryService;
63     private final InventoryPersistence inventoryPersistence;
64
65     @Override
66     public Collection<String> queryCmHandleIds(
67             final CmHandleQueryServiceParameters cmHandleQueryServiceParameters) {
68         return executeQueries(cmHandleQueryServiceParameters,
69             this::executeCpsPathQuery,
70             this::queryCmHandlesByPublicProperties,
71             this::executeModuleNameQuery,
72                 this::queryCmHandlesByTrustLevel);
73     }
74
75     @Override
76     public Collection<String> queryCmHandleIdsForInventory(
77         final CmHandleQueryServiceParameters cmHandleQueryServiceParameters) {
78         return executeQueries(cmHandleQueryServiceParameters,
79             this::queryCmHandlesByPublicProperties,
80             this::queryCmHandlesByPrivateProperties,
81             this::queryCmHandlesByDmiPlugin);
82     }
83
84     @Override
85     public Collection<NcmpServiceCmHandle> queryCmHandles(
86         final CmHandleQueryServiceParameters cmHandleQueryServiceParameters) {
87
88         if (cmHandleQueryServiceParameters.getCmHandleQueryParameters().isEmpty()) {
89             return getAllCmHandles();
90         }
91
92         final Collection<String> cmHandleIds = queryCmHandleIds(cmHandleQueryServiceParameters);
93
94         return getNcmpServiceCmHandles(cmHandleIds);
95     }
96
97     @Override
98     public Collection<NcmpServiceCmHandle> getAllCmHandles() {
99         final DataNode dataNode = inventoryPersistence.getDataNode(NCMP_DMI_REGISTRY_PARENT).iterator().next();
100         return dataNode.getChildDataNodes().stream().map(this::createNcmpServiceCmHandle).collect(Collectors.toSet());
101     }
102
103     private Collection<String> queryCmHandlesByDmiPlugin(
104             final CmHandleQueryServiceParameters cmHandleQueryServiceParameters) {
105         final Map<String, String> dmiPropertyQueryPairs =
106                 getPropertyPairs(cmHandleQueryServiceParameters.getCmHandleQueryParameters(),
107                         InventoryQueryConditions.CM_HANDLE_WITH_DMI_PLUGIN.getName());
108         if (dmiPropertyQueryPairs.isEmpty()) {
109             return NO_QUERY_TO_EXECUTE;
110         }
111
112         final String dmiPluginIdentifierValue = dmiPropertyQueryPairs
113             .get(PropertyType.DMI_PLUGIN.getYangContainerName());
114
115         return cmHandleQueryService.getCmHandleIdsByDmiPluginIdentifier(dmiPluginIdentifierValue);
116     }
117
118     private Collection<String> queryCmHandlesByPrivateProperties(
119             final CmHandleQueryServiceParameters cmHandleQueryServiceParameters) {
120
121         final Map<String, String> privatePropertyQueryPairs =
122                 getPropertyPairs(cmHandleQueryServiceParameters.getCmHandleQueryParameters(),
123                         InventoryQueryConditions.HAS_ALL_ADDITIONAL_PROPERTIES.getName());
124
125         if (privatePropertyQueryPairs.isEmpty()) {
126             return NO_QUERY_TO_EXECUTE;
127         }
128         return cmHandleQueryService.queryCmHandleAdditionalProperties(privatePropertyQueryPairs);
129     }
130
131     private Collection<String> queryCmHandlesByPublicProperties(
132             final CmHandleQueryServiceParameters cmHandleQueryServiceParameters) {
133
134         final Map<String, String> publicPropertyQueryPairs =
135                 getPropertyPairs(cmHandleQueryServiceParameters.getCmHandleQueryParameters(),
136                         HAS_ALL_PROPERTIES.getConditionName());
137
138         if (publicPropertyQueryPairs.isEmpty()) {
139             return NO_QUERY_TO_EXECUTE;
140         }
141         return cmHandleQueryService.queryCmHandlePublicProperties(publicPropertyQueryPairs);
142     }
143
144     private Collection<String> queryCmHandlesByTrustLevel(final CmHandleQueryServiceParameters
145                                                                   cmHandleQueryServiceParameters) {
146
147         final Map<String, String> trustLevelPropertyQueryPairs =
148                 getPropertyPairs(cmHandleQueryServiceParameters.getCmHandleQueryParameters(),
149                         WITH_TRUST_LEVEL.getConditionName());
150
151         if (trustLevelPropertyQueryPairs.isEmpty()) {
152             return NO_QUERY_TO_EXECUTE;
153         }
154         return cmHandleQueryService.queryCmHandlesByTrustLevel(trustLevelPropertyQueryPairs);
155     }
156
157     private Collection<String> executeModuleNameQuery(
158             final CmHandleQueryServiceParameters cmHandleQueryServiceParameters) {
159         final Collection<String> moduleNamesForQuery =
160                 getModuleNamesForQuery(cmHandleQueryServiceParameters.getCmHandleQueryParameters());
161         if (moduleNamesForQuery.isEmpty()) {
162             return NO_QUERY_TO_EXECUTE;
163         }
164         return inventoryPersistence.getCmHandleIdsWithGivenModules(moduleNamesForQuery);
165     }
166
167     private Collection<String> executeCpsPathQuery(
168             final CmHandleQueryServiceParameters cmHandleQueryServiceParameters) {
169         final Map<String, String> cpsPathCondition
170             = getCpsPathCondition(cmHandleQueryServiceParameters.getCmHandleQueryParameters());
171         if (!validateCpsPathConditionProperties(cpsPathCondition)) {
172             return Collections.emptySet();
173         }
174         final Collection<String> cpsPathQueryResult;
175         if (cpsPathCondition.isEmpty()) {
176             return NO_QUERY_TO_EXECUTE;
177         }
178         try {
179             cpsPathQueryResult = collectCmHandleIdsFromDataNodes(
180                 cmHandleQueryService.queryCmHandleAncestorsByCpsPath(
181                         cpsPathCondition.get("cpsPath"), OMIT_DESCENDANTS));
182         } catch (final PathParsingException pathParsingException) {
183             throw new DataValidationException(pathParsingException.getMessage(), pathParsingException.getDetails(),
184                     pathParsingException);
185         }
186         return cpsPathQueryResult;
187     }
188
189     private Collection<String> getModuleNamesForQuery(final List<ConditionProperties> conditionProperties) {
190         final List<String> result = new ArrayList<>();
191         getConditions(conditionProperties, HAS_ALL_MODULES.getConditionName()).forEach(
192                 conditionProperty -> {
193                     validateModuleNameConditionProperties(conditionProperty);
194                     result.add(conditionProperty.get("moduleName"));
195                 });
196         return result;
197     }
198
199     private Map<String, String> getCpsPathCondition(final List<ConditionProperties> conditionProperties) {
200         final Map<String, String> result = new HashMap<>();
201         getConditions(conditionProperties, WITH_CPS_PATH.getConditionName()).forEach(result::putAll);
202         return result;
203     }
204
205     private Map<String, String> getPropertyPairs(final List<ConditionProperties> conditionProperties,
206                                                        final String queryProperty) {
207         final Map<String, String> result = new HashMap<>();
208         getConditions(conditionProperties, queryProperty).forEach(result::putAll);
209         return result;
210     }
211
212     private List<Map<String, String>> getConditions(final List<ConditionProperties> conditionProperties,
213                                                     final String name) {
214         for (final ConditionProperties conditionProperty : conditionProperties) {
215             if (conditionProperty.getConditionName().equals(name)) {
216                 return conditionProperty.getConditionParameters();
217             }
218         }
219         return Collections.emptyList();
220     }
221
222     private Collection<String> getAllCmHandleIds() {
223         final DataNode dataNode = inventoryPersistence.getDataNode(NCMP_DMI_REGISTRY_PARENT, DIRECT_CHILDREN_ONLY)
224                 .iterator().next();
225         return collectCmHandleIdsFromDataNodes(dataNode.getChildDataNodes());
226     }
227
228     private Collection<NcmpServiceCmHandle> getNcmpServiceCmHandles(final Collection<String> cmHandleIds) {
229         final Collection<YangModelCmHandle> yangModelcmHandles
230             = inventoryPersistence.getYangModelCmHandles(cmHandleIds);
231
232         final Collection<NcmpServiceCmHandle> ncmpServiceCmHandles = new ArrayList<>(yangModelcmHandles.size());
233
234         yangModelcmHandles.forEach(yangModelcmHandle ->
235             ncmpServiceCmHandles.add(YangDataConverter.convertYangModelCmHandleToNcmpServiceCmHandle(yangModelcmHandle))
236         );
237         return ncmpServiceCmHandles;
238     }
239
240     private NcmpServiceCmHandle createNcmpServiceCmHandle(final DataNode dataNode) {
241         return convertYangModelCmHandleToNcmpServiceCmHandle(YangDataConverter.convertCmHandleToYangModel(dataNode));
242     }
243
244     private Collection<String> executeQueries(final CmHandleQueryServiceParameters cmHandleQueryServiceParameters,
245                                               final Function<CmHandleQueryServiceParameters, Collection<String>>...
246                                                   queryFunctions) {
247         if (cmHandleQueryServiceParameters.getCmHandleQueryParameters().isEmpty()) {
248             return getAllCmHandleIds();
249         }
250         Collection<String> combinedQueryResult = NO_QUERY_TO_EXECUTE;
251         for (final Function<CmHandleQueryServiceParameters, Collection<String>> queryFunction : queryFunctions) {
252             final Collection<String> queryResult = queryFunction.apply(cmHandleQueryServiceParameters);
253             if (noEntriesFoundCanStopQuerying(queryResult)) {
254                 return Collections.emptySet();
255             }
256             combinedQueryResult = combineCmHandleQueryResults(combinedQueryResult, queryResult);
257         }
258         return combinedQueryResult;
259     }
260
261     private boolean noEntriesFoundCanStopQuerying(final Collection<String> queryResult) {
262         return queryResult != NO_QUERY_TO_EXECUTE && queryResult.isEmpty();
263     }
264
265     private Collection<String> combineCmHandleQueryResults(final Collection<String> firstQuery,
266                                                            final Collection<String> secondQuery) {
267         if (firstQuery == NO_QUERY_TO_EXECUTE && secondQuery == NO_QUERY_TO_EXECUTE) {
268             return NO_QUERY_TO_EXECUTE;
269         } else if (firstQuery == NO_QUERY_TO_EXECUTE) {
270             return secondQuery;
271         } else if (secondQuery == NO_QUERY_TO_EXECUTE) {
272             return firstQuery;
273         } else {
274             firstQuery.retainAll(secondQuery);
275             return firstQuery;
276         }
277     }
278
279     private Collection<String> collectCmHandleIdsFromDataNodes(final Collection<DataNode> dataNodes) {
280         return dataNodes.stream().map(dataNode -> (String) dataNode.getLeaves().get("id")).collect(Collectors.toSet());
281     }
282
283 }