Upversion artifacts to 1.8.0-SNAPSHOT
[aai/data-router.git] / src / main / java / org / onap / aai / datarouter / entity / SuggestionSearchEntity.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.datarouter.entity;
22
23 import java.io.IOException;
24 import java.io.Serializable;
25 import java.security.NoSuchAlgorithmException;
26 import java.util.ArrayList;
27 import java.util.HashMap;
28 import java.util.List;
29 import java.util.Map;
30
31 import org.json.JSONArray;
32 import org.json.JSONObject;
33 import org.onap.aai.datarouter.search.filters.config.UiFilterConfig;
34 import org.onap.aai.datarouter.search.filters.config.UiFiltersConfig;
35 import org.onap.aai.datarouter.search.filters.config.UiFiltersSchemaUtility;
36 import org.onap.aai.datarouter.util.NodeUtils;
37 import org.onap.aai.datarouter.util.SearchSuggestionPermutation;
38
39 import com.fasterxml.jackson.databind.JsonNode;
40
41 public class SuggestionSearchEntity implements DocumentStoreDataEntity {
42
43   private static final String FILTER_ID = "filterId";
44   private static final String FILTER_VALUE = "filterValue";
45   private static final String FILTER_LIST = "filterList";
46
47   protected String id; // generated SHA-256 digest
48   private String entityType;
49   private List<String> entityTypeAliases;
50   private List<String> suggestionInputPermutations = new ArrayList<>();
51   private List<String> statusPermutations = new ArrayList<>();
52   private List<String> suggestableAttr = new ArrayList<>();
53   
54   private Map<String, String> inputOutputData = new HashMap<>();
55   private Map<String, UiFilterConfig> filters = new HashMap<>();
56   private JSONObject filterPayload = new JSONObject();
57   private StringBuilder searchSuggestionDisplayString = new StringBuilder();
58   private JSONArray payloadFilters = new JSONArray();
59   private UiFiltersSchemaUtility filtersSchemaUtility = new UiFiltersSchemaUtility();
60
61   public SuggestionSearchEntity() {
62     UiFiltersConfig filterConfigList = filtersSchemaUtility.loadUiFiltersConfig();
63
64     // Populate the map with keys that will match the suggestableAttr values
65     for (UiFilterConfig filter : filterConfigList.getFilters()) {
66       if (filter.getDataSource() != null) {
67         filters.put(filter.getDataSource().getFieldName(), filter);
68       }
69     }
70   }
71
72   /**
73    * Create the search suggestion string to display to the user in the search suggestion drop-down
74    * 
75    * @throws NoSuchAlgorithmException
76    */
77   public void generateSearchSuggestionDisplayStringAndId() throws NoSuchAlgorithmException {
78     int payloadEntryCounter = 1;
79
80     for (Map.Entry<String, String> outputValue : inputOutputData.entrySet()) {
81       if (outputValue.getValue() != null && outputValue.getValue().length() > 0) {
82         this.searchSuggestionDisplayString.append(outputValue.getValue());
83
84         if (payloadEntryCounter < inputOutputData.entrySet().size()) {
85           this.searchSuggestionDisplayString.append(" and ");
86         } else {
87           this.searchSuggestionDisplayString.append(" ");
88         }
89       }
90
91       payloadEntryCounter++;
92     }
93
94     this.searchSuggestionDisplayString.append(getEntityTypeAliases().get(0));
95     generateSearchSuggestionId(searchSuggestionDisplayString.toString());
96   }
97   
98   /**
99    * Generates an ID by encrypting the string to display to the user in the search suggestion
100    * drop-down
101    * 
102    * @param outputString The string to create the encrypted ID from
103    */
104   private void generateSearchSuggestionId(String searchSuggestionDisplayString) {
105     this.id = NodeUtils.generateUniqueShaDigest(searchSuggestionDisplayString);
106   }
107
108   /**
109    * Launch pad for performing permutations of the entity type, aliases, prov status and orchestration status.
110    * SHA-256 will result in an ID with a guaranteed uniqueness compared to just a java hashcode value
111    * 
112    * @return
113    */
114   public List<String> generateSuggestionInputPermutations() {
115     List<String> entityNames = new ArrayList<>();
116     entityNames.add(entityType);
117
118     if ((entityTypeAliases != null) && !(entityTypeAliases.isEmpty())) {
119       for (String alias : entityTypeAliases) {
120         entityNames.add(alias);
121       }
122     }
123
124     ArrayList<String> listOfSearchSuggestionPermutations = new ArrayList<>();
125     ArrayList<String> listToPermutate = 
126         new ArrayList<>(this.getInputOutputData().values());
127
128     for (String entityName : entityNames) {
129       listToPermutate.add(entityName);
130       List<List<String>> lists = SearchSuggestionPermutation.getListPermutations(listToPermutate);
131       for (List<String> li : lists){
132         listOfSearchSuggestionPermutations.add(String.join(" ", li));
133       }
134       listToPermutate.remove(entityName);
135     }
136
137     return listOfSearchSuggestionPermutations;
138   }
139
140   /**
141    * Return a custom JSON representation of this class
142    */
143   @Override
144   public String getAsJson() throws IOException {
145     if (entityType == null || suggestionInputPermutations == null) {
146       return null;
147     }
148
149     JSONObject rootNode = new JSONObject();
150     JSONArray inputArray = new JSONArray();
151     JSONObject payloadNode = new JSONObject();
152     StringBuilder outputString = new StringBuilder();
153
154     int payloadEntryCounter = 1;
155
156     // Add prov and orchestration status to search suggestion string
157     for (Map.Entry<String, String> payload : inputOutputData.entrySet()) {
158       payloadNode.put(payload.getKey(), payload.getValue());
159       outputString.append(payload.getValue());
160
161       if (payloadEntryCounter < inputOutputData.entrySet().size()) {
162         // Add the word "and" between prov and orchestration statuses, if both are present
163         outputString.append(" and ");
164         payloadEntryCounter++;
165       }
166     }
167
168     /* Add entity type to search suggestion string. We've decided to use the first entity type alias
169      * from the OXM */
170     outputString.append(" ").append(getEntityTypeAliases().get(0));
171
172     for (String permutation : suggestionInputPermutations) {
173       inputArray.put(permutation);
174     }
175
176     // Build up the search suggestion as JSON
177     JSONObject entitySuggest = new JSONObject();
178     entitySuggest.put("input", inputArray);
179     entitySuggest.put("output", outputString);
180     entitySuggest.put("payload", this.filterPayload);
181     rootNode.put("entity_suggest", entitySuggest);
182
183     return rootNode.toString();
184   }
185
186   public boolean isSuggestableDoc() {
187     return this.getFilterPayload().length() != 0;
188   }
189
190   /**
191    * Generate all permutations of Entity Type and (Prov Status and/or Orchestration Status)
192    * 
193    * @param list The list of unique elements to create permutations of
194    * @param permutation A list to hold the current permutation used during
195    * @param size To keep track of the original size of the number of unique elements
196    * @param listOfSearchSuggestionPermutationList The list to hold all of the different permutations
197    */
198   private void permutateList(List<String> list, List<String> permutation, int size,
199       List<String> listOfSearchSuggestionPermutationList) {
200     if (permutation.size() == size) {
201       StringBuilder newPermutation = new StringBuilder();
202
203       for (int i = 0; i < permutation.size(); i++) {
204         newPermutation.append(permutation.get(i)).append(" ");
205       }
206
207       listOfSearchSuggestionPermutationList.add(newPermutation.toString().trim());
208
209       return;
210     }
211
212     String[] availableItems = list.toArray(new String[0]);
213
214     for (String i : availableItems) {
215       permutation.add(i);
216       list.remove(i);
217       permutateList(list, permutation, size, listOfSearchSuggestionPermutationList);
218       list.add(i);
219       permutation.remove(i);
220     }
221   }
222
223   /**
224    * Populate a string that will represent the UI filters portion of the JSON payload that's stored in the
225    * search engine
226    * 
227    * @param entityFromUebEvent
228    * @param suggestibleAttrInPayload
229    */
230   public void setFilterBasedPayloadFromResponse(JsonNode entityFromUebEvent,
231       List<String> suggestibleAttrInOxm, List<String> suggestibleAttrInPayload) {
232     if (suggestibleAttrInOxm != null) {
233       for (String attribute : suggestibleAttrInOxm) {
234         UiFilterConfig filterConfig = filters.get(attribute);
235
236         if (suggestibleAttrInPayload.contains(attribute)) {
237           inputOutputData.put(attribute, entityFromUebEvent.get(attribute).asText());
238
239           if(filterConfig != null) {
240             JSONObject jsonFilterPayload = new JSONObject();
241             jsonFilterPayload.put(FILTER_ID, filterConfig.getFilterId());
242             jsonFilterPayload.put(FILTER_VALUE, entityFromUebEvent.get(attribute).asText());
243             this.payloadFilters.put(jsonFilterPayload);
244           } else {
245             this.filterPayload.put(attribute, entityFromUebEvent.get(attribute).asText()); 
246           }
247         } else {
248           if(filterConfig != null) {
249             JSONObject emptyValueFilterPayload = new JSONObject();
250             emptyValueFilterPayload.put(FILTER_ID, filterConfig.getFilterId());
251             this.payloadFilters.put(emptyValueFilterPayload);
252           }
253         }
254       }
255
256       this.filterPayload.put(FILTER_LIST, this.payloadFilters);
257     }
258   }
259
260   public void setPayloadFromResponse(JsonNode node) {
261     if (suggestableAttr != null) {
262       for (String attribute : suggestableAttr) {
263         if (node.get(attribute) != null) {
264           inputOutputData.put(attribute, node.get(attribute).asText());
265           this.filterPayload.put(attribute, node.get(attribute).asText());
266         }
267       }
268     }
269   }
270
271   public String getEntityType() {
272     return entityType;
273   }
274
275   public void setEntityType(String entityType) {
276     this.entityType = entityType;
277   }
278
279   public List<String> getEntityTypeAliases() {
280     return entityTypeAliases;
281   }
282
283   public void setEntityTypeAliases(List<String> entityTypeAliases) {
284     this.entityTypeAliases = entityTypeAliases;
285   }
286
287   @Override
288   public String getId() {
289     return id;
290   }
291
292   public StringBuilder getSearchSuggestionDisplayString() {
293     return searchSuggestionDisplayString;
294   }
295
296   public JSONObject getFilterPayload() {
297     return filterPayload;
298   }
299
300   public List<String> getStatusPermutations() {
301     return statusPermutations;
302   }
303
304   public List<String> getSuggestableAttr() {
305     return suggestableAttr;
306   }
307
308   public List<String> getSuggestionInputPermutations() {
309     return this.suggestionInputPermutations;
310   }
311
312   public void setId(String id) {
313     this.id = id;
314   }
315   
316   public void setInputOutputData(Map<String, String> inputOutputData) {
317     this.inputOutputData = inputOutputData;
318   }
319
320   public Map<String, String> getInputOutputData() {
321     return inputOutputData;
322   }
323
324   public void setSearchSuggestionDisplayString(StringBuilder searchSuggestionDisplayString) {
325     this.searchSuggestionDisplayString = searchSuggestionDisplayString;
326   }
327
328   public void setFilterPayload(JSONObject filterPayload) {
329     this.filterPayload = filterPayload;
330   }
331   
332   public void setFiltersSchemaUtility(UiFiltersSchemaUtility filtersSchemaUtility) {
333     this.filtersSchemaUtility = filtersSchemaUtility;
334   }
335
336   public void setStatusPermutations(List<String> statusPermutations) {
337     this.statusPermutations = statusPermutations;
338   }
339
340   public void setSuggestableAttr(List<String> attributes) {
341     for (String attribute : attributes) {
342       this.suggestableAttr.add(attribute);
343     }
344   }
345
346   public void setSuggestionInputPermutations(List<String> permutations) {
347     this.suggestionInputPermutations = permutations;
348   }
349
350   @Override
351   public String toString() {
352     return "SuggestionSearchEntity [id=" + id + ", entityType=" + entityType
353         + ", entityTypeAliases=" + entityTypeAliases + ", suggestionInputPermutations="
354         + suggestionInputPermutations + ", statusPermutations=" + statusPermutations
355         + ", suggestableAttr=" + suggestableAttr + ", inputOutputData=" + inputOutputData
356         + ", filters=" + filters + ", filterPayload=" + filterPayload
357         + ", searchSuggestionDisplayString=" + searchSuggestionDisplayString + ", payloadFilters="
358         + payloadFilters + "]";
359   }
360 }