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