Fix release notes
[cps.git] / cps-ncmp-service / src / main / java / org / onap / cps / ncmp / api / impl / NetworkCmProxyCmHandlerQueryServiceImpl.java
1 /*
2  *  ============LICENSE_START=======================================================
3  *  Copyright (C) 2022 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.constants.DmiRegistryConstants.NCMP_DATASPACE_NAME;
24 import static org.onap.cps.ncmp.api.impl.constants.DmiRegistryConstants.NCMP_DMI_REGISTRY_ANCHOR;
25 import static org.onap.cps.spi.FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS;
26 import static org.onap.cps.utils.CmHandleQueryRestParametersValidator.validateModuleNameConditionProperties;
27
28 import java.util.ArrayList;
29 import java.util.Collection;
30 import java.util.Collections;
31 import java.util.HashMap;
32 import java.util.List;
33 import java.util.Map;
34 import lombok.RequiredArgsConstructor;
35 import lombok.extern.slf4j.Slf4j;
36 import org.onap.cps.ncmp.api.NetworkCmProxyCmHandlerQueryService;
37 import org.onap.cps.spi.CpsAdminPersistenceService;
38 import org.onap.cps.spi.CpsDataPersistenceService;
39 import org.onap.cps.spi.model.Anchor;
40 import org.onap.cps.spi.model.CmHandleQueryParameters;
41 import org.onap.cps.spi.model.ConditionProperties;
42 import org.onap.cps.spi.model.DataNode;
43 import org.onap.cps.spi.model.DataNodeIdentifier;
44 import org.onap.cps.utils.JsonObjectMapper;
45 import org.springframework.stereotype.Service;
46
47 @Service
48 @Slf4j
49 @RequiredArgsConstructor
50 public class NetworkCmProxyCmHandlerQueryServiceImpl implements NetworkCmProxyCmHandlerQueryService {
51
52     private static final String PROPERTY_QUERY_NAME = "hasAllProperties";
53     private static final String MODULE_QUERY_NAME = "hasAllModules";
54     private final CpsDataPersistenceService cpsDataPersistenceService;
55     private final CpsAdminPersistenceService cpsAdminPersistenceService;
56     private final JsonObjectMapper jsonObjectMapper;
57
58     /**
59      * Query and return cm handles that match the given query parameters.
60      *
61      * @param cmHandleQueryParameters the cm handle query parameters
62      * @return collection of cm handles
63      */
64     @Override
65     public Collection<DataNode> queryCmHandles(final CmHandleQueryParameters cmHandleQueryParameters) {
66
67         if (cmHandleQueryParameters.getCmHandleQueryParameters().isEmpty()) {
68             return getAllCmHandles();
69         }
70
71         final Collection<DataNodeIdentifier> amalgamatedQueryResultIdentifiers = new ArrayList<>();
72         final Map<DataNodeIdentifier, DataNode> amalgamatedQueryResults = new HashMap<>();
73
74         final boolean firstQuery = moduleNameQuery(cmHandleQueryParameters,
75                 amalgamatedQueryResultIdentifiers, amalgamatedQueryResults);
76
77         publicPropertyQuery(cmHandleQueryParameters, amalgamatedQueryResultIdentifiers,
78                 amalgamatedQueryResults, firstQuery);
79
80         final Collection<DataNode> filteredDataNodes = new ArrayList<>();
81         amalgamatedQueryResultIdentifiers.forEach(amalgamatedQueryResultIdentifier ->
82             filteredDataNodes.add(amalgamatedQueryResults.get(amalgamatedQueryResultIdentifier))
83         );
84
85         return filteredDataNodes;
86     }
87
88     private void publicPropertyQuery(final CmHandleQueryParameters cmHandleQueryParameters,
89                                      final Collection<DataNodeIdentifier> amalgamatedQueryResultIdentifiers,
90                                      final Map<DataNodeIdentifier, DataNode> amalgamatedQueryResults,
91                                      boolean firstQuery) {
92         for (final Map.Entry<String, String> entry :
93                 getPublicPropertyPairs(cmHandleQueryParameters.getCmHandleQueryParameters()).entrySet()) {
94             final String cmHandlePath = "//public-properties[@name='" + entry.getKey() + "' " + "and @value='"
95                     + entry.getValue() + "']" + "/ancestor::cm-handles";
96
97             final Collection<DataNode> dataNodes = getDataNodes(cmHandlePath);
98
99             if (firstQuery) {
100                 firstQuery = false;
101                 dataNodes.forEach(dataNode -> {
102                     final DataNodeIdentifier dataNodeIdentifier =
103                             jsonObjectMapper.convertToValueType(dataNode, DataNodeIdentifier.class);
104                     amalgamatedQueryResultIdentifiers.add(dataNodeIdentifier);
105                     amalgamatedQueryResults.put(dataNodeIdentifier, dataNode);
106                 });
107             } else {
108                 final Collection<DataNodeIdentifier> singleConditionQueryDataNodeIdentifiers = new ArrayList<>();
109                 dataNodes.forEach(dataNode -> {
110                     final DataNodeIdentifier dataNodeIdentifier =
111                             jsonObjectMapper.convertToValueType(dataNode, DataNodeIdentifier.class);
112                     singleConditionQueryDataNodeIdentifiers.add(dataNodeIdentifier);
113                     amalgamatedQueryResults.put(dataNodeIdentifier, dataNode);
114                 });
115                 amalgamatedQueryResultIdentifiers.retainAll(singleConditionQueryDataNodeIdentifiers);
116             }
117
118             if (amalgamatedQueryResultIdentifiers.isEmpty()) {
119                 break;
120             }
121         }
122     }
123
124     private boolean moduleNameQuery(final CmHandleQueryParameters cmHandleQueryParameters,
125                                     final Collection<DataNodeIdentifier> amalgamatedQueryResultIdentifiers,
126                                     final Map<DataNodeIdentifier, DataNode> amalgamatedQueryResults) {
127         boolean firstQuery = true;
128         if (!getModuleNames(cmHandleQueryParameters.getCmHandleQueryParameters()).isEmpty()) {
129             final Collection<Anchor> anchors = cpsAdminPersistenceService.queryAnchors("NFP-Operational",
130                     getModuleNames(cmHandleQueryParameters.getCmHandleQueryParameters()));
131             anchors.forEach(anchor -> {
132                 final List<DataNode> dataNodes = getDataNodes("//cm-handles[@id='" + anchor.getName() + "']");
133                 dataNodes.parallelStream().forEach(dataNode -> {
134                     final DataNodeIdentifier dataNodeIdentifier =
135                             jsonObjectMapper.convertToValueType(dataNode, DataNodeIdentifier.class);
136                     amalgamatedQueryResultIdentifiers.add(dataNodeIdentifier);
137                     amalgamatedQueryResults.put(dataNodeIdentifier, dataNode);
138                 });
139             });
140             firstQuery = false;
141         }
142         return firstQuery;
143     }
144
145     private List<Map<String, String>> getConditions(final List<ConditionProperties> conditionProperties,
146                                                     final String name) {
147         for (final ConditionProperties conditionProperty : conditionProperties) {
148             if (conditionProperty.getConditionName().equals(name)) {
149                 return conditionProperty.getConditionParameters();
150             }
151         }
152         return Collections.emptyList();
153     }
154
155     private List<String> getModuleNames(final List<ConditionProperties> conditionProperties) {
156         final List<String> result = new ArrayList<>();
157         getConditions(conditionProperties, MODULE_QUERY_NAME).parallelStream().forEach(
158                 conditionProperty -> {
159                     validateModuleNameConditionProperties(conditionProperty);
160                     result.add(conditionProperty.get("moduleName"));
161                 }
162         );
163         return result;
164     }
165
166     private Map<String, String> getPublicPropertyPairs(final List<ConditionProperties> conditionProperties) {
167         final Map<String, String> result = new HashMap<>();
168         getConditions(conditionProperties, PROPERTY_QUERY_NAME).forEach(result::putAll);
169         return result;
170     }
171
172     private Collection<DataNode> getAllCmHandles() {
173         return getDataNodes("//public-properties/ancestor::cm-handles");
174     }
175
176     private List<DataNode> getDataNodes(final String cmHandlePath) {
177         return cpsDataPersistenceService.queryDataNodes(
178                 NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, cmHandlePath, INCLUDE_ALL_DESCENDANTS);
179     }
180 }