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