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