ES to SDS conversion
[aai/sparky-be.git] / sparkybe-onap-service / src / main / java / org / onap / aai / sparky / search / filters / searchservice / FilterQueryAndResponseBuilder.java
1 /**
2  * ============LICENSE_START=======================================================
3  * org.onap.aai
4  * ================================================================================
5  * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
6  * Copyright © 2017-2018 Amdocs
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 package org.onap.aai.sparky.search.filters.searchservice;
22
23 import java.util.ArrayList;
24 import java.util.HashMap;
25 import java.util.List;
26 import java.util.Map;
27
28 import org.onap.aai.cl.api.Logger;
29 import org.onap.aai.cl.eelf.LoggerFactory;
30 import org.onap.aai.sparky.logging.AaiUiMsgs;
31 import org.onap.aai.sparky.search.filters.config.FiltersConfig;
32
33 import com.google.gson.Gson;
34 import com.google.gson.GsonBuilder;
35 import com.google.gson.JsonArray;
36 import com.google.gson.JsonElement;
37 import com.google.gson.JsonObject;
38
39 public class FilterQueryAndResponseBuilder {
40
41   public class FileBasedFiltersConstants {
42     public static final String FILTERS = "filters";
43     public static final String FILTER = "filter";
44     public static final String QUERIES = "queries";
45     public static final String AGGREGATIONS = "aggregations";
46
47     public static final String FILTER_ID = "filterId";
48     public static final String DATA_SOURCE = "dataSource";
49     public static final String FILTER_VALUE = "filterValue";
50     public static final String FIELD_NAME = "fieldName";
51
52     public static final String ALL = "all";
53     public static final String MATCH = "match";
54     public static final String FIELD = "field";
55     public static final String VALUE = "value";
56
57     public static final String NAME = "name";
58     public static final String AGGREGATION = "aggregation";
59     public static final String GROUP_BY = "group-by";
60
61     public static final String VIEWS = "views";
62     public static final String VIEW_NAME = "viewName";
63
64     public static final String AGGREGATION_RESULT = "aggregationResult";
65     public static final String BUCKETS = "buckets";
66     public static final String KEY = "key";
67
68     public static final String LABEL = "label";
69     public static final String DISPLAY_NAME = "displayName";
70     public static final String CONTROLS = "controls";
71     public static final String TYPE = "type";
72     public static final String DATA_TYPE = "dataType";
73     public static final String MULTISELECT = "multiSelect";
74     public static final String WATERMARK = "watermark";
75     public static final String OPTIONS_TYPE = "optionsType";
76     public static final String OPTIONS_VALUES = "optionsValues";
77     public static final String DEFAULT_VALUE = "defaultValue";
78     public static final String DECODE = "decode";
79     public static final String CODE = "code";
80     public static final String FILTER_NAME = "filterName";
81
82     public static final String TOTAL = "total";
83     public static final String DOC_COUNT = "doc_count";
84     public static final String COUNT = "count";
85     public static final String SEARCH_RESULT = "searchResult";
86     public static final String TOTAL_HITS = "totalHits";
87
88     public static final String FILTER_VALUE_QUERY = "filterQuery";
89     public static final String INDEX_NAME = "indexName";
90     public static final String INDEX = "index";
91
92     public static final int FILTER_VALUE_AGG_SIZE_LIMIT = 1;
93     public static final int FILTER_VALUE_AGG_FIRST_ELEMENT = 0;
94   }
95   
96   private static final Logger LOG = LoggerFactory.getInstance().getLogger(FilterQueryAndResponseBuilder.class);
97
98   private FileBasedFilters fileBasedFilters;
99   private Gson converter;
100   private Gson responseFormatter;
101
102   public FilterQueryAndResponseBuilder(FiltersConfig filtersConfig) {
103     this.fileBasedFilters = new FileBasedFilters(filtersConfig);
104     this.converter = new Gson();
105     this.responseFormatter = new GsonBuilder().disableHtmlEscaping().create();
106   }
107   
108   public void setFiltersConfig(FiltersConfig filtersConfig) {
109     this.fileBasedFilters.setFiltersConfig(filtersConfig);
110   }
111
112   public String createFileBasedFilterQuery(String request) {
113     String query = null;
114
115     JsonObject filtersOnFile = fileBasedFilters.getFilters();
116     JsonObject requestObj = converter.fromJson(request, JsonObject.class);
117
118     if (filtersOnFile != null && requestObj != null) {
119       JsonElement rawRequestFilters = requestObj.get(FileBasedFiltersConstants.FILTERS);
120       JsonArray requestFilters = null;
121
122       if (rawRequestFilters != null && rawRequestFilters.isJsonArray()) {
123         requestFilters = rawRequestFilters.getAsJsonArray();
124
125         Map<String, JsonObject> filtersOnFileMap = convertFiltersOnFileToMap(filtersOnFile);
126
127         JsonObject filterSubObject =
128             createFileBasedFilterQuerySubObject(requestFilters, filtersOnFileMap);
129         JsonArray queriesSubObject = createFileBasedQueriesQuerySubObject();
130         JsonArray aggregationsSubObject = createFileBasedAggregationQuerySubObject(requestFilters, filtersOnFileMap);
131
132         JsonObject finalQuery = new JsonObject();
133         finalQuery.add(FileBasedFiltersConstants.FILTER, filterSubObject);
134         finalQuery.add(FileBasedFiltersConstants.QUERIES, queriesSubObject);
135         finalQuery.add(FileBasedFiltersConstants.AGGREGATIONS, aggregationsSubObject);
136
137         query = responseFormatter.toJson(finalQuery);
138       }
139     }
140
141     return query;
142   }
143
144   public JsonArray createFileBasedFilterValueQueries(String request) {
145     JsonArray returnArray = new JsonArray();
146
147     JsonObject requestObj = converter.fromJson(request, JsonObject.class);
148
149     if (requestObj != null && requestObj.has(FileBasedFiltersConstants.VIEW_NAME)) {
150       JsonObject viewsOnFile = fileBasedFilters.getViews();
151       Map<String, JsonObject> viewsMap = convertViewsOnFileToMap(viewsOnFile);
152
153       String viewName = requestObj.get(FileBasedFiltersConstants.VIEW_NAME).getAsString();
154       JsonObject viewObj = viewsMap.get(viewName);
155
156       if (viewObj != null) {
157         JsonObject filtersOnFile = fileBasedFilters.getFilters();
158         Map<String, JsonObject> filtersOnFileMap = convertFiltersOnFileToMap(filtersOnFile);
159
160         JsonArray filtersForView = viewObj.get(FileBasedFiltersConstants.FILTERS).getAsJsonArray();
161
162         for (JsonElement filterForView : filtersForView) {
163           JsonObject idAndQuery = new JsonObject();
164
165           JsonObject filterIdObj = filterForView.getAsJsonObject();
166           String filterId = filterIdObj.get(FileBasedFiltersConstants.FILTER_ID).getAsString();
167           JsonObject filterOnFile = filtersOnFileMap.get(filterId);
168           
169           if(filterOnFile != null) {
170             idAndQuery.addProperty(FileBasedFiltersConstants.FILTER_ID, filterId);
171             
172             if (filterOnFile.has(FileBasedFiltersConstants.DATA_SOURCE)) {
173               JsonObject dataSource = filterOnFile.get(FileBasedFiltersConstants.DATA_SOURCE).getAsJsonObject();
174               String searchIndex = dataSource.get(FileBasedFiltersConstants.INDEX_NAME).getAsString();
175               idAndQuery.addProperty(FileBasedFiltersConstants.INDEX, searchIndex);
176             
177               JsonObject filterQuery = new JsonObject();
178               filterQuery.add(FileBasedFiltersConstants.FILTER, new JsonObject());
179               filterQuery.add(FileBasedFiltersConstants.QUERIES, new JsonArray());
180               JsonObject filterAgg = createFileBasedAggregationQuerySubObject(filterForView, filtersOnFileMap);
181               JsonArray aggArray = new JsonArray();
182               aggArray.add(filterAgg);
183               filterQuery.add(FileBasedFiltersConstants.AGGREGATIONS, aggArray);
184               idAndQuery.add(FileBasedFiltersConstants.FILTER_VALUE_QUERY, filterQuery);
185             }
186
187             returnArray.add(idAndQuery);
188           } else {
189             LOG.error(AaiUiMsgs.ERROR_GENERIC, "Filter with ID " + filterId + " did not exist on the file system. Check filter configuration.");
190           }
191         }
192       }
193     }
194
195     return returnArray;
196   }
197
198   public JsonObject formatSingleFilterValueQueryResult(String result, String filterId, JsonObject existingFilters) {
199
200     List<String> filterValues = null;
201
202     if (result != null) {
203       JsonObject resultObj = converter.fromJson(result, JsonObject.class);
204       JsonObject aggsResult = resultObj.get(FileBasedFiltersConstants.AGGREGATION_RESULT).getAsJsonObject();
205       JsonArray aggs = aggsResult.get(FileBasedFiltersConstants.AGGREGATIONS).getAsJsonArray();
206
207       // If there are more than one aggregation array then previous steps are incorrect
208       if (aggs.size() == FileBasedFiltersConstants.FILTER_VALUE_AGG_SIZE_LIMIT) {
209         JsonObject aggObj = aggs.get(FileBasedFiltersConstants.FILTER_VALUE_AGG_FIRST_ELEMENT).getAsJsonObject();
210         JsonArray buckets = aggObj.get(FileBasedFiltersConstants.BUCKETS).getAsJsonArray();
211         filterValues = new ArrayList<String>();
212         for (JsonElement singleResult : buckets) {
213           JsonObject singleResultObj = singleResult.getAsJsonObject();
214           filterValues.add(singleResultObj.get(FileBasedFiltersConstants.KEY).getAsString());
215         }
216       }
217     }
218
219     JsonObject filtersOnFile = fileBasedFilters.getFilters();
220     Map<String, JsonObject> filtersOnFileMap = convertFiltersOnFileToMap(filtersOnFile);
221     JsonObject filterOnFile = filtersOnFileMap.get(filterId);
222     
223     if(filterOnFile != null) {
224       JsonObject populatedFilter = createPopulatedFilterObjectForResponse(filterOnFile, filterValues);
225       existingFilters.add(filterId, populatedFilter);
226     }
227     
228     return existingFilters;
229   }
230
231   public String formatAggregationsResponse(String result) {
232     String response = null;
233
234     JsonObject resultObj = converter.fromJson(result, JsonObject.class);
235     JsonObject searchResults =
236         resultObj.get(FileBasedFiltersConstants.SEARCH_RESULT).getAsJsonObject();
237     String total = searchResults.get(FileBasedFiltersConstants.TOTAL_HITS).getAsString();
238
239     JsonObject aggResult =
240         resultObj.get(FileBasedFiltersConstants.AGGREGATION_RESULT).getAsJsonObject();
241     JsonArray aggs = aggResult.get(FileBasedFiltersConstants.AGGREGATIONS).getAsJsonArray();
242
243     JsonObject responseAggs = new JsonObject();
244     for (JsonElement aggregation : aggs) {
245       JsonObject aggObj = aggregation.getAsJsonObject();
246
247       String aggName = aggObj.get(FileBasedFiltersConstants.NAME).getAsString();
248       JsonArray buckets = aggObj.get(FileBasedFiltersConstants.BUCKETS).getAsJsonArray();
249
250       JsonArray aggResponseSubArray = new JsonArray();
251       for (JsonElement singleResult : buckets) {
252         JsonObject singleResultObj = singleResult.getAsJsonObject();
253
254         JsonObject responseObj = new JsonObject();
255         responseObj.addProperty(FileBasedFiltersConstants.DOC_COUNT, singleResultObj.get(FileBasedFiltersConstants.COUNT).getAsInt());
256         responseObj.addProperty(FileBasedFiltersConstants.KEY, singleResultObj.get(FileBasedFiltersConstants.KEY).getAsString());
257
258         aggResponseSubArray.add(responseObj);
259       }
260
261       responseAggs.add(aggName, aggResponseSubArray);
262     }
263
264     JsonObject finalResponse = new JsonObject();
265     finalResponse.addProperty(FileBasedFiltersConstants.TOTAL, total);
266     finalResponse.add(FileBasedFiltersConstants.AGGREGATIONS, responseAggs);
267
268     response = responseFormatter.toJson(finalResponse);
269
270     return response;
271   }
272
273   private JsonObject createFileBasedFilterQuerySubObject(JsonArray requestFilters,
274       Map<String, JsonObject> filtersOnFile) {
275     JsonObject filter = new JsonObject();
276     JsonArray all = new JsonArray();
277
278     for (JsonElement requestElement : requestFilters) {
279       JsonObject requestObj = requestElement.getAsJsonObject();
280       // Only add filters to array if a filter value is present
281       if (requestObj != null && requestObj.has(FileBasedFiltersConstants.FILTER_VALUE)) {
282
283         String filterId = requestObj.get(FileBasedFiltersConstants.FILTER_ID).getAsString();
284         JsonObject filterObj = filtersOnFile.get(filterId);
285
286         JsonObject dataSource =
287             filterObj.get(FileBasedFiltersConstants.DATA_SOURCE).getAsJsonObject();
288         String field = dataSource.get(FileBasedFiltersConstants.FIELD_NAME).getAsString();
289         String value = requestObj.get(FileBasedFiltersConstants.FILTER_VALUE).getAsString();
290
291         JsonObject matchObj = new JsonObject();
292         matchObj.addProperty(FileBasedFiltersConstants.FIELD, field);
293         matchObj.addProperty(FileBasedFiltersConstants.VALUE, value);
294
295         JsonObject allEntry = new JsonObject();
296         allEntry.add(FileBasedFiltersConstants.MATCH, matchObj);
297
298         all.add(allEntry);
299       }
300     }
301
302     if (all.size() > 0) {
303       filter.add(FileBasedFiltersConstants.ALL, all);
304     }
305
306     return filter;
307   }
308
309   private JsonArray createFileBasedQueriesQuerySubObject() {
310     return new JsonArray();
311   }
312
313   private JsonArray createFileBasedAggregationQuerySubObject(JsonArray requestFilters,
314       Map<String, JsonObject> filtersOnFile) {
315     JsonArray aggregations = new JsonArray();
316
317     for (JsonElement requestElement : requestFilters) {
318       JsonObject requestObj = requestElement.getAsJsonObject();
319       String filterId = requestObj.get(FileBasedFiltersConstants.FILTER_ID).getAsString();
320       JsonObject filterObj = filtersOnFile.get(filterId);
321
322       if (filterObj != null && filterObj.has(FileBasedFiltersConstants.DATA_SOURCE)) {
323         JsonObject dataSource =
324             filterObj.get(FileBasedFiltersConstants.DATA_SOURCE).getAsJsonObject();
325         String field = dataSource.get(FileBasedFiltersConstants.FIELD_NAME).getAsString();
326
327         JsonObject groupBy = new JsonObject();
328         groupBy.addProperty(FileBasedFiltersConstants.FIELD, field);
329
330         JsonObject aggregation = new JsonObject();
331         aggregation.add(FileBasedFiltersConstants.GROUP_BY, groupBy);
332
333         JsonObject aggregationsEntry = new JsonObject();
334         aggregationsEntry.addProperty(FileBasedFiltersConstants.NAME, field);
335         aggregationsEntry.add(FileBasedFiltersConstants.AGGREGATION, aggregation);
336
337         aggregations.add(aggregationsEntry);
338       }
339     }
340
341     return aggregations;
342   }
343
344   private JsonObject createFileBasedAggregationQuerySubObject(JsonElement requestElement, Map<String, JsonObject> filtersOnFile) {
345     JsonObject requestObj = requestElement.getAsJsonObject();
346     String filterId = requestObj.get(FileBasedFiltersConstants.FILTER_ID).getAsString();
347     JsonObject filterObj = filtersOnFile.get(filterId);
348
349     JsonObject aggregationsEntry = new JsonObject();
350     // If there is no data source for a filter, then there is no query to generate ("should" contain predetermined values)
351     if (filterObj != null && filterObj.has(FileBasedFiltersConstants.DATA_SOURCE)) {
352       JsonObject dataSource = filterObj.get(FileBasedFiltersConstants.DATA_SOURCE).getAsJsonObject();
353       String field = dataSource.get(FileBasedFiltersConstants.FIELD_NAME).getAsString();
354
355       JsonObject groupBy = new JsonObject();
356       groupBy.addProperty(FileBasedFiltersConstants.FIELD, field);
357
358       JsonObject aggregation = new JsonObject();
359       aggregation.add(FileBasedFiltersConstants.GROUP_BY, groupBy);
360
361       aggregationsEntry.addProperty(FileBasedFiltersConstants.NAME, field);
362       aggregationsEntry.add(FileBasedFiltersConstants.AGGREGATION, aggregation);
363     }
364
365     return aggregationsEntry;
366   }
367
368   private Map<String, JsonObject> convertFiltersOnFileToMap(JsonObject filtersOnFile) {
369     Map<String, JsonObject> ninjaTurtle = new HashMap<String, JsonObject>();
370
371     if (filtersOnFile != null) {
372       JsonElement filtersElement = filtersOnFile.get(FileBasedFiltersConstants.FILTERS);
373       if (filtersElement != null && filtersElement.isJsonArray()) {
374         JsonArray filtersOnFileArray = filtersElement.getAsJsonArray();
375         for (JsonElement filterElement : filtersOnFileArray) {
376           if (filterElement.isJsonObject()) {
377             JsonObject filterObj = filterElement.getAsJsonObject();
378             String filterId = filterObj.get(FileBasedFiltersConstants.FILTER_ID).getAsString();
379             ninjaTurtle.put(filterId, filterObj);
380           }
381         }
382       }
383     }
384
385     return ninjaTurtle;
386   }
387
388   private Map<String, JsonObject> convertViewsOnFileToMap(JsonObject viewsOnFile) {
389     Map<String, JsonObject> viewsMap = new HashMap<String, JsonObject>();
390
391     if (viewsOnFile != null) {
392       JsonElement viewsElement = viewsOnFile.get(FileBasedFiltersConstants.VIEWS);
393       if (viewsElement != null && viewsElement.isJsonArray()) {
394         JsonArray viewsArray = viewsElement.getAsJsonArray();
395         for (JsonElement view : viewsArray) {
396           JsonObject viewObj = view.getAsJsonObject();
397           String viewName = viewObj.get(FileBasedFiltersConstants.VIEW_NAME).getAsString();
398           viewsMap.put(viewName, viewObj);
399         }
400       }
401     }
402
403     return viewsMap;
404   }
405
406   private JsonObject createPopulatedFilterObjectForResponse(JsonObject filterOnFile, List<String> filterValues) {
407
408     JsonObject filterNameObj = new JsonObject();
409     filterNameObj.addProperty(FileBasedFiltersConstants.TYPE, filterOnFile.get(FileBasedFiltersConstants.DATA_TYPE).getAsString());
410     filterNameObj.addProperty(FileBasedFiltersConstants.MULTISELECT, filterOnFile.get(FileBasedFiltersConstants.MULTISELECT).getAsString());
411     filterNameObj.addProperty(FileBasedFiltersConstants.WATERMARK, filterOnFile.get(FileBasedFiltersConstants.WATERMARK).getAsString());
412
413     if (filterOnFile.has(FileBasedFiltersConstants.DEFAULT_VALUE)) {
414       filterNameObj.add(FileBasedFiltersConstants.DEFAULT_VALUE, filterOnFile.get(FileBasedFiltersConstants.DEFAULT_VALUE));
415     }
416
417     JsonArray options = new JsonArray();
418
419     if (filterValues != null && !filterValues.isEmpty()) {
420       for (String value : filterValues) {
421         JsonObject optionValue = new JsonObject();
422         optionValue.addProperty(FileBasedFiltersConstants.DECODE, value);
423         optionValue.addProperty(FileBasedFiltersConstants.CODE, value);
424         options.add(optionValue);
425       }
426     }
427
428     if (filterOnFile.has(FileBasedFiltersConstants.OPTIONS_VALUES)) {
429       JsonElement optionsValuesElement = filterOnFile.get(FileBasedFiltersConstants.OPTIONS_VALUES);
430       if (optionsValuesElement.isJsonArray()) {
431         options.addAll(optionsValuesElement.getAsJsonArray());
432       }
433     }
434
435     filterNameObj.add(filterOnFile.get(FileBasedFiltersConstants.OPTIONS_TYPE).getAsString(), options);
436
437     JsonObject controlsObj = new JsonObject();
438     controlsObj.add(filterOnFile.get(FileBasedFiltersConstants.FILTER_NAME).getAsString(), filterNameObj);
439
440     JsonObject populatedFilter = new JsonObject();
441     populatedFilter.addProperty(FileBasedFiltersConstants.LABEL, filterOnFile.get(FileBasedFiltersConstants.DISPLAY_NAME).getAsString());
442     populatedFilter.add(FileBasedFiltersConstants.CONTROLS, controlsObj);
443
444     return populatedFilter;
445   }
446 }