Update license and poms
[aai/sparky-be.git] / sparkybe-onap-service / src / main / java / org / onap / aai / sparky / search / filters / FilterQueryBuilder.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;
22
23 import java.util.ArrayList;
24 import java.util.List;
25
26 import javax.json.Json;
27 import javax.json.JsonArrayBuilder;
28 import javax.json.JsonObject;
29 import javax.json.JsonObjectBuilder;
30
31 import org.onap.aai.sparky.search.filters.config.FiltersConfig;
32 import org.onap.aai.sparky.search.filters.config.UiFilterConfig;
33 import org.onap.aai.sparky.search.filters.entity.AggregationEntity;
34 import org.onap.aai.sparky.search.filters.entity.BoolQueryBuilder;
35 import org.onap.aai.sparky.search.filters.entity.FilteredAggregationQueryBuilder;
36 import org.onap.aai.sparky.search.filters.entity.MatchFilterCriteriaEntity;
37 import org.onap.aai.sparky.search.filters.entity.SearchFilter;
38
39 /**
40  * Used to generate queries against Elasticsearch for filter related queries.
41  */
42 public class FilterQueryBuilder {
43   
44   private static final int EXISTING_FILTERS_LIMIT = 0;
45   private static final int SHOULD_BRANCH_LIMIT = 2;
46
47   public static JsonObject createFilteredBoolQueryObject(FiltersConfig filtersConfig, List<SearchFilter> searchFilters, int minShouldMatch, List<String> fields) {
48
49     if (searchFilters == null || searchFilters.size() == 0) {
50       return null;
51     }
52
53     int searchFilterValueSize = 0;
54
55     BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
56
57     for (SearchFilter searchFilter : searchFilters) {
58
59       searchFilterValueSize = searchFilter.getValues().size();
60
61       /*
62        * translate the filter-id into the filter-name from the oxm data model/config file
63        */
64       UiFilterConfig filter = filtersConfig.getFilterById(searchFilter.getFilterId());
65
66       if (filter == null || filter.getFilterName() == null) {
67         // log error and continue
68       } else {
69         
70         String fieldName = filter.getDataSource().getFieldName();
71         if(!fields.contains(fieldName)) {
72           fields.add(fieldName);
73         }
74         
75         if (searchFilterValueSize >= SHOULD_BRANCH_LIMIT) {
76           // Add should branches
77           for (String filterValue : searchFilter.getValues()) {
78             boolQueryBuilder.addShouldFilter(new MatchFilterCriteriaEntity(fieldName, filterValue)); 
79           }
80
81         } else if (searchFilterValueSize > EXISTING_FILTERS_LIMIT) {
82           // Add must branch
83           for (String filterValue : searchFilter.getValues()) {
84             boolQueryBuilder.addMustFilter(new MatchFilterCriteriaEntity(fieldName, filterValue));
85           }
86         }
87       }
88     }
89
90     boolQueryBuilder.setMinShouldMatch(minShouldMatch);
91     
92     return boolQueryBuilder.getJsonObject();
93   }
94
95   public static JsonObject createAggregationQueryArray(FiltersConfig filtersConfig, List<SearchFilter> searchFilters) {
96
97     if (searchFilters == null || searchFilters.size() == 0) {
98       // log error
99       return null;
100     }
101
102     FilteredAggregationQueryBuilder aggQueryBuilder = new FilteredAggregationQueryBuilder();
103
104     for (SearchFilter searchFilter : searchFilters) {
105
106       /*
107        * translate the filter-id into the filter-name from the oxm data model/config file
108        */
109       UiFilterConfig filter = filtersConfig.getFilterById(searchFilter.getFilterId());
110
111       if (filter == null || filter.getFilterName() == null) {
112         // log error and continue
113       } else {
114         String fieldName = filter.getDataSource().getFieldName();
115         aggQueryBuilder.addAggregationEntity(new AggregationEntity(fieldName, fieldName, 0));
116       }
117
118     }
119
120     return aggQueryBuilder.getJsonObject();
121   }
122
123   public static JsonObject createCombinedBoolAndAggQuery(FiltersConfig filtersConfig, List<SearchFilter> searchFilters, int minShouldMatch) {
124     JsonObjectBuilder wrappedQueryBuilder = Json.createObjectBuilder();
125     if(searchFilters != null) {
126       List<String> fields = new ArrayList<String>();
127       JsonObject boolQuery = createFilteredBoolQueryObject(filtersConfig,searchFilters, minShouldMatch, fields);
128       JsonObject aggQuery = createAggregationQueryArray(filtersConfig, searchFilters);
129
130       if (boolQuery != null) {
131         wrappedQueryBuilder.add("size", 0);
132         
133         JsonArrayBuilder filedsArrayBuilder = Json.createBuilderFactory(null).createArrayBuilder(); // TODO -> Should we use a class instance factory?
134         for(String field : fields) {
135           filedsArrayBuilder.add(field);
136         }
137         wrappedQueryBuilder.add("fields", filedsArrayBuilder.build());
138         
139         wrappedQueryBuilder.add("query", boolQuery);
140       }
141
142       if (aggQuery != null) {
143         wrappedQueryBuilder.add("aggs", aggQuery);
144       }
145     }
146     return wrappedQueryBuilder.build();
147   }
148
149   public static JsonObject createFilterValueQueryObject(String fieldValue) {
150     JsonObjectBuilder jsonBuilder = Json.createObjectBuilder();
151     jsonBuilder.add("size", "0"); // avoid source data
152     buildZeroTermSummaryQuery(jsonBuilder, fieldValue);
153
154     return jsonBuilder.build();
155   }
156
157   public static JsonObject createNestedFilterValueQueryObject(String fieldValue,
158       String pathToField) {
159     JsonObjectBuilder jsonBuilder = Json.createObjectBuilder();
160     jsonBuilder.add("size", "0"); // avoid source data
161     generateNestedAggregations(jsonBuilder, fieldValue, pathToField);
162
163     return jsonBuilder.build();
164   }
165
166   public static void buildZeroTermSummaryQuery(JsonObjectBuilder jsonBuilder, String fieldValue) {
167     JsonObjectBuilder aggsBlobBuilder = Json.createObjectBuilder();
168     getSummaryAggsBlob(aggsBlobBuilder, fieldValue, 0);
169     jsonBuilder.add("aggs", aggsBlobBuilder.build());
170   }
171
172   public static void getSummaryAggsBlob(JsonObjectBuilder aggsBlobBuilder, String fieldValue,
173       int resultSize) {
174     JsonObjectBuilder fieldBuilder =
175         Json.createObjectBuilder().add("field", fieldValue).add("size", resultSize);
176     JsonObject aggsFieldBlob = fieldBuilder.build();
177     JsonObjectBuilder defaultBlobBuilder = Json.createObjectBuilder().add("terms", aggsFieldBlob);
178     JsonObject defaultBlob = defaultBlobBuilder.build();
179     aggsBlobBuilder.add("default", defaultBlob);
180   }
181
182   public static void addNestedSummaryAggsBlob(JsonObjectBuilder nestedAggsBuilder,
183       String containerValue, String fieldValue, int resultSize) {
184     JsonObjectBuilder fieldBuilder = Json.createObjectBuilder()
185         .add("field", containerValue + "." + fieldValue).add("size", resultSize);
186     JsonObject aggsFieldObject = fieldBuilder.build();
187
188     JsonObjectBuilder termBuilder = Json.createObjectBuilder().add("terms", aggsFieldObject);
189     JsonObject termObject = termBuilder.build();
190
191     JsonObjectBuilder namedAggsBuilder = Json.createObjectBuilder().add(fieldValue, termObject);
192     JsonObject namedAggsObject = namedAggsBuilder.build();
193
194     nestedAggsBuilder.add("aggs", namedAggsObject);
195   }
196
197   public static void generateNestedAggregations(JsonObjectBuilder jsonBuilder, String fieldValue,
198       String pathToField) {
199     JsonObjectBuilder nestedAggsBuilder = Json.createObjectBuilder();
200
201     JsonObjectBuilder pathObjectBuilder = Json.createObjectBuilder().add("path", pathToField);
202     JsonObject nestedPathObject = pathObjectBuilder.build();
203
204     JsonObjectBuilder nestedObjectBuilder =
205         Json.createObjectBuilder().add("nested", nestedPathObject);
206
207     addNestedSummaryAggsBlob(nestedObjectBuilder, pathToField, fieldValue, 0);
208
209     JsonObject nestedObject = nestedObjectBuilder.build();
210     nestedAggsBuilder.add(pathToField, nestedObject);
211
212     jsonBuilder.add("aggs", nestedAggsBuilder.build());
213   }
214 }