PageRenderTime 47ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/app/controllers/SearchController.java

https://github.com/Graylog2/graylog2-web-interface
Java | 203 lines | 155 code | 26 blank | 22 comment | 33 complexity | 38c97d22bf32fd7f69f149bef5ead80e MD5 | raw file
  1. /*
  2. * Copyright 2013 TORCH UG
  3. *
  4. * This file is part of Graylog2.
  5. *
  6. * Graylog2 is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * Graylog2 is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with Graylog2. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. package controllers;
  20. import com.google.common.base.Splitter;
  21. import com.google.common.collect.Iterables;
  22. import com.google.common.collect.Lists;
  23. import com.google.common.collect.Sets;
  24. import com.google.common.net.MediaType;
  25. import com.google.inject.Inject;
  26. import lib.*;
  27. import lib.security.RestPermissions;
  28. import org.graylog2.restclient.lib.APIException;
  29. import org.graylog2.restclient.lib.ApiClient;
  30. import org.graylog2.restclient.lib.Field;
  31. import org.graylog2.restclient.lib.ServerNodes;
  32. import org.graylog2.restclient.lib.timeranges.InvalidRangeParametersException;
  33. import org.graylog2.restclient.lib.timeranges.TimeRange;
  34. import org.graylog2.restclient.models.*;
  35. import org.graylog2.restclient.models.api.results.DateHistogramResult;
  36. import org.graylog2.restclient.models.api.results.SearchResult;
  37. import play.mvc.Result;
  38. import views.helpers.Permissions;
  39. import java.io.IOException;
  40. import java.util.List;
  41. import java.util.Set;
  42. public class SearchController extends AuthenticatedController {
  43. @Inject
  44. protected UniversalSearch.Factory searchFactory;
  45. @Inject
  46. protected MessagesService messagesService;
  47. @Inject
  48. protected SavedSearchService savedSearchService;
  49. @Inject
  50. private ServerNodes serverNodes;
  51. public Result globalSearch() {
  52. // User would not be allowed to do any global searches anyway, so we can redirect him to the streams page to avoid confusion.
  53. if (Permissions.isPermitted(RestPermissions.SEARCHES_ABSOLUTE)
  54. || Permissions.isPermitted(RestPermissions.SEARCHES_RELATIVE)
  55. || Permissions.isPermitted(RestPermissions.SEARCHES_KEYWORD)) {
  56. return ok(views.html.search.global.render(currentUser()));
  57. } else {
  58. return redirect(routes.StreamsController.index());
  59. }
  60. }
  61. public Result index(String q,
  62. String rangeType,
  63. int relative,
  64. String from, String to,
  65. String keyword,
  66. String interval,
  67. int page,
  68. String savedSearchId,
  69. String sortField, String sortOrder,
  70. String fields) {
  71. SearchSort sort = buildSearchSort(sortField, sortOrder);
  72. UniversalSearch search;
  73. try {
  74. search = getSearch(q, null, rangeType, relative, from, to, keyword, page, sort);
  75. } catch(InvalidRangeParametersException e2) {
  76. return status(400, views.html.errors.error.render("Invalid range parameters provided.", e2, request()));
  77. } catch(IllegalArgumentException e1) {
  78. return status(400, views.html.errors.error.render("Invalid range type provided.", e1, request()));
  79. }
  80. SearchResult searchResult;
  81. DateHistogramResult histogramResult;
  82. SavedSearch savedSearch;
  83. Set<String> selectedFields = getSelectedFields(fields);
  84. try {
  85. if(savedSearchId != null && !savedSearchId.isEmpty()) {
  86. savedSearch = savedSearchService.get(savedSearchId);
  87. } else {
  88. savedSearch = null;
  89. }
  90. // Histogram interval.
  91. if (interval == null || interval.isEmpty() || !SearchTools.isAllowedDateHistogramInterval(interval)) {
  92. interval = "minute";
  93. }
  94. searchResult = search.search();
  95. if (searchResult.getError() != null) {
  96. return ok(views.html.search.queryerror.render(currentUser(), q, searchResult, savedSearch, fields, null));
  97. }
  98. searchResult.setAllFields(getAllFields());
  99. histogramResult = search.dateHistogram(interval);
  100. } catch (IOException e) {
  101. return status(504, views.html.errors.error.render(ApiClient.ERROR_MSG_IO, e, request()));
  102. } catch (APIException e) {
  103. String message = "There was a problem with your search. We expected HTTP 200, but got a HTTP " + e.getHttpCode() + ".";
  104. return status(504, views.html.errors.error.render(message, e, request()));
  105. }
  106. if (searchResult.getTotalResultCount() > 0) {
  107. return ok(views.html.search.results.render(currentUser(), search, searchResult, histogramResult, q, page, savedSearch, selectedFields, serverNodes.asMap(), null));
  108. } else {
  109. return ok(views.html.search.noresults.render(currentUser(), q, searchResult, savedSearch, selectedFields, null));
  110. }
  111. }
  112. protected Set<String> getSelectedFields(String fields) {
  113. Set<String> selectedFields = Sets.newLinkedHashSet();
  114. if (fields != null && !fields.isEmpty()) {
  115. Iterables.addAll(selectedFields, Splitter.on(',').split(fields));
  116. } else {
  117. selectedFields.addAll(Field.STANDARD_SELECTED_FIELDS);
  118. }
  119. return selectedFields;
  120. }
  121. public Result exportAsCsv(String q, String filter, String rangeType, int relative, String from, String to, String keyword, String fields) {
  122. UniversalSearch search;
  123. try {
  124. search = getSearch(q, filter.isEmpty() ? null : filter, rangeType, relative, from, to, keyword, 0, UniversalSearch.DEFAULT_SORT);
  125. } catch(InvalidRangeParametersException e2) {
  126. return status(400, views.html.errors.error.render("Invalid range parameters provided.", e2, request()));
  127. } catch(IllegalArgumentException e1) {
  128. return status(400, views.html.errors.error.render("Invalid range type provided.", e1, request()));
  129. }
  130. final String s;
  131. try {
  132. Set<String> selectedFields = getSelectedFields(fields);
  133. s = search.searchAsCsv(selectedFields);
  134. } catch (IOException e) {
  135. return status(504, views.html.errors.error.render(ApiClient.ERROR_MSG_IO, e, request()));
  136. } catch (APIException e) {
  137. String message = "There was a problem with your search. We expected HTTP 200, but got a HTTP " + e.getHttpCode() + ".";
  138. return status(504, views.html.errors.error.render(message, e, request()));
  139. }
  140. // TODO streaming the result
  141. response().setContentType(MediaType.CSV_UTF_8.toString());
  142. response().setHeader("Content-Disposition", "attachment; filename=graylog2-searchresult.csv");
  143. return ok(s);
  144. }
  145. protected List<Field> getAllFields() {
  146. List<Field> allFields = Lists.newArrayList();
  147. for(String f : messagesService.getMessageFields()) {
  148. allFields.add(new Field(f));
  149. }
  150. return allFields;
  151. }
  152. protected UniversalSearch getSearch(String q, String filter, String rangeType, int relative,String from, String to, String keyword, int page, SearchSort order)
  153. throws InvalidRangeParametersException, IllegalArgumentException {
  154. if (q == null || q.trim().isEmpty()) {
  155. q = "*";
  156. }
  157. // Determine timerange type.
  158. TimeRange timerange = TimeRange.factory(rangeType, relative, from, to, keyword);
  159. UniversalSearch search;
  160. if (filter == null) {
  161. search = searchFactory.queryWithRangePageAndOrder(q, timerange, page, order);
  162. } else {
  163. search = searchFactory.queryWithFilterRangePageAndOrder(q, filter, timerange, page, order);
  164. }
  165. return search;
  166. }
  167. protected SearchSort buildSearchSort(String sortField, String sortOrder) {
  168. if (sortField == null || sortOrder == null || sortField.isEmpty() || sortOrder.isEmpty()) {
  169. return UniversalSearch.DEFAULT_SORT;
  170. }
  171. try {
  172. return new SearchSort(sortField, SearchSort.Direction.valueOf(sortOrder.toUpperCase()));
  173. } catch(IllegalArgumentException e) {
  174. return UniversalSearch.DEFAULT_SORT;
  175. }
  176. }
  177. }