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