SDN-R Server provide GUI cut through for ODLUX
[ccsdk/features.git] / sdnr / wt / data-provider / provider / src / main / java / org / onap / ccsdk / features / sdnr / wt / dataprovider / impl / DataTreeProviderImpl.java
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.DataTreeHttpServlet.FilterMode;
40 import org.onap.ccsdk.features.sdnr.wt.dataprovider.http.DataTreeObject;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.Entity;
42
43 /**
44  * @author Michael Dürre
45  *
46  */
47 public class DataTreeProviderImpl {
48
49     private static final long MAXSIZE_PERSEARCH = 10;
50     private HtDatabaseClient dbClient;
51     final String INVENTORY_PROPERTY_TREELEVEL = "tree-level";
52     final String INVENTORY_PROPERTY_NODEID = "node-id";
53     final String INVENTORY_PROPERTY_UUID = "uuid";
54     final String INVENTORY_PROPERTY_PARENTUUID = "parent-uuid";
55     final String INVENTORY_PROPERTY_FOR_LABEL_CHILD = "uuid";
56     final String INVENTORY_PROPERTY_FOR_LABEL = "uuid";
57
58     private List<SearchHit> search(Entity e, String filter, String propTreeLevel) throws IOException {
59         return this.search(e, filter, null, null, null, null, null, null, propTreeLevel);
60     }
61
62     private List<SearchHit> search(Entity e, String filter, String nodeKey, String nodeId, String parentKey,
63             String parentValue, String childKey, String childValue, String propTreeLevel) throws IOException {
64         QueryBuilder query =
65                 filter == null ? QueryBuilders.matchAllQuery() : QueryBuilders.searchAllFieldsQuery(filter);
66         if ((nodeId != null && nodeKey != null) || (parentKey != null && parentValue != null)) {
67             BoolQueryBuilder bquery = new BoolQueryBuilder();
68             if (filter != null) {
69                 bquery.must(query);
70             }
71             if (nodeId != null) {
72                 bquery.must(QueryBuilders.matchQuery(nodeKey, nodeId));
73             }
74             //                  if (parentKey != null && parentValue != null) {
75             //                          bquery.must(QueryBuilders.matchQuery(parentKey, parentValue));
76             //                  }
77             //                  if (childKey != null && childValue != null) {
78             //                          bquery.must(QueryBuilders.matchQuery(childKey, childValue));
79             //                  }
80             query = bquery;
81
82         }
83         return this.search(e, query, propTreeLevel);
84     }
85
86     private List<SearchHit> search(Entity e, QueryBuilder query, String propTreeLevel) throws IOException {
87         List<SearchHit> list = new ArrayList<SearchHit>();
88         query.sort(propTreeLevel, SortOrder.ASCENDING);
89         SearchRequest request = new Search7Request(Entity.Inventoryequipment.getName());
90         query.size(MAXSIZE_PERSEARCH);
91         request.setQuery(query);
92         SearchResponse response = this.dbClient.search(request);
93         SearchHit[] matches = response.getHits();
94         for (SearchHit hit : matches) {
95             list.add(hit);
96         }
97         if (response.getTotal() > MAXSIZE_PERSEARCH) {
98             long todo = response.getTotal();
99             long from = MAXSIZE_PERSEARCH;
100             while (todo > from) {
101                 request.setQuery(query.from(from));
102                 from += MAXSIZE_PERSEARCH;
103                 //merge into list
104                 response = this.dbClient.search(request);
105                 matches = response.getHits();
106                 for (SearchHit hit : matches) {
107                     list.add(hit);
108                 }
109             }
110         }
111         return list;
112     }
113
114     /**
115      * @param iNVENTORY_PROPERTY_NODEID2
116      * @return
117      * @throws IOException
118      */
119     private AggregationEntries searchAggregated(Entity e, String key) throws IOException {
120         QueryBuilder query = QueryBuilders.matchAllQuery().aggregations(key).size(MAXSIZE_PERSEARCH);
121         SearchRequest request = new Search7Request(e.getName());
122         request.setQuery(query);
123         SearchResponse response = this.dbClient.search(request);
124         return response.getAggregations(key);
125     }
126
127     /**
128      *
129      * @param tree
130      * @param filter
131      * @param
132      * @return
133      * @throws IOException
134      */
135     public DataTreeObject readInventoryTree(List<String> tree, String filter, FilterMode mode) throws IOException {
136
137         //root nodes will be node-information -> below inventory
138         if (tree == null || tree.size() <= 0) {
139             return this.readInventoryTreeWithNode(filter, mode);
140         }
141         //root node will be inventory on tree-level if sliced treePath
142         else {
143             return this.readInventoryTreeForNode(tree.get(0), tree.subList(0, tree.size() - 1), filter, mode);
144         }
145
146     }
147
148     /**
149      * @param string
150      * @param slice
151      * @param filter
152      * @param mode
153      * @return
154      */
155     private DataTreeObject readInventoryTreeForNode(String nodeId, List<String> list, String filter, FilterMode mode)
156             throws IOException {
157         DataTreeObject tree = new DataTreeObject(INVENTORY_PROPERTY_PARENTUUID, INVENTORY_PROPERTY_UUID);
158         final String parentUuid = list.size() > 1 ? list.get(list.size() - 2) : null;
159         final String uuid = list.size() > 0 ? list.get(list.size() - 1) : null;
160         List<SearchHit> matches = this.search(Entity.Inventoryequipment, filter, INVENTORY_PROPERTY_NODEID, nodeId,
161                 INVENTORY_PROPERTY_PARENTUUID, parentUuid, INVENTORY_PROPERTY_UUID, uuid, INVENTORY_PROPERTY_TREELEVEL);
162
163         //tree.a(subtreePath);
164         List<SearchHit> others = this.search(Entity.Inventoryequipment, (String) 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         }
212         return tree;
213     }
214
215     /**
216      * node will be root elements inventory information below from level-1
217      *
218      * @param filter
219      * @param mode
220      * @return
221      * @throws IOException
222      */
223     private DataTreeObject readInventoryTreeWithNode(String filter, FilterMode mode) 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             if (mode == FilterMode.Strict) {
306                 tree.removeUnmatchedPaths();
307             }
308         }
309         return tree;
310     }
311
312
313
314     /**
315      * @param client
316      */
317     public void setDatabaseClient(HtDatabaseClient client) {
318         this.dbClient = client;
319
320     }
321 }