569e91e2c95d4ff26d4ace8bb2d1aa6b408ea983
[cps.git] / cps-ncmp-service / src / main / java / org / onap / cps / ncmp / api / inventory / CmHandleQueries.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.inventory;
22
23 import static org.onap.cps.ncmp.api.impl.utils.YangDataConverter.convertYangModelCmHandleToNcmpServiceCmHandle;
24 import static org.onap.cps.spi.FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS;
25 import static org.onap.cps.spi.FetchDescendantsOption.OMIT_DESCENDANTS;
26
27 import java.util.Collection;
28 import java.util.Collections;
29 import java.util.HashMap;
30 import java.util.HashSet;
31 import java.util.List;
32 import java.util.Map;
33 import java.util.Set;
34 import java.util.stream.Collectors;
35 import lombok.RequiredArgsConstructor;
36 import org.onap.cps.ncmp.api.impl.utils.YangDataConverter;
37 import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle;
38 import org.onap.cps.spi.CpsDataPersistenceService;
39 import org.onap.cps.spi.FetchDescendantsOption;
40 import org.onap.cps.spi.model.DataNode;
41 import org.springframework.stereotype.Component;
42
43 @RequiredArgsConstructor
44 @Component
45 public class CmHandleQueries {
46
47     private static final String NCMP_DATASPACE_NAME = "NCMP-Admin";
48     private static final String NCMP_DMI_REGISTRY_ANCHOR = "ncmp-dmi-registry";
49
50     private final CpsDataPersistenceService cpsDataPersistenceService;
51     private static final Map<String, NcmpServiceCmHandle> NO_QUERY_TO_EXECUTE = null;
52     private static final String ANCESTOR_CM_HANDLES = "/ancestor::cm-handles";
53
54
55     /**
56      * Query CmHandles based on PublicProperties.
57      *
58      * @param publicPropertyQueryPairs public properties for query
59      * @return CmHandles which have these public properties
60      */
61     public Map<String, NcmpServiceCmHandle> queryCmHandlePublicProperties(
62             final Map<String, String> publicPropertyQueryPairs) {
63         if (publicPropertyQueryPairs.isEmpty()) {
64             return Collections.emptyMap();
65         }
66         Map<String, NcmpServiceCmHandle> cmHandleIdToNcmpServiceCmHandles = null;
67         for (final Map.Entry<String, String> publicPropertyQueryPair : publicPropertyQueryPairs.entrySet()) {
68             final String cpsPath = "//public-properties[@name=\"" + publicPropertyQueryPair.getKey()
69                     + "\" and @value=\"" + publicPropertyQueryPair.getValue() + "\"]";
70
71             final Collection<DataNode> dataNodes = queryCmHandleDataNodesByCpsPath(cpsPath, INCLUDE_ALL_DESCENDANTS);
72             if (cmHandleIdToNcmpServiceCmHandles == null) {
73                 cmHandleIdToNcmpServiceCmHandles = collectDataNodesToNcmpServiceCmHandles(dataNodes);
74             } else {
75                 final Collection<String> cmHandleIdsToRetain = dataNodes.parallelStream()
76                         .map(dataNode -> dataNode.getLeaves().get("id").toString()).collect(Collectors.toSet());
77                 cmHandleIdToNcmpServiceCmHandles.keySet().retainAll(cmHandleIdsToRetain);
78             }
79             if (cmHandleIdToNcmpServiceCmHandles.isEmpty()) {
80                 break;
81             }
82         }
83         return cmHandleIdToNcmpServiceCmHandles;
84     }
85
86     /**
87      * Combine Maps of CmHandles.
88      *
89      * @param firstQuery first CmHandles Map
90      * @param secondQuery second CmHandles Map
91      * @return combined Map of CmHandles
92      */
93     public Map<String, NcmpServiceCmHandle> combineCmHandleQueries(
94             final Map<String, NcmpServiceCmHandle> firstQuery,
95             final Map<String, NcmpServiceCmHandle> secondQuery) {
96         if (firstQuery == NO_QUERY_TO_EXECUTE && secondQuery == NO_QUERY_TO_EXECUTE) {
97             return NO_QUERY_TO_EXECUTE;
98         } else if (firstQuery == NO_QUERY_TO_EXECUTE) {
99             return secondQuery;
100         } else if (secondQuery == NO_QUERY_TO_EXECUTE) {
101             return firstQuery;
102         } else {
103             firstQuery.keySet().retainAll(secondQuery.keySet());
104             return firstQuery;
105         }
106     }
107
108     /**
109      * Method which returns cm handles by the cm handles state.
110      *
111      * @param cmHandleState cm handle state
112      * @return a list of cm handles
113      */
114     public List<DataNode> queryCmHandlesByState(final CmHandleState cmHandleState) {
115         return queryCmHandleDataNodesByCpsPath("//state[@cm-handle-state=\"" + cmHandleState + "\"]",
116             INCLUDE_ALL_DESCENDANTS);
117     }
118
119     /**
120      * Method to return data nodes representing the cm handles.
121      *
122      * @param cpsPath cps path for which the cmHandle is requested
123      * @return a list of data nodes representing the cm handles.
124      */
125     public List<DataNode> queryCmHandleDataNodesByCpsPath(final String cpsPath,
126                                                           final FetchDescendantsOption fetchDescendantsOption) {
127         return cpsDataPersistenceService.queryDataNodes(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR,
128             cpsPath + ANCESTOR_CM_HANDLES, fetchDescendantsOption);
129     }
130
131     /**
132      * Method to check the state of a cm handle with given id.
133      *
134      * @param cmHandleId cm handle id
135      * @param requiredCmHandleState the required state of the cm handle
136      * @return a boolean, true if the state is equal to the required state
137      */
138     public boolean cmHandleHasState(final String cmHandleId, final CmHandleState requiredCmHandleState) {
139         final DataNode stateDataNode = getCmHandleState(cmHandleId);
140         final String cmHandleStateAsString = (String) stateDataNode.getLeaves().get("cm-handle-state");
141         return CmHandleState.valueOf(cmHandleStateAsString).equals(requiredCmHandleState);
142     }
143
144     /**
145      * Method which returns cm handles by the operational sync state of cm handle.
146      * @param dataStoreSyncState sync state
147      * @return a list of cm handles
148      */
149     public List<DataNode> queryCmHandlesByOperationalSyncState(final DataStoreSyncState dataStoreSyncState) {
150         return queryCmHandleDataNodesByCpsPath("//state/datastores" + "/operational[@sync-state=\""
151                 + dataStoreSyncState + "\"]", FetchDescendantsOption.OMIT_DESCENDANTS);
152     }
153
154     private Map<String, NcmpServiceCmHandle> collectDataNodesToNcmpServiceCmHandles(
155             final Collection<DataNode> dataNodes) {
156         final Map<String, NcmpServiceCmHandle> cmHandleIdToNcmpServiceCmHandle = new HashMap<>();
157         dataNodes.forEach(dataNode -> {
158             final NcmpServiceCmHandle ncmpServiceCmHandle = createNcmpServiceCmHandle(dataNode);
159             cmHandleIdToNcmpServiceCmHandle.put(ncmpServiceCmHandle.getCmHandleId(), ncmpServiceCmHandle);
160         });
161         return cmHandleIdToNcmpServiceCmHandle;
162     }
163
164     private NcmpServiceCmHandle createNcmpServiceCmHandle(final DataNode dataNode) {
165         return convertYangModelCmHandleToNcmpServiceCmHandle(YangDataConverter
166                 .convertCmHandleToYangModel(dataNode, dataNode.getLeaves().get("id").toString()));
167     }
168
169     /**
170      * Get all cm handles by DMI plugin identifier.
171      *
172      * @param dmiPluginIdentifier DMI plugin identifier
173      * @return set of cm handles
174      */
175     public Set<NcmpServiceCmHandle> getCmHandlesByDmiPluginIdentifier(final String dmiPluginIdentifier) {
176         final Map<String, DataNode> cmHandleAsDataNodePerCmHandleId = new HashMap<>();
177         for (final ModelledDmiServiceLeaves modelledDmiServiceLeaf : ModelledDmiServiceLeaves.values()) {
178             for (final DataNode cmHandleAsDataNode: getCmHandlesByDmiPluginIdentifierAndDmiProperty(
179                     dmiPluginIdentifier,
180                     modelledDmiServiceLeaf.getLeafName())) {
181                 cmHandleAsDataNodePerCmHandleId.put(
182                         cmHandleAsDataNode.getLeaves().get("id").toString(), cmHandleAsDataNode);
183             }
184         }
185         final Set<NcmpServiceCmHandle> ncmpServiceCmHandles = new HashSet<>(cmHandleAsDataNodePerCmHandleId.size());
186         cmHandleAsDataNodePerCmHandleId.values().forEach(
187                 cmHandleAsDataNode -> ncmpServiceCmHandles.add(createNcmpServiceCmHandle(cmHandleAsDataNode)));
188         return ncmpServiceCmHandles;
189     }
190
191     private List<DataNode> getCmHandlesByDmiPluginIdentifierAndDmiProperty(final String dmiPluginIdentifier,
192                                                              final String dmiProperty) {
193         return cpsDataPersistenceService.queryDataNodes(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR,
194                 "/dmi-registry/cm-handles[@" + dmiProperty + "='" + dmiPluginIdentifier + "']",
195                 OMIT_DESCENDANTS);
196     }
197
198     private DataNode getCmHandleState(final String cmHandleId) {
199         final String xpath = "/dmi-registry/cm-handles[@id='" + cmHandleId + "']/state";
200         return cpsDataPersistenceService.getDataNode(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR,
201                 xpath, OMIT_DESCENDANTS);
202     }
203 }
204
205