cb62e3326f1e2b9d1cd797d67acecbb7329d8e34
[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             query = bquery;
74
75         }
76         return this.search(e, query, propTreeLevel);
77     }
78
79     private List<SearchHit> search(Entity e, QueryBuilder query, String propTreeLevel) throws IOException {
80         List<SearchHit> list = new ArrayList<SearchHit>();
81         query.sort(propTreeLevel, SortOrder.ASCENDING);
82         SearchRequest request = new Search7Request(Entity.Inventoryequipment.getName());
83         query.size(MAXSIZE_PERSEARCH);
84         request.setQuery(query);
85         SearchResponse response = this.dbClient.search(request);
86         SearchHit[] matches = response.getHits();
87         for (SearchHit hit : matches) {
88             list.add(hit);
89         }
90         if (response.getTotal() > MAXSIZE_PERSEARCH) {
91             long todo = response.getTotal();
92             long from = MAXSIZE_PERSEARCH;
93             while (todo > from) {
94                 request.setQuery(query.from(from));
95                 from += MAXSIZE_PERSEARCH;
96                 //merge into list
97                 response = this.dbClient.search(request);
98                 matches = response.getHits();
99                 for (SearchHit hit : matches) {
100                     list.add(hit);
101                 }
102             }
103         }
104         return list;
105     }
106
107     /**
108      * @param iNVENTORY_PROPERTY_NODEID2
109      * @return
110      * @throws IOException
111      */
112     private AggregationEntries searchAggregated(Entity e, String key) throws IOException {
113         QueryBuilder query = QueryBuilders.matchAllQuery().aggregations(key).size(MAXSIZE_PERSEARCH);
114         SearchRequest request = new Search7Request(e.getName());
115         request.setQuery(query);
116         SearchResponse response = this.dbClient.search(request);
117         return response.getAggregations(key);
118     }
119
120     /**
121      *
122      * @param tree
123      * @param filter
124      * @param
125      * @return
126      * @throws IOException
127      */
128     public DataTreeObject readInventoryTree(List<String> tree, String filter) throws IOException {
129
130         //root nodes will be node-information -> below inventory
131         if (tree == null || tree.size() <= 0) {
132             return this.readInventoryTreeWithNode(filter);
133         }
134         //root node will be inventory on tree-level if sliced treePath
135         else {
136             return this.readInventoryTreeForNode(tree.get(0), tree.subList(0, tree.size() - 1), filter);
137         }
138
139     }
140
141     /**
142      * @param string
143      * @param slice
144      * @param filter
145      * @param mode
146      * @return
147      */
148     private DataTreeObject readInventoryTreeForNode(String nodeId, List<String> list, String filter)
149             throws IOException {
150         DataTreeObject tree = new DataTreeObject(INVENTORY_PROPERTY_PARENTUUID, INVENTORY_PROPERTY_UUID);
151         final String parentUuid = list.size() > 1 ? list.get(list.size() - 2) : null;
152         final String uuid = list.size() > 0 ? list.get(list.size() - 1) : null;
153         List<SearchHit> matches = this.search(Entity.Inventoryequipment, filter, INVENTORY_PROPERTY_NODEID, nodeId,
154                 INVENTORY_PROPERTY_PARENTUUID, parentUuid, INVENTORY_PROPERTY_UUID, uuid, INVENTORY_PROPERTY_TREELEVEL);
155
156         //tree.a(subtreePath);
157         List<SearchHit> others = this.search(Entity.Inventoryequipment, (String) null, INVENTORY_PROPERTY_NODEID, nodeId,
158                 null, null, null, null, INVENTORY_PROPERTY_TREELEVEL);
159         if (matches.size() > 0) {
160             int treeLevelToStart = (list == null || list.size() <= 0) ? 0 : list.size() - 1;
161             //build tree
162             JSONObject hitData;
163             //fill root elems
164             for (SearchHit hit : matches) {
165                 hitData = hit.getSource();
166                 if (hitData.getLong(INVENTORY_PROPERTY_TREELEVEL) == treeLevelToStart) {
167                     tree.put(hit.getId(),
168                             new DataTreeChildObject(hitData.getString(INVENTORY_PROPERTY_FOR_LABEL), true)
169                                     .setProperty(INVENTORY_PROPERTY_UUID, hitData.getString(INVENTORY_PROPERTY_UUID))
170                                     .setProperty(INVENTORY_PROPERTY_PARENTUUID,
171                                             hitData.getString(INVENTORY_PROPERTY_PARENTUUID)));
172                 }
173             }
174             for (SearchHit hit : others) {
175                 hitData = hit.getSource();
176                 if (hitData.getLong(INVENTORY_PROPERTY_TREELEVEL) == treeLevelToStart) {
177                     tree.putIfNotExists(hit.getId(),
178                             new DataTreeChildObject(hitData.getString(INVENTORY_PROPERTY_FOR_LABEL), false)
179                                     .setProperty(INVENTORY_PROPERTY_UUID, hitData.getString(INVENTORY_PROPERTY_UUID))
180                                     .setProperty(INVENTORY_PROPERTY_PARENTUUID,
181                                             hitData.getString(INVENTORY_PROPERTY_PARENTUUID)));
182                 }
183             }
184             //fill child elems
185             for (SearchHit hit : matches) {
186                 hitData = hit.getSource();
187                 if (hitData.getLong(INVENTORY_PROPERTY_TREELEVEL) > treeLevelToStart) {
188                     tree.put(hitData.getLong(INVENTORY_PROPERTY_TREELEVEL) - treeLevelToStart - 1, hit.getId(),
189                             new DataTreeChildObject(hitData.getString(INVENTORY_PROPERTY_FOR_LABEL), true)
190                                     .setProperty(INVENTORY_PROPERTY_UUID, hitData.getString(INVENTORY_PROPERTY_UUID))
191                                     .setProperty(INVENTORY_PROPERTY_PARENTUUID,
192                                             hitData.getString(INVENTORY_PROPERTY_PARENTUUID)));
193                 }
194             }
195             for (SearchHit hit : others) {
196                 hitData = hit.getSource();
197                 if (hitData.getLong(INVENTORY_PROPERTY_TREELEVEL) > treeLevelToStart) {
198                     tree.putIfNotExists(hitData.getLong(INVENTORY_PROPERTY_TREELEVEL) - treeLevelToStart - 1, hit.getId(),
199                             new DataTreeChildObject(hitData.getString(INVENTORY_PROPERTY_FOR_LABEL), false)
200                                     .setProperty(INVENTORY_PROPERTY_UUID, hitData.getString(INVENTORY_PROPERTY_UUID))
201                                     .setProperty(INVENTORY_PROPERTY_PARENTUUID,
202                                             hitData.getString(INVENTORY_PROPERTY_PARENTUUID)));
203                 }
204             }
205             tree.removeUnmatchedPaths();
206         }
207         return tree;
208     }
209
210     /**
211      * node will be root elements inventory information below from level-1
212      *
213      * @param filter
214      * @return
215      * @throws IOException
216      */
217     private DataTreeObject readInventoryTreeWithNode(String filter) throws IOException {
218         DataTreeObject tree = new DataTreeObject(INVENTORY_PROPERTY_PARENTUUID, INVENTORY_PROPERTY_UUID);
219
220         List<SearchHit> matches = this.search(Entity.Inventoryequipment, filter, INVENTORY_PROPERTY_TREELEVEL);
221         List<SearchHit> others = null;
222         if (matches.size() > 0) {
223             if (filter != null) {
224                 //find all parents up to tree-level 0
225                 String nodeId = "";
226                 List<String> alreadyInList = new ArrayList<>();
227                 BoolQueryBuilder query2 = QueryBuilders.boolQuery();
228                 for (SearchHit hit : matches) {
229                     nodeId = hit.getSource().getString(INVENTORY_PROPERTY_NODEID);
230                     if (alreadyInList.contains(nodeId)) {
231                         continue;
232                     }
233                     query2.should(QueryBuilders.matchQuery(INVENTORY_PROPERTY_NODEID, nodeId));
234                     alreadyInList.add(nodeId);
235                     tree.put(nodeId,
236                             new DataTreeChildObject(nodeId, false).setProperty(INVENTORY_PROPERTY_UUID, nodeId));
237
238                 }
239                 others = this.search(Entity.Inventoryequipment, query2, INVENTORY_PROPERTY_TREELEVEL);
240             } else {
241                 AggregationEntries nodes = this.searchAggregated(Entity.Inventoryequipment, INVENTORY_PROPERTY_NODEID);
242                 for (String node : nodes.keySet()) {
243                     tree.put(node, new DataTreeChildObject(node, false).setProperty(INVENTORY_PROPERTY_UUID, node));
244                 }
245             }
246
247             //build tree
248             JSONObject hitData;
249             //fill root elems
250             for (SearchHit hit : matches) {
251                 hitData = hit.getSource();
252                 if (hitData.getLong(INVENTORY_PROPERTY_TREELEVEL) == 0) {
253                     tree.put(0, hit.getId(),
254                             new DataTreeChildObject(hitData.getString(INVENTORY_PROPERTY_FOR_LABEL), true)
255                                     .setProperty(INVENTORY_PROPERTY_UUID, hitData.getString(INVENTORY_PROPERTY_UUID))
256                                     .setProperty(INVENTORY_PROPERTY_PARENTUUID,
257                                             hitData.getString(INVENTORY_PROPERTY_NODEID)));
258                 }
259             }
260             if (others != null) {
261                 for (SearchHit hit : others) {
262                     hitData = hit.getSource();
263                     if (hitData.getLong(INVENTORY_PROPERTY_TREELEVEL) == 0) {
264                         tree.putIfNotExists(0, hit.getId(),
265                                 new DataTreeChildObject(hitData.getString(INVENTORY_PROPERTY_FOR_LABEL), false)
266                                         .setProperty(INVENTORY_PROPERTY_UUID,
267                                                 hitData.getString(INVENTORY_PROPERTY_UUID))
268                                         .setProperty(INVENTORY_PROPERTY_PARENTUUID,
269                                                 hitData.getString(INVENTORY_PROPERTY_NODEID)));
270                     }
271                 }
272             }
273             //fill child elements
274             for (SearchHit hit : matches) {
275                 hitData = hit.getSource();
276                 long treeLevel = hitData.getLong(INVENTORY_PROPERTY_TREELEVEL);
277                 if (treeLevel > 0) {
278                     tree.put(treeLevel, hit.getId(),
279                             new DataTreeChildObject(hitData.getString(INVENTORY_PROPERTY_FOR_LABEL_CHILD), true)
280                                     .setProperty(INVENTORY_PROPERTY_UUID, hitData.getString(INVENTORY_PROPERTY_UUID))
281                                     .setProperty(INVENTORY_PROPERTY_PARENTUUID,
282                                             hitData.getString(INVENTORY_PROPERTY_PARENTUUID)));
283                 }
284             }
285             if (others != null) {
286                 for (SearchHit hit : others) {
287                     hitData = hit.getSource();
288                     long treeLevel = hitData.getLong(INVENTORY_PROPERTY_TREELEVEL);
289                     if (hitData.getLong(INVENTORY_PROPERTY_TREELEVEL) > 0) {
290                         tree.putIfNotExists(treeLevel, hit.getId(),
291                                 new DataTreeChildObject(hitData.getString(INVENTORY_PROPERTY_FOR_LABEL_CHILD), false)
292                                         .setProperty(INVENTORY_PROPERTY_UUID,
293                                                 hitData.getString(INVENTORY_PROPERTY_UUID))
294                                         .setProperty(INVENTORY_PROPERTY_PARENTUUID,
295                                                 hitData.getString(INVENTORY_PROPERTY_PARENTUUID)));
296                     }
297                 }
298             }
299             tree.removeUnmatchedPaths();
300
301         }
302         return tree;
303     }
304
305
306
307     /**
308      * @param client
309      */
310     public void setDatabaseClient(HtDatabaseClient client) {
311         this.dbClient = client;
312
313     }
314 }