2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
6 * Copyright © 2017 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
12 * http://www.apache.org/licenses/LICENSE-2.0
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=========================================================
21 * ECOMP is a trademark and service mark of AT&T Intellectual Property.
23 package org.onap.aai.sparky.viewandinspect.services;
25 import java.io.BufferedReader;
26 import java.io.IOException;
27 import java.io.PrintWriter;
28 import java.util.ArrayList;
29 import java.util.Arrays;
30 import java.util.Collection;
31 import java.util.HashMap;
32 import java.util.Iterator;
33 import java.util.List;
36 import javax.servlet.ServletException;
37 import javax.servlet.http.HttpServletRequest;
38 import javax.servlet.http.HttpServletResponse;
40 import org.json.JSONException;
41 import org.json.JSONObject;
42 import org.onap.aai.sparky.config.oxm.OxmEntityDescriptor;
43 import org.onap.aai.sparky.config.oxm.OxmModelLoader;
44 import org.onap.aai.sparky.dal.elasticsearch.HashQueryResponse;
45 import org.onap.aai.sparky.dal.elasticsearch.SearchAdapter;
46 import org.onap.aai.sparky.dal.rest.OperationResult;
47 import org.onap.aai.sparky.dal.sas.config.SearchServiceConfig;
48 import org.onap.aai.sparky.logging.AaiUiMsgs;
49 import org.onap.aai.sparky.search.VnfSearchService;
50 import org.onap.aai.sparky.search.config.SuggestionConfig;
51 import org.onap.aai.sparky.suggestivesearch.SuggestionEntity;
52 import org.onap.aai.sparky.util.NodeUtils;
53 import org.onap.aai.sparky.viewandinspect.entity.QuerySearchEntity;
54 import org.onap.aai.sparky.viewandinspect.entity.SearchResponse;
55 import org.onap.aai.cl.api.Logger;
56 import org.onap.aai.cl.eelf.LoggerFactory;
58 import com.fasterxml.jackson.databind.JsonNode;
59 import com.fasterxml.jackson.databind.ObjectMapper;
60 import com.fasterxml.jackson.databind.node.ArrayNode;
63 * The Class SearchServlet.
66 public class SearchServiceWrapper {
68 private static final long serialVersionUID = 1L;
70 private static final Logger LOG =
71 LoggerFactory.getInstance().getLogger(SearchServiceWrapper.class);
73 private SearchServiceConfig sasConfig = null;
74 private SuggestionConfig suggestionConfig = null;
75 private SearchAdapter search = null;
76 private ObjectMapper mapper;
77 private OxmModelLoader oxmModelLoader;
78 private VnfSearchService vnfSearch = null;
80 private static final String SEARCH_STRING = "search";
81 private static final String COUNT_STRING = "count";
82 private static final String QUERY_SEARCH = SEARCH_STRING + "/querysearch";
83 private static final String SUMMARY_BY_ENTITY_TYPE_API = SEARCH_STRING + "/summarybyentitytype";
84 private static final String SUMMARY_BY_ENTITY_TYPE_COUNT_API =
85 SUMMARY_BY_ENTITY_TYPE_API + "/" + COUNT_STRING;
87 private static final String VALUE_ANYKEY = "anyKey";
88 private static final String VALUE_QUERY = "query";
90 private static final String KEY_HASH_ID = "hashId";
91 private static final String KEY_GROUP_BY = "groupby";
92 private static final String KEY_SEARCH_RESULT = "searchResult";
93 private static final String KEY_HITS = "hits";
94 private static final String KEY_PAYLOAD = "payload";
95 private static final String KEY_DOCUMENT = "document";
96 private static final String KEY_CONTENT = "content";
97 private static final String KEY_SEARCH_TAG_IDS = "searchTagIDs";
98 private static final String KEY_SEARCH_TAGS = "searchTags";
99 private static final String KEY_LINK = "link";
100 private static final String KEY_ENTITY_TYPE = "entityType";
102 private static final String VI_SUGGESTION_ROUTE = "viewInspect"; // TODO -> Read route from
103 // suggestive-search.properties
104 // instead of hard coding
106 private static final String VIUI_SEARCH_TEMPLATE =
107 "{ " + "\"results-start\": 0," + "\"results-size\": %d," + "\"queries\": [{" + "\"must\": {"
108 + "\"match\": {" + "\"field\": \"entityType searchTags crossEntityReferenceValues\","
109 + "\"value\": \"%s\"," + "\"operator\": \"and\", "
110 + "\"analyzer\": \"whitespace_analyzer\"" + "}" + "}" + "}]" + "}";
113 * Instantiates a new search service wrapper
115 public SearchServiceWrapper() {
116 this.mapper = new ObjectMapper();
117 vnfSearch = new VnfSearchService();
120 if (sasConfig == null) {
121 sasConfig = SearchServiceConfig.getConfig();
124 if (suggestionConfig == null) {
125 suggestionConfig = SuggestionConfig.getConfig();
128 if (search == null) {
129 search = new SearchAdapter();
132 if (oxmModelLoader == null) {
133 oxmModelLoader = OxmModelLoader.getInstance();
135 if (OxmModelLoader.getInstance().getSearchableEntityDescriptors().isEmpty()) {
136 LOG.error(AaiUiMsgs.ENTITY_NOT_FOUND_IN_OXM, "searchable entity");
139 } catch (Exception exc) {
140 new ServletException(
141 "Caught an exception while getting an instance of servlet configuration from SearchServlet.",
146 public void doGet(HttpServletRequest request, HttpServletResponse response)
147 throws ServletException, IOException {
148 doPost(request, response);
151 public void setSasConfig(SearchServiceConfig sasConfig) {
152 this.sasConfig = sasConfig;
155 public SearchServiceConfig getSasConfig() {
159 public void setSuggestionConfig(SuggestionConfig suggestionConfig) {
160 this.suggestionConfig = suggestionConfig;
163 public void setSearch(SearchAdapter search) {
164 this.search = search;
167 public SuggestionConfig getSuggestionConfig() {
168 return suggestionConfig;
171 public SearchAdapter getSearch() {
175 public void setOxmModelLoader(OxmModelLoader oxmModelLoader) {
176 this.oxmModelLoader = oxmModelLoader;
179 public OxmModelLoader getOxmModelLoader() {
180 return oxmModelLoader;
183 public VnfSearchService getVnfSearch() {
187 public void setVnfSearch(VnfSearchService vnfSearch) {
188 this.vnfSearch = vnfSearch;
192 * Get Full URL for search
196 * @return the full url
198 private String getSasFullUrl(String indexName, String type, String ipAddress, String port,
201 return String.format("https://%s:%s/services/search-data-service/%s/search/indexes/%s/%s",
202 ipAddress, port, version, indexName, type);
206 * Handle search service do query.
209 * @param request the request
210 * @param response the response
211 * @throws Exception the exception
214 protected JSONObject getRequestParamsFromHeader(HttpServletRequest request) {
215 StringBuffer br = new StringBuffer();
218 BufferedReader reader = request.getReader();
219 while ((line = reader.readLine()) != null) {
222 } catch (Exception exc) {
223 LOG.error(AaiUiMsgs.ERROR_READING_HTTP_REQ_PARAMS);
226 String output = br.toString();
228 return new JSONObject(output);
231 protected void handleSummaryByEntityTypeCount(HttpServletRequest request,
232 HttpServletResponse response) throws Exception {
233 JSONObject parameters = getRequestParamsFromHeader(request);
234 String hashId = null;
235 if (parameters.has(KEY_HASH_ID)) {
236 hashId = parameters.get(KEY_HASH_ID).toString();
238 vnfSearch.setZeroCountResponse(response);
239 LOG.error(AaiUiMsgs.ERROR_HASH_NOT_FOUND);
242 HashQueryResponse hashQueryResponse = getResponseForQueryByHash(hashId, response);
243 Map<String, String> hashQueryResponsePayloadParams = new HashMap<String, String>();
244 if (hashQueryResponse.getJsonPayload() != null) {
245 hashQueryResponsePayloadParams = getPayloadParams(hashQueryResponse.getJsonPayload());
246 vnfSearch.getEntityCountResults(response, hashQueryResponsePayloadParams);
248 vnfSearch.setZeroCountResponse(response);
249 LOG.error(AaiUiMsgs.ERROR_INVALID_HASH, hashId);
253 protected Map<String, String> getPayloadParams(String parameters) {
254 Map<String, String> payloadParams = new HashMap<String, String>();
256 JSONObject json = new JSONObject(parameters);
257 JSONObject payload = json.getJSONObject(KEY_PAYLOAD);
258 if (payload.length() > 0) {
259 for (String key : JSONObject.getNames(payload)) {
260 payloadParams.put(key, payload.getString(key));
263 } catch (JSONException exc) {
264 LOG.error(AaiUiMsgs.ERROR_PARSING_PARAMS, exc);
266 return payloadParams;
269 protected HashQueryResponse getResponseForQueryByHash(String hashId,
270 HttpServletResponse response) {
271 return vnfSearch.getJSONPayloadFromHash(hashId);
274 protected void handleSummaryByEntityType(HttpServletRequest request, HttpServletResponse response)
276 JSONObject parameters = getRequestParamsFromHeader(request);
277 String hashId = null;
278 if (parameters.has(KEY_HASH_ID)) {
279 hashId = parameters.get(KEY_HASH_ID).toString();
281 vnfSearch.setZeroCountResponse(response);
282 LOG.error(AaiUiMsgs.ERROR_HASH_NOT_FOUND);
285 HashQueryResponse hashQueryResponse = getResponseForQueryByHash(hashId, response);
286 Map<String, String> hashQueryResponsePayloadParams = new HashMap<String, String>();
287 if (hashQueryResponse.getJsonPayload() != null) {
288 hashQueryResponsePayloadParams = getPayloadParams(hashQueryResponse.getJsonPayload());
289 if (parameters.has(KEY_GROUP_BY)) {
290 String groupByKey = parameters.getString(KEY_GROUP_BY);
291 vnfSearch.getSummaryByEntityType(response, hashQueryResponsePayloadParams, groupByKey);
294 LOG.error(AaiUiMsgs.ERROR_INVALID_HASH, hashId);
295 vnfSearch.setEmptyAggResponse(response);
300 * Gets the value from node.
302 * @param node the node
303 * @param fieldName the field name
304 * @return the value from node
306 private String getValueFromNode(JsonNode node, String fieldName) {
308 if (node == null || fieldName == null) {
312 JsonNode valueNode = node.get(fieldName);
314 if (valueNode != null) {
315 return valueNode.asText();
323 * Builds the search response.
325 * @param operationResult the operation result
326 * @param queryStr the query str
328 * @return the search response
330 private List<SuggestionEntity> generateSuggestionsForSearchResponse(String operationResult,
334 if (operationResult == null || operationResult.length() == 0) {
338 ObjectMapper mapper = new ObjectMapper();
339 JsonNode rootNode = null;
340 List<SuggestionEntity> suggestionEntityList = new ArrayList<SuggestionEntity>();
342 rootNode = mapper.readTree(operationResult);
344 JsonNode hitsNode = rootNode.get(KEY_SEARCH_RESULT);
347 // Check if there are hits that are coming back
348 if (hitsNode.has(KEY_HITS)) {
349 ArrayNode hitsArray = (ArrayNode) hitsNode.get(KEY_HITS);
352 * next we iterate over the values in the hit array elements
355 Iterator<JsonNode> nodeIterator = hitsArray.elements();
356 JsonNode entityNode = null;
357 SuggestionEntity suggestionEntity = null;
358 JsonNode sourceNode = null;
359 while (nodeIterator.hasNext()) {
360 entityNode = nodeIterator.next();
361 sourceNode = entityNode.get(KEY_DOCUMENT).get(KEY_CONTENT);
363 // do the point transformation as we build the response?
364 suggestionEntity = new SuggestionEntity();
365 suggestionEntity.setRoute(VI_SUGGESTION_ROUTE);
368 * This is where we probably want to annotate the search tags because we also have access
372 String searchTagIds = getValueFromNode(sourceNode, KEY_SEARCH_TAG_IDS);
373 String searchTags = getValueFromNode(sourceNode, KEY_SEARCH_TAGS);
374 String link = getValueFromNode(sourceNode, KEY_LINK);
375 String entityType = getValueFromNode(sourceNode, KEY_ENTITY_TYPE);
377 suggestionEntity.setHashId(NodeUtils.generateUniqueShaDigest(link));
382 .setText(annotateSearchTags(searchTags, searchTagIds, entityType, queryStr));
383 } catch (Exception exc) {
384 LOG.error(AaiUiMsgs.SEARCH_TAG_ANNOTATION_ERROR, searchTags.toString(),
385 exc.getLocalizedMessage());
386 // at least send back the un-annotated search tags
387 suggestionEntity.setText(searchTags);
390 if (searchTags != null) {
391 suggestionEntityList.add(suggestionEntity);
396 } catch (IOException exc) {
397 LOG.warn(AaiUiMsgs.SEARCH_RESPONSE_BUILDING_EXCEPTION, exc.getLocalizedMessage());
399 return suggestionEntityList;
406 * Query terms match search tag.
408 * @param queryTerms the query terms
409 * @param searchTag the search tag
410 * @return true, if successful @return.
412 private boolean queryTermsMatchSearchTag(String[] queryTerms, String searchTag) {
414 if (queryTerms == null || queryTerms.length == 0 || searchTag == null) {
418 for (String queryTerm : queryTerms) {
419 if (searchTag.toLowerCase().contains(queryTerm.toLowerCase())) {
429 * The current format of an UI-dropdown-item is like: "search-terms entityType att1=attr1_val".
430 * Example, for pserver: search-terms pserver hostname=djmAG-72060,
431 * pserver-name2=example-pserver-name2-val-17254, pserver-id=example-pserver-id-val-17254,
432 * ipv4-oam-address=example-ipv4-oam-address-val-17254 SearchController.js parses the above
433 * format. So if you are modifying the parsing below, please update SearchController.js as well.
435 * @param searchTags the search tags
436 * @param searchTagIds the search tag ids
437 * @param entityType the entity type
438 * @param queryStr the query str
442 private String annotateSearchTags(String searchTags, String searchTagIds, String entityType,
445 if (searchTags == null || searchTagIds == null) {
446 String valueOfSearchTags = String.valueOf(searchTags);
447 String valueOfSearchTagIds = String.valueOf(searchTagIds);
449 LOG.error(AaiUiMsgs.SEARCH_TAG_ANNOTATION_ERROR, "See error",
450 "Search tags = " + valueOfSearchTags + " and Seach tag IDs = " + valueOfSearchTagIds);
454 if (entityType == null) {
455 LOG.error(AaiUiMsgs.SEARCH_TAG_ANNOTATION_ERROR, searchTags.toString(), "EntityType is null");
459 if (queryStr == null) {
460 LOG.error(AaiUiMsgs.SEARCH_TAG_ANNOTATION_ERROR, searchTags.toString(),
461 "Query string is null");
466 * The ElasticSearch analyzer has already applied the lowercase filter, so we don't have to
469 String[] searchTagsArray = searchTags.split(";");
470 String[] searchTagIdsArray = searchTagIds.split(";");
472 // specifically apply lower case to the the query terms to make matching
474 String[] queryTerms = queryStr.toLowerCase().split(" ");
476 OxmEntityDescriptor desc = oxmModelLoader.getSearchableEntityDescriptors().get(entityType);
479 LOG.error(AaiUiMsgs.ENTITY_NOT_FOUND_IN_OXM, entityType.toString());
483 String primaryKeyName = NodeUtils.concatArray(desc.getPrimaryKeyAttributeName(), "/");
484 String primaryKeyValue = null;
487 * For each used attribute, get the fieldName for the attribute index and transform the search
488 * tag into t1,t2,t3 => h1=t1, h2=t2, h3=t3;
490 StringBuilder searchTagsBuilder = new StringBuilder(128);
491 searchTagsBuilder.append(entityType);
493 String primaryKeyConjunctionValue = null;
494 boolean queryTermsMatchedSearchTags = false;
496 if (searchTagsArray.length == searchTagIdsArray.length) {
497 for (int i = 0; i < searchTagsArray.length; i++) {
498 String searchTagAttributeId = searchTagIdsArray[i];
499 String searchTagAttributeValue = searchTagsArray[i];
501 // Find the concat conjunction
502 Map<String, String> pairConjunctionList = suggestionConfig.getPairingList();
504 String suggConjunction = null;
505 if (pairConjunctionList.get(searchTagAttributeId) != null) {
506 suggConjunction = pairConjunctionList.get(searchTagAttributeId);
508 suggConjunction = suggestionConfig.getDefaultPairingValue();
511 if (primaryKeyName.equals(searchTagAttributeId)) {
512 primaryKeyValue = searchTagAttributeValue;
513 primaryKeyConjunctionValue = suggConjunction;
516 if (queryTermsMatchSearchTag(queryTerms, searchTagAttributeValue)) {
517 searchTagsBuilder.append(" " + suggConjunction + " " + searchTagAttributeValue);
518 queryTermsMatchedSearchTags = true;
522 String errorMessage =
523 "Search tags length did not match search tag ID length for entity type " + entityType;
524 LOG.error(AaiUiMsgs.ENTITY_SYNC_SEARCH_TAG_ANNOTATION_FAILED, errorMessage);
528 * if none of the user query terms matched the index entity search tags then we should still tag
529 * the matched entity with a conjunction set to at least it's entity primary key value to
530 * discriminate between the entities of the same type in the search results displayed in the UI
534 if (!queryTermsMatchedSearchTags) {
536 if (primaryKeyValue != null && primaryKeyConjunctionValue != null) {
537 searchTagsBuilder.append(" " + primaryKeyConjunctionValue + " " + primaryKeyValue);
539 LOG.error(AaiUiMsgs.SEARCH_TAG_ANNOTATION_ERROR, "See error",
540 "Could not annotate user query terms " + queryStr
541 + " from available entity search tags = " + searchTags);
547 return searchTagsBuilder.toString();
553 * @param queryStr - space separate query search terms
554 * @return - query string with stop-words removed
556 private String stripStopWordsFromQuery(String queryStr) {
558 if (queryStr == null) {
562 Collection<String> stopWords = suggestionConfig.getStopWords();
563 ArrayList<String> queryTerms =
564 new ArrayList<String>(Arrays.asList(queryStr.toLowerCase().split(" ")));
566 queryTerms.removeAll(stopWords);
568 return String.join(" ", queryTerms);
574 * POST /search/viuiSearch/
576 * { "maxResults" : "10", "searchStr" : "<search bar text>" }
580 * Handle view and inspect search.
582 * @param request the request
583 * @param maxResults Max number of results to return
584 * @param response the response
586 * @throws IOException Signals that an I/O exception has occurred.
588 protected List<SuggestionEntity> performViewAndInspectQuerySearch(
589 QuerySearchEntity querySearchEntity, int maxResults) throws IOException {
590 List<SuggestionEntity> suggestionEntityList = new ArrayList<SuggestionEntity>();
593 * Based on the configured stop words, we need to strip any matched stop-words ( case
594 * insensitively ) from the query string, before hitting elastic to prevent the words from being
595 * used against the elastic view-and-inspect index. Another alternative to this approach would
596 * be to define stop words on the elastic search index configuration for the
597 * entity-search-index, but but that may be more complicated / more risky than just a simple bug
598 * fix, but it's something we should think about for the future.
602 final String queryStringWithoutStopWords =
603 stripStopWordsFromQuery(querySearchEntity.getQueryStr());
605 final String fullUrlStr = getSasFullUrl(sasConfig.getIndexName(), VALUE_QUERY,
606 sasConfig.getIpAddress(), sasConfig.getHttpPort(), sasConfig.getVersion());
609 String.format(VIUI_SEARCH_TEMPLATE, maxResults, queryStringWithoutStopWords);
611 OperationResult opResult = search.doPost(fullUrlStr, postBody, "application/json");
612 if (opResult.getResultCode() == 200) {
613 suggestionEntityList = generateSuggestionsForSearchResponse(opResult.getResult(),
614 querySearchEntity.getQueryStr());
616 } catch (Exception exc) {
617 LOG.error(AaiUiMsgs.SEARCH_SERVLET_ERROR,
618 "View and inspect query failed with error = " + exc.getMessage());
620 return suggestionEntityList;
623 protected List<SuggestionEntity> performVnfQuerySearch(QuerySearchEntity querySearchEntity,
624 int resultCountLimit) throws Exception {
625 return vnfSearch.getSuggestionsResults(querySearchEntity, resultCountLimit);
628 protected void handleQuerySearch(HttpServletRequest request, HttpServletResponse response)
630 String payload = NodeUtils.getBody(request);
631 if (payload == null || payload.isEmpty()) {
632 handleSearchServletErrors("Unable to parse payload", null, response);
634 QuerySearchEntity querySearchEntity = mapper.readValue(payload, QuerySearchEntity.class);
635 int maxResultsPerSearch = Integer.valueOf(querySearchEntity.getMaxResults());
637 SearchResponse searchResponse = new SearchResponse();
638 List<SuggestionEntity> viewAndInspectsuggestionEntityList =
639 new ArrayList<SuggestionEntity>();
640 List<SuggestionEntity> vnfSuggestionEntityList = new ArrayList<SuggestionEntity>();
641 long processTime = System.currentTimeMillis();
642 for (String searchService : suggestionConfig.getSearchIndexToSearchService().values()) {
643 if (searchService.equals(SearchServiceWrapper.class.getSimpleName())) {
644 viewAndInspectsuggestionEntityList =
645 performViewAndInspectQuerySearch(querySearchEntity, maxResultsPerSearch);
646 } else if (searchService.equals(VnfSearchService.class.getSimpleName())) {
647 vnfSuggestionEntityList = performVnfQuerySearch(querySearchEntity, maxResultsPerSearch);
652 for (int i = 0; i < maxResultsPerSearch; i++) {
653 if (i < viewAndInspectsuggestionEntityList.size() && totalAdded < maxResultsPerSearch) {
654 searchResponse.addSuggestion(viewAndInspectsuggestionEntityList.get(i));
657 if (i < vnfSuggestionEntityList.size() && totalAdded < maxResultsPerSearch) {
658 searchResponse.addSuggestion(vnfSuggestionEntityList.get(i));
661 if (totalAdded >= maxResultsPerSearch) {
665 searchResponse.addToTotalFound(totalAdded);
666 String searchResponseJson = NodeUtils.convertObjectToJson(searchResponse, true);
668 processTime = System.currentTimeMillis() - processTime;
669 searchResponse.setProcessingTimeInMs(processTime);
670 setServletResponse(response, searchResponseJson);
671 } catch (Exception exc) {
672 LOG.error(AaiUiMsgs.SEARCH_SERVLET_ERROR,
673 "Query search failed with error = " + exc.getMessage());
678 public void doPost(HttpServletRequest request, HttpServletResponse response)
679 throws ServletException, IOException {
684 // set default response
685 response.setStatus(200);
687 if (request.getRequestURI().contains(QUERY_SEARCH)) {
689 handleQuerySearch(request, response);
691 } else if (request.getRequestURI().contains(SUMMARY_BY_ENTITY_TYPE_COUNT_API)) {
692 api = SUMMARY_BY_ENTITY_TYPE_COUNT_API;
693 handleSummaryByEntityTypeCount(request, response);
695 } else if (request.getRequestURI().contains(SUMMARY_BY_ENTITY_TYPE_API)) {
696 api = SUMMARY_BY_ENTITY_TYPE_API;
697 handleSummaryByEntityType(request, response);
701 final String errorMessage = "Ignored request-uri = " + request.getRequestURI();
702 LOG.error(AaiUiMsgs.SEARCH_SERVLET_ERROR, errorMessage);
703 response.setStatus(404);
704 response.setContentType("application/json");
705 PrintWriter out = response.getWriter();
706 out.println(generateJsonErrorResponse(errorMessage));
711 } catch (JSONException je) {
712 handleSearchServletErrors("Caught an exception while parsing json in processing for " + api,
714 } catch (Exception e1) {
715 handleSearchServletErrors("Caught an exception while communicating with elasticsearch", e1,
721 * Generate json error response.
723 * @param message the message
727 * This is the manual approach, however we could also create an object container for the error
728 * then use the Jackson ObjectWrite to dump the object to json instead. If it gets any more
729 * complicated we could do that approach so we don't have to manually trip over the JSON
732 protected String generateJsonErrorResponse(String message) {
733 return String.format("{ \"errorMessage\" : %s }", message);
737 * Handle search servlet errors.
739 * @param errorMsg the error msg
741 * @param response the response
742 * @throws IOException Signals that an I/O exception has occurred.
744 public void handleSearchServletErrors(String errorMsg, Exception exc,
745 HttpServletResponse response) throws IOException {
748 (exc == null ? errorMsg : errorMsg + ". Error:" + exc.getLocalizedMessage());
750 LOG.error(AaiUiMsgs.SEARCH_SERVLET_ERROR, errorLogMsg);
752 response.setContentType("application/json");
753 PrintWriter out = response.getWriter();
754 out.println(generateJsonErrorResponse(errorMsg));
762 * @param response the response
763 * @param requestUrl the request url
764 * @param requestJsonPayload the request json payload
765 * @throws Exception the exception
767 public void executeQuery(HttpServletResponse response, String requestUrl,
768 String requestJsonPayload) throws Exception {
770 OperationResult opResult = search.doPost(requestUrl, requestJsonPayload, "application/json");
772 if (opResult != null) {
774 response.setStatus(opResult.getResultCode());
775 String finalOutput = opResult.getResult();
777 // example: failed to populate drop-down items from formatOutputJson()
778 if (finalOutput != null) {
779 response.setContentType("application/json");
780 PrintWriter out = response.getWriter();
781 out.println(finalOutput);
786 response.setStatus(500);
792 * Sets the servlet response.
794 * @param response the response
795 * @param postPayload the post payload
797 * @throws IOException Signals that an I/O exception has occurred.
799 private void setServletResponse(HttpServletResponse response, String postPayload)
802 if (postPayload != null) {
803 response.setContentType("application/json");
804 PrintWriter out = response.getWriter();
805 out.println(postPayload);
813 public ObjectMapper getMapper() {
818 * @param mapper the mapper to set
820 public void setMapper(ObjectMapper mapper) {
821 this.mapper = mapper;
825 * @return the serialversionuid
827 public static long getSerialversionuid() {
828 return serialVersionUID;
834 public static Logger getLog() {
839 * @return the searchString
841 public static String getSearchString() {
842 return SEARCH_STRING;
846 * @return the countString
848 public static String getCountString() {
853 * @return the querySearch
855 public static String getQuerySearch() {
860 * @return the summaryByEntityTypeApi
862 public static String getSummaryByEntityTypeApi() {
863 return SUMMARY_BY_ENTITY_TYPE_API;
867 * @return the summaryByEntityTypeCountApi
869 public static String getSummaryByEntityTypeCountApi() {
870 return SUMMARY_BY_ENTITY_TYPE_COUNT_API;
874 * @return the valueAnykey
876 public static String getValueAnykey() {
881 * @return the valueQuery
883 public static String getValueQuery() {
888 * @return the keyHashId
890 public static String getKeyHashId() {
895 * @return the keyGroupBy
897 public static String getKeyGroupBy() {
902 * @return the keySearchResult
904 public static String getKeySearchResult() {
905 return KEY_SEARCH_RESULT;
909 * @return the keyHits
911 public static String getKeyHits() {
916 * @return the keyPayload
918 public static String getKeyPayload() {
923 * @return the keyDocument
925 public static String getKeyDocument() {
930 * @return the keyContent
932 public static String getKeyContent() {
937 * @return the keySearchTagIds
939 public static String getKeySearchTagIds() {
940 return KEY_SEARCH_TAG_IDS;
944 * @return the keySearchTags
946 public static String getKeySearchTags() {
947 return KEY_SEARCH_TAGS;
951 * @return the keyLink
953 public static String getKeyLink() {
958 * @return the keyEntityType
960 public static String getKeyEntityType() {
961 return KEY_ENTITY_TYPE;
965 * @return the viSuggestionRoute
967 public static String getViSuggestionRoute() {
968 return VI_SUGGESTION_ROUTE;
972 * @return the viuiSearchTemplate
974 public static String getViuiSearchTemplate() {
975 return VIUI_SEARCH_TEMPLATE;