74ddc22150cbf1ff73b07dfc332dbd57e4522313
[cps.git] /
1 /*
2  *  ============LICENSE_START=======================================================
3  *  Copyright (C) 2022-2025 OpenInfra Foundation Europe. All rights reserved.
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.models.CmHandleQueryConditions.HAS_ALL_MODULES;
26 import static org.onap.cps.ncmp.impl.inventory.models.CmHandleQueryConditions.HAS_ALL_PROPERTIES;
27 import static org.onap.cps.ncmp.impl.inventory.models.CmHandleQueryConditions.WITH_CPS_PATH;
28 import static org.onap.cps.ncmp.impl.inventory.models.CmHandleQueryConditions.WITH_TRUST_LEVEL;
29
30 import java.util.ArrayList;
31 import java.util.Collection;
32 import java.util.Collections;
33 import java.util.HashMap;
34 import java.util.List;
35 import java.util.Map;
36 import java.util.function.BiFunction;
37 import lombok.RequiredArgsConstructor;
38 import org.onap.cps.api.exceptions.DataValidationException;
39 import org.onap.cps.api.model.ConditionProperties;
40 import org.onap.cps.cpspath.parser.PathParsingException;
41 import org.onap.cps.ncmp.api.inventory.models.CmHandleQueryServiceParameters;
42 import org.onap.cps.ncmp.api.inventory.models.NcmpServiceCmHandle;
43 import org.onap.cps.ncmp.impl.inventory.models.InventoryQueryConditions;
44 import org.onap.cps.ncmp.impl.inventory.models.PropertyType;
45 import org.onap.cps.ncmp.impl.inventory.models.YangModelCmHandle;
46 import org.onap.cps.ncmp.impl.inventory.trustlevel.TrustLevelManager;
47 import org.onap.cps.ncmp.impl.utils.YangDataConverter;
48 import org.springframework.stereotype.Service;
49 import reactor.core.publisher.Flux;
50
51 @Service
52 @RequiredArgsConstructor
53 public class ParameterizedCmHandleQueryServiceImpl implements ParameterizedCmHandleQueryService {
54
55     private static final int FLUX_BUFFER_SIZE = 1000;
56     private static final Collection<String> NO_QUERY_TO_EXECUTE = null;
57     private final CmHandleQueryService cmHandleQueryService;
58     private final InventoryPersistence inventoryPersistence;
59     private final TrustLevelManager trustLevelManager;
60
61     @Override
62     public Collection<String> queryCmHandleReferenceIds(
63             final CmHandleQueryServiceParameters cmHandleQueryServiceParameters,
64             final boolean outputAlternateId) {
65         return executeQueries(cmHandleQueryServiceParameters, outputAlternateId,
66                 this::executeCpsPathQuery,
67                 this::queryCmHandlesByPublicProperties,
68                 this::executeModuleNameQuery,
69                 this::queryCmHandlesByTrustLevel);
70     }
71
72     @Override
73     public Collection<String> queryCmHandleIdsForInventory(
74             final CmHandleQueryServiceParameters cmHandleQueryServiceParameters,
75             final boolean outputAlternateId) {
76         return executeQueries(cmHandleQueryServiceParameters, outputAlternateId,
77                 this::executeCpsPathQuery,
78                 this::queryCmHandlesByPublicProperties,
79                 this::queryCmHandlesByPrivateProperties,
80                 this::queryCmHandlesByDmiPlugin);
81     }
82
83     @Override
84     public Flux<NcmpServiceCmHandle> queryCmHandles(final CmHandleQueryServiceParameters queryParameters) {
85         final Collection<String> cmHandleIds = queryCmHandleReferenceIds(queryParameters, false);
86         return getNcmpServiceCmHandles(cmHandleIds);
87     }
88
89     @Override
90     public Flux<NcmpServiceCmHandle> queryInventoryForCmHandles(final CmHandleQueryServiceParameters queryParameters) {
91         final Collection<String> cmHandleIds = queryCmHandleIdsForInventory(queryParameters, false);
92         return getNcmpServiceCmHandles(cmHandleIds);
93     }
94
95     private Collection<String> queryCmHandlesByDmiPlugin(
96             final CmHandleQueryServiceParameters cmHandleQueryServiceParameters, final boolean outputAlternateId) {
97         final Map<String, String> dmiPropertyQueryPairs =
98                 getPropertyPairs(cmHandleQueryServiceParameters.getCmHandleQueryParameters(),
99                         InventoryQueryConditions.CM_HANDLE_WITH_DMI_PLUGIN.getName());
100         if (dmiPropertyQueryPairs.isEmpty()) {
101             return NO_QUERY_TO_EXECUTE;
102         }
103
104         final String dmiPluginIdentifierValue = dmiPropertyQueryPairs
105                 .get(PropertyType.DMI_PLUGIN.getYangContainerName());
106
107         return cmHandleQueryService.getCmHandleReferencesByDmiPluginIdentifier(
108                 dmiPluginIdentifierValue, outputAlternateId);
109
110     }
111
112     private Collection<String> queryCmHandlesByPrivateProperties(
113             final CmHandleQueryServiceParameters cmHandleQueryServiceParameters, final boolean outputAlternateId) {
114
115         final Map<String, String> privatePropertyQueryPairs =
116                 getPropertyPairs(cmHandleQueryServiceParameters.getCmHandleQueryParameters(),
117                         InventoryQueryConditions.HAS_ALL_ADDITIONAL_PROPERTIES.getName());
118
119         if (privatePropertyQueryPairs.isEmpty()) {
120             return NO_QUERY_TO_EXECUTE;
121         }
122         return cmHandleQueryService.queryCmHandleAdditionalProperties(privatePropertyQueryPairs, outputAlternateId);
123     }
124
125     private Collection<String> queryCmHandlesByPublicProperties(
126             final CmHandleQueryServiceParameters cmHandleQueryServiceParameters, final boolean outputAlternateId) {
127
128         final Map<String, String> publicPropertyQueryPairs =
129                 getPropertyPairs(cmHandleQueryServiceParameters.getCmHandleQueryParameters(),
130                         HAS_ALL_PROPERTIES.getConditionName());
131
132         if (publicPropertyQueryPairs.isEmpty()) {
133             return NO_QUERY_TO_EXECUTE;
134         }
135         return cmHandleQueryService.queryPublicCmHandleProperties(publicPropertyQueryPairs, outputAlternateId);
136     }
137
138     private Collection<String> queryCmHandlesByTrustLevel(final CmHandleQueryServiceParameters
139                                                                   cmHandleQueryServiceParameters,
140                                                           final boolean outputAlternateId) {
141
142         final Map<String, String> trustLevelPropertyQueryPairs =
143                 getPropertyPairs(cmHandleQueryServiceParameters.getCmHandleQueryParameters(),
144                         WITH_TRUST_LEVEL.getConditionName());
145
146         if (trustLevelPropertyQueryPairs.isEmpty()) {
147             return NO_QUERY_TO_EXECUTE;
148         }
149         return cmHandleQueryService.queryCmHandlesByTrustLevel(trustLevelPropertyQueryPairs, outputAlternateId);
150     }
151
152     private Collection<String> executeModuleNameQuery(
153             final CmHandleQueryServiceParameters cmHandleQueryServiceParameters, final boolean outputAlternateId) {
154         final Collection<String> moduleNamesForQuery =
155                 getModuleNamesForQuery(cmHandleQueryServiceParameters.getCmHandleQueryParameters());
156         if (moduleNamesForQuery.isEmpty()) {
157             return NO_QUERY_TO_EXECUTE;
158         }
159         return inventoryPersistence.getCmHandleReferencesWithGivenModules(moduleNamesForQuery, outputAlternateId);
160     }
161
162     private Collection<String> executeCpsPathQuery(
163             final CmHandleQueryServiceParameters cmHandleQueryServiceParameters, final boolean outputAlternateId) {
164         final Map<String, String> cpsPathCondition
165                 = getCpsPathCondition(cmHandleQueryServiceParameters.getCmHandleQueryParameters());
166         if (!validateCpsPathConditionProperties(cpsPathCondition)) {
167             return Collections.emptySet();
168         }
169         final Collection<String> cpsPathQueryResult;
170         if (cpsPathCondition.isEmpty()) {
171             return NO_QUERY_TO_EXECUTE;
172         }
173         try {
174             cpsPathQueryResult = cmHandleQueryService.getCmHandleReferencesByCpsPath(cpsPathCondition.get("cpsPath"),
175                     outputAlternateId);
176         } catch (final PathParsingException pathParsingException) {
177             throw new DataValidationException(pathParsingException.getMessage(), pathParsingException.getDetails(),
178                     pathParsingException);
179         }
180         return cpsPathQueryResult;
181     }
182
183     private Collection<String> getModuleNamesForQuery(final List<ConditionProperties> conditionProperties) {
184         final List<String> result = new ArrayList<>();
185         getConditions(conditionProperties, HAS_ALL_MODULES.getConditionName()).forEach(
186                 conditionProperty -> {
187                     validateModuleNameConditionProperties(conditionProperty);
188                     result.add(conditionProperty.get("moduleName"));
189                 });
190         return result;
191     }
192
193     private Map<String, String> getCpsPathCondition(final List<ConditionProperties> conditionProperties) {
194         final Map<String, String> result = new HashMap<>();
195         getConditions(conditionProperties, WITH_CPS_PATH.getConditionName()).forEach(result::putAll);
196         return result;
197     }
198
199     private Map<String, String> getPropertyPairs(final List<ConditionProperties> conditionProperties,
200                                                  final String queryProperty) {
201         final Map<String, String> result = new HashMap<>();
202         getConditions(conditionProperties, queryProperty).forEach(result::putAll);
203         return result;
204     }
205
206     private List<Map<String, String>> getConditions(final List<ConditionProperties> conditionProperties,
207                                                     final String name) {
208         for (final ConditionProperties conditionProperty : conditionProperties) {
209             if (conditionProperty.getConditionName().equals(name)) {
210                 return conditionProperty.getConditionParameters();
211             }
212         }
213         return Collections.emptyList();
214     }
215
216     private Collection<String> getAllCmHandleReferences(final boolean outputAlternateId) {
217         return cmHandleQueryService.getAllCmHandleReferences(outputAlternateId);
218     }
219
220     private Flux<NcmpServiceCmHandle> getNcmpServiceCmHandles(final Collection<String> cmHandleIds) {
221         return Flux.fromIterable(cmHandleIds)
222                 .buffer(FLUX_BUFFER_SIZE)
223                 .map(this::getNcmpServiceCmHandleBatch)
224                 .flatMap(Flux::fromIterable);
225     }
226
227     private Collection<NcmpServiceCmHandle> getNcmpServiceCmHandleBatch(final Collection<String> cmHandleIds) {
228         final Collection<YangModelCmHandle> yangModelcmHandles
229                 = inventoryPersistence.getYangModelCmHandles(cmHandleIds);
230
231         final Collection<NcmpServiceCmHandle> ncmpServiceCmHandles = new ArrayList<>(yangModelcmHandles.size());
232
233         yangModelcmHandles.forEach(yangModelcmHandle ->
234                 ncmpServiceCmHandles.add(YangDataConverter.toNcmpServiceCmHandle(yangModelcmHandle))
235         );
236         trustLevelManager.applyEffectiveTrustLevels(ncmpServiceCmHandles);
237         return ncmpServiceCmHandles;
238     }
239
240     private Collection<String> executeQueries(final CmHandleQueryServiceParameters cmHandleQueryServiceParameters,
241                                               final boolean outputAlternateId,
242                                               final BiFunction<CmHandleQueryServiceParameters, Boolean,
243                                                       Collection<String>>... queryFunctions) {
244         if (cmHandleQueryServiceParameters.getCmHandleQueryParameters().isEmpty()) {
245             return getAllCmHandleReferences(outputAlternateId);
246         }
247         Collection<String> combinedQueryResult = NO_QUERY_TO_EXECUTE;
248         for (final BiFunction<CmHandleQueryServiceParameters, Boolean,
249                 Collection<String>> queryFunction : queryFunctions) {
250             final Collection<String> queryResult = queryFunction.apply(cmHandleQueryServiceParameters,
251                     outputAlternateId);
252             if (noEntriesFoundCanStopQuerying(queryResult)) {
253                 return Collections.emptySet();
254             }
255             combinedQueryResult = combineCmHandleQueryResults(combinedQueryResult, queryResult);
256         }
257         return combinedQueryResult;
258     }
259
260     private boolean noEntriesFoundCanStopQuerying(final Collection<String> queryResult) {
261         return queryResult != NO_QUERY_TO_EXECUTE && queryResult.isEmpty();
262     }
263
264     private Collection<String> combineCmHandleQueryResults(final Collection<String> firstQuery,
265                                                            final Collection<String> secondQuery) {
266         if (firstQuery == NO_QUERY_TO_EXECUTE && secondQuery == NO_QUERY_TO_EXECUTE) {
267             return NO_QUERY_TO_EXECUTE;
268         } else if (firstQuery == NO_QUERY_TO_EXECUTE) {
269             return secondQuery;
270         } else if (secondQuery == NO_QUERY_TO_EXECUTE) {
271             return firstQuery;
272         } else {
273             firstQuery.retainAll(secondQuery);
274             return firstQuery;
275         }
276     }
277
278 }