e69ddb7375c3e0168961cfdf35c7390369648689
[ccsdk/features.git] /
1 /*
2  * ============LICENSE_START=======================================================
3  * ONAP : ccsdk features
4  * ================================================================================
5  * Copyright (C) 2020 highstreet technologies GmbH Intellectual Property.
6  * All rights reserved.
7  * ================================================================================
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *     http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  * ============LICENSE_END=========================================================
20  *
21  */
22 package org.onap.ccsdk.features.sdnr.wt.dataprovider.impl;
23
24 import java.io.IOException;
25 import java.util.ArrayList;
26 import java.util.List;
27 import org.json.JSONObject;
28 import org.onap.ccsdk.features.sdnr.wt.common.database.HtDatabaseClient;
29 import org.onap.ccsdk.features.sdnr.wt.common.database.SearchHit;
30 import org.onap.ccsdk.features.sdnr.wt.common.database.queries.BoolQueryBuilder;
31 import org.onap.ccsdk.features.sdnr.wt.common.database.queries.QueryBuilder;
32 import org.onap.ccsdk.features.sdnr.wt.common.database.queries.QueryBuilders;
33 import org.onap.ccsdk.features.sdnr.wt.common.database.queries.SortOrder;
34 import org.onap.ccsdk.features.sdnr.wt.common.database.requests.Search7Request;
35 import org.onap.ccsdk.features.sdnr.wt.common.database.requests.SearchRequest;
36 import org.onap.ccsdk.features.sdnr.wt.common.database.responses.AggregationEntries;
37 import org.onap.ccsdk.features.sdnr.wt.common.database.responses.SearchResponse;
38 import org.onap.ccsdk.features.sdnr.wt.dataprovider.http.DataTreeChildObject;
39 import org.onap.ccsdk.features.sdnr.wt.dataprovider.http.DataTreeObject;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.Entity;
41
42 /**
43  * @author Michael Dürre
44  *
45  */
46 public class DataTreeProviderImpl {
47
48     private static final long MAXSIZE_PERSEARCH = 10;
49     private HtDatabaseClient dbClient;
50     private static final String INVENTORY_PROPERTY_TREELEVEL = "tree-level";
51     private static final String INVENTORY_PROPERTY_NODEID = "node-id";
52     private static final String INVENTORY_PROPERTY_UUID = "uuid";
53     private static final String INVENTORY_PROPERTY_PARENTUUID = "parent-uuid";
54     private static final String INVENTORY_PROPERTY_FOR_LABEL_CHILD = "uuid";
55     private static final String INVENTORY_PROPERTY_FOR_LABEL = "uuid";
56
57     private List<SearchHit> search(Entity e, String filter, String propTreeLevel) throws IOException {
58         return this.search(e, filter, null, null, null, null, null, null, propTreeLevel);
59     }
60
61     private List<SearchHit> search(Entity e, String filter, String nodeKey, String nodeId, String parentKey,
62             String parentValue, String childKey, String childValue, String propTreeLevel) throws IOException {
63         QueryBuilder query =
64                 filter == null ? QueryBuilders.matchAllQuery() : QueryBuilders.searchAllFieldsQuery(filter);
65         if ((nodeId != null && nodeKey != null) || (parentKey != null && parentValue != null)) {
66             BoolQueryBuilder bquery = new BoolQueryBuilder();
67             if (filter != null) {
68                 bquery.must(query);
69             }
70             if (nodeId != null) {
71                 bquery.must(QueryBuilders.matchQuery(nodeKey, nodeId));
72             }
73             //                  if (parentKey != null && parentValue != null) {
74             //                          bquery.must(QueryBuilders.matchQuery(parentKey, parentValue));
75             //                  }
76             //                  if (childKey != null && childValue != null) {
77             //                          bquery.must(QueryBuilders.matchQuery(childKey, childValue));
78             //                  }
79             query = bquery;
80
81         }
82         return this.search(e, query, propTreeLevel);
83     }
84
85     private List<SearchHit> search(Entity e, QueryBuilder query, String propTreeLevel) throws IOException {
86         List<SearchHit> list = new ArrayList<SearchHit>();
87         query.sort(propTreeLevel, SortOrder.ASCENDING);
88         SearchRequest request = new Search7Request(Entity.Inventoryequipment.getName());
89         query.size(MAXSIZE_PERSEARCH);
90         request.setQuery(query);
91         SearchResponse response = this.dbClient.search(request);
92         SearchHit[] matches = response.getHits();
93         for (SearchHit hit : matches) {
94             list.add(hit);
95         }
96         if (response.getTotal() > MAXSIZE_PERSEARCH) {
97             long todo = response.getTotal();
98             long from = MAXSIZE_PERSEARCH;
99             while (todo > from) {
100                 request.setQuery(query.from(from));
101                 from += MAXSIZE_PERSEARCH;
102                 //merge into list
103                 response = this.dbClient.search(request);
104                 matches = response.getHits();
105                 for (SearchHit hit : matches) {
106                     list.add(hit);
107                 }
108             }
109         }
110         return list;
111     }
112
113     /**
114      * @param iNVENTORY_PROPERTY_NODEID2
115      * @return
116      * @throws IOException
117      */
118     private AggregationEntries searchAggregated(Entity e, String key) throws IOException {
119         QueryBuilder query = QueryBuilders.matchAllQuery().aggregations(key).size(MAXSIZE_PERSEARCH);
120         SearchRequest request = new Search7Request(e.getName());
121         request.setQuery(query);
122         SearchResponse response = this.dbClient.search(request);
123         return response.getAggregations(key);
124     }
125
126     /**
127      *
128      * @param tree
129      * @param filter
130      * @param
131      * @return
132      * @throws IOException
133      */
134     public DataTreeObject readInventoryTree(List<String> tree, String filter) throws IOException {
135
136         //root nodes will be node-information -> below inventory
137         if (tree == null || tree.size() <= 0) {
138             return this.readInventoryTreeWithNode(filter);
139         }
140         //root node will be inventory on tree-level if sliced treePath
141         else {
142             return this.readInventoryTreeForNode(tree.get(0), tree.subList(0, tree.size() - 1), filter);
143         }
144
145     }
146
147     /**
148      * @param string
149      * @param slice
150      * @param filter
151      * @param mode
152      * @return
153      */
154     private DataTreeObject readInventoryTreeForNode(String nodeId, List<String> list, String filter)
155             throws IOException {
156         DataTreeObject tree = new DataTreeObject(INVENTORY_PROPERTY_PARENTUUID, INVENTORY_PROPERTY_UUID);
157         final String parentUuid = list.size() > 1 ? list.get(list.size() - 2) : null;
158         final String uuid = list.size() > 0 ? list.get(list.size() - 1) : null;
159         List<SearchHit> matches = this.search(Entity.Inventoryequipment, filter, INVENTORY_PROPERTY_NODEID, nodeId,
160                 INVENTORY_PROPERTY_PARENTUUID, parentUuid, INVENTORY_PROPERTY_UUID, uuid, INVENTORY_PROPERTY_TREELEVEL);
161
162         //tree.a(subtreePath);
163         List<SearchHit> others = this.search(Entity.Inventoryequipment, (String) null, INVENTORY_PROPERTY_NODEID, nodeId,
164                 null, null, null, null, INVENTORY_PROPERTY_TREELEVEL);
165         if (matches.size() > 0) {
166             int treeLevelToStart = (list == null || list.size() <= 0) ? 0 : list.size() - 1;
167             //build tree
168             JSONObject hitData;
169             //fill root elems
170             for (SearchHit hit : matches) {
171                 hitData = hit.getSource();
172                 if (hitData.getLong("tree-level") == treeLevelToStart) {
173                     tree.put(hit.getId(),
174                             new DataTreeChildObject(hitData.getString(INVENTORY_PROPERTY_FOR_LABEL), true)
175                                     .setProperty(INVENTORY_PROPERTY_UUID, hitData.getString(INVENTORY_PROPERTY_UUID))
176                                     .setProperty(INVENTORY_PROPERTY_PARENTUUID,
177                                             hitData.getString(INVENTORY_PROPERTY_PARENTUUID)));
178                 }
179             }
180             for (SearchHit hit : others) {
181                 hitData = hit.getSource();
182                 if (hitData.getLong("tree-level") == treeLevelToStart) {
183                     tree.putIfNotExists(hit.getId(),
184                             new DataTreeChildObject(hitData.getString(INVENTORY_PROPERTY_FOR_LABEL), false)
185                                     .setProperty(INVENTORY_PROPERTY_UUID, hitData.getString(INVENTORY_PROPERTY_UUID))
186                                     .setProperty(INVENTORY_PROPERTY_PARENTUUID,
187                                             hitData.getString(INVENTORY_PROPERTY_PARENTUUID)));
188                 }
189             }
190             //fill child elems
191             for (SearchHit hit : matches) {
192                 hitData = hit.getSource();
193                 if (hitData.getLong("tree-level") > treeLevelToStart) {
194                     tree.put(hitData.getLong("tree-level") - treeLevelToStart - 1, hit.getId(),
195                             new DataTreeChildObject(hitData.getString(INVENTORY_PROPERTY_FOR_LABEL), true)
196                                     .setProperty(INVENTORY_PROPERTY_UUID, hitData.getString(INVENTORY_PROPERTY_UUID))
197                                     .setProperty(INVENTORY_PROPERTY_PARENTUUID,
198                                             hitData.getString(INVENTORY_PROPERTY_PARENTUUID)));
199                 }
200             }
201             for (SearchHit hit : others) {
202                 hitData = hit.getSource();
203                 if (hitData.getLong("tree-level") > treeLevelToStart) {
204                     tree.putIfNotExists(hitData.getLong("tree-level") - treeLevelToStart - 1, hit.getId(),
205                             new DataTreeChildObject(hitData.getString(INVENTORY_PROPERTY_FOR_LABEL), false)
206                                     .setProperty(INVENTORY_PROPERTY_UUID, hitData.getString(INVENTORY_PROPERTY_UUID))
207                                     .setProperty(INVENTORY_PROPERTY_PARENTUUID,
208                                             hitData.getString(INVENTORY_PROPERTY_PARENTUUID)));
209                 }
210             }
211             tree.removeUnmatchedPaths();
212         }
213         return tree;
214     }
215
216     /**
217      * node will be root elements inventory information below from level-1
218      *
219      * @param filter
220      * @return
221      * @throws IOException
222      */
223     private DataTreeObject readInventoryTreeWithNode(String filter) throws IOException {
224         DataTreeObject tree = new DataTreeObject(INVENTORY_PROPERTY_PARENTUUID, INVENTORY_PROPERTY_UUID);
225
226         List<SearchHit> matches = this.search(Entity.Inventoryequipment, filter, INVENTORY_PROPERTY_TREELEVEL);
227         List<SearchHit> others = null;
228         if (matches.size() > 0) {
229             if (filter != null) {
230                 //find all parents up to tree-level 0
231                 String nodeId = "";
232                 List<String> alreadyInList = new ArrayList<>();
233                 BoolQueryBuilder query2 = QueryBuilders.boolQuery();
234                 for (SearchHit hit : matches) {
235                     nodeId = hit.getSource().getString(INVENTORY_PROPERTY_NODEID);
236                     if (alreadyInList.contains(nodeId)) {
237                         continue;
238                     }
239                     query2.should(QueryBuilders.matchQuery(INVENTORY_PROPERTY_NODEID, nodeId));
240                     alreadyInList.add(nodeId);
241                     tree.put(nodeId,
242                             new DataTreeChildObject(nodeId, false).setProperty(INVENTORY_PROPERTY_UUID, nodeId));
243
244                 }
245                 others = this.search(Entity.Inventoryequipment, query2, INVENTORY_PROPERTY_TREELEVEL);
246             } else {
247                 AggregationEntries nodes = this.searchAggregated(Entity.Inventoryequipment, INVENTORY_PROPERTY_NODEID);
248                 for (String node : nodes.keySet()) {
249                     tree.put(node, new DataTreeChildObject(node, false).setProperty(INVENTORY_PROPERTY_UUID, node));
250                 }
251             }
252
253             //build tree
254             JSONObject hitData;
255             //fill root elems
256             for (SearchHit hit : matches) {
257                 hitData = hit.getSource();
258                 if (hitData.getLong("tree-level") == 0) {
259                     tree.put(0, hit.getId(),
260                             new DataTreeChildObject(hitData.getString(INVENTORY_PROPERTY_FOR_LABEL), true)
261                                     .setProperty(INVENTORY_PROPERTY_UUID, hitData.getString(INVENTORY_PROPERTY_UUID))
262                                     .setProperty(INVENTORY_PROPERTY_PARENTUUID,
263                                             hitData.getString(INVENTORY_PROPERTY_NODEID)));
264                 }
265             }
266             if (others != null) {
267                 for (SearchHit hit : others) {
268                     hitData = hit.getSource();
269                     if (hitData.getLong("tree-level") == 0) {
270                         tree.putIfNotExists(0, hit.getId(),
271                                 new DataTreeChildObject(hitData.getString(INVENTORY_PROPERTY_FOR_LABEL), false)
272                                         .setProperty(INVENTORY_PROPERTY_UUID,
273                                                 hitData.getString(INVENTORY_PROPERTY_UUID))
274                                         .setProperty(INVENTORY_PROPERTY_PARENTUUID,
275                                                 hitData.getString(INVENTORY_PROPERTY_NODEID)));
276                     }
277                 }
278             }
279             //fill child elements
280             for (SearchHit hit : matches) {
281                 hitData = hit.getSource();
282                 long treeLevel = hitData.getLong("tree-level");
283                 if (treeLevel > 0) {
284                     tree.put(treeLevel, hit.getId(),
285                             new DataTreeChildObject(hitData.getString(INVENTORY_PROPERTY_FOR_LABEL_CHILD), true)
286                                     .setProperty(INVENTORY_PROPERTY_UUID, hitData.getString(INVENTORY_PROPERTY_UUID))
287                                     .setProperty(INVENTORY_PROPERTY_PARENTUUID,
288                                             hitData.getString(INVENTORY_PROPERTY_PARENTUUID)));
289                 }
290             }
291             if (others != null) {
292                 for (SearchHit hit : others) {
293                     hitData = hit.getSource();
294                     long treeLevel = hitData.getLong("tree-level");
295                     if (hitData.getLong("tree-level") > 0) {
296                         tree.putIfNotExists(treeLevel, hit.getId(),
297                                 new DataTreeChildObject(hitData.getString(INVENTORY_PROPERTY_FOR_LABEL_CHILD), false)
298                                         .setProperty(INVENTORY_PROPERTY_UUID,
299                                                 hitData.getString(INVENTORY_PROPERTY_UUID))
300                                         .setProperty(INVENTORY_PROPERTY_PARENTUUID,
301                                                 hitData.getString(INVENTORY_PROPERTY_PARENTUUID)));
302                     }
303                 }
304             }
305             tree.removeUnmatchedPaths();
306
307         }
308         return tree;
309     }
310
311
312
313     /**
314      * @param client
315      */
316     public void setDatabaseClient(HtDatabaseClient client) {
317         this.dbClient = client;
318
319     }
320 }