Skip to content
This repository was archived by the owner on Jan 8, 2019. It is now read-only.

Commit ceaca33

Browse files
committed
use selected fields for csv export
limit number of messages to 10000 to avoid running out of heap. fixes #766
1 parent 48f598c commit ceaca33

File tree

5 files changed

+27
-15
lines changed

5 files changed

+27
-15
lines changed

app/controllers/SearchController.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ protected Set<String> getSelectedFields(String fields) {
131131
return selectedFields;
132132
}
133133

134-
public Result exportAsCsv(String q, String filter, String rangeType, int relative, String from, String to, String keyword) {
134+
public Result exportAsCsv(String q, String filter, String rangeType, int relative, String from, String to, String keyword, String fields) {
135135
UniversalSearch search;
136136
try {
137137
search = getSearch(q, filter.isEmpty() ? null : filter, rangeType, relative, from, to, keyword, 0, UniversalSearch.DEFAULT_SORT);
@@ -143,7 +143,8 @@ public Result exportAsCsv(String q, String filter, String rangeType, int relativ
143143

144144
final String s;
145145
try {
146-
s = search.searchAsCsv();
146+
Set<String> selectedFields = getSelectedFields(fields);
147+
s = search.searchAsCsv(selectedFields);
147148
} catch (IOException e) {
148149
return status(504, views.html.errors.error.render(ApiClient.ERROR_MSG_IO, e, request()));
149150
} catch (APIException e) {

app/controllers/StreamSearchController.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ public Result index(String streamId,
102102
}
103103

104104
@Override
105-
public Result exportAsCsv(String q, String streamId, String rangeType, int relative, String from, String to, String keyword) {
106-
return super.exportAsCsv(q, "streams:"+streamId, rangeType, relative, from, to, keyword);
105+
public Result exportAsCsv(String q, String streamId, String rangeType, int relative, String from, String to, String keyword, String fields) {
106+
return super.exportAsCsv(q, "streams:"+streamId, rangeType, relative, from, to, keyword, fields);
107107
}
108108
}

app/models/UniversalSearch.java

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,14 @@
1818
*/
1919
package models;
2020

21+
import com.google.common.base.Joiner;
2122
import com.google.common.net.MediaType;
2223
import com.google.inject.assistedinject.Assisted;
2324
import com.google.inject.assistedinject.AssistedInject;
2425
import controllers.routes;
2526
import lib.APIException;
2627
import lib.ApiClient;
28+
import lib.ApiRequestBuilder;
2729
import lib.Tools;
2830
import lib.timeranges.TimeRange;
2931
import models.api.responses.*;
@@ -36,6 +38,7 @@
3638

3739
import javax.annotation.Nullable;
3840
import java.io.IOException;
41+
import java.util.Set;
3942
import java.util.concurrent.TimeUnit;
4043

4144
import static lib.Configuration.apiTimeout;
@@ -102,23 +105,28 @@ private UniversalSearch(ApiClient api, FieldMapper fieldMapper, @Assisted TimeRa
102105
}
103106
}
104107

105-
private <T> T doSearch(Class<T> clazz, MediaType mediaType, int pageSize) throws APIException, IOException {
106-
return api.get(clazz)
108+
private <T> T doSearch(Class<T> clazz, MediaType mediaType, int pageSize, Set<String> selectedFields) throws APIException, IOException {
109+
final ApiRequestBuilder<T> builder = api.get(clazz)
107110
.path("/search/universal/{0}", timeRange.getType().toString().toLowerCase())
108111
.queryParams(timeRange.getQueryParams())
109112
.queryParam("query", query)
110113
.queryParam("limit", pageSize)
111114
.queryParam("offset", page * pageSize)
112115
.queryParam("filter", (filter == null ? "*" : filter))
113-
.queryParam("sort", order.toApiParam())
116+
.queryParam("sort", order.toApiParam());
117+
if (selectedFields != null && !selectedFields.isEmpty()) {
118+
builder.queryParam("fields", Joiner.on(',').skipNulls().join(selectedFields));
119+
}
120+
final T result = builder
114121
.accept(mediaType)
115122
.timeout(KEITH, TimeUnit.SECONDS)
116123
.expect(200, 400)
117124
.execute();
125+
return result;
118126
}
119127

120128
public SearchResult search() throws IOException, APIException {
121-
SearchResultResponse response = doSearch(SearchResultResponse.class, MediaType.JSON_UTF_8, PER_PAGE);
129+
SearchResultResponse response = doSearch(SearchResultResponse.class, MediaType.JSON_UTF_8, PER_PAGE, null);
122130
if (response == null) {
123131
log.error("We should never get an empty result without throwing an IOException.");
124132
throw new APIException(null, null, new RuntimeException("Empty search response, this is likely a bug in exception handling."));
@@ -140,8 +148,8 @@ public SearchResult search() throws IOException, APIException {
140148
return result;
141149
}
142150

143-
public String searchAsCsv() throws IOException, APIException {
144-
return doSearch(String.class, MediaType.CSV_UTF_8, 100000); // TODO fix huge page size by using scroll searches and streaming results
151+
public String searchAsCsv(Set<String> selectedFields) throws IOException, APIException {
152+
return doSearch(String.class, MediaType.CSV_UTF_8, 10_000, selectedFields); // TODO make use of streaming support in the server.
145153
}
146154

147155
public DateHistogramResult dateHistogram(String interval) throws IOException, APIException {
@@ -243,6 +251,7 @@ public Call getCsvRoute(Request request, Stream stream) {
243251
String from = Tools.stringSearchParamOrEmpty(request, "from");
244252
String to = Tools.stringSearchParamOrEmpty(request, "to");
245253
String keyword = Tools.stringSearchParamOrEmpty(request, "keyword");
254+
String fields = Tools.stringSearchParamOrEmpty(request, "fields");
246255
if (stream == null) {
247256
return routes.SearchController.exportAsCsv(
248257
query,
@@ -251,7 +260,8 @@ public Call getCsvRoute(Request request, Stream stream) {
251260
relative,
252261
from,
253262
to,
254-
keyword
263+
keyword,
264+
fields
255265
);
256266
} else {
257267
return routes.StreamSearchController.exportAsCsv(
@@ -261,7 +271,8 @@ public Call getCsvRoute(Request request, Stream stream) {
261271
relative,
262272
from,
263273
to,
264-
keyword
274+
keyword,
275+
fields
265276
);
266277
}
267278
}

app/views/search/results.scala.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@
6161
<span class="caret"></span>
6262
</a>
6363
<ul class="dropdown-menu">
64-
<li><a href="@search.getCsvRoute(request(), stream)">Download as CSV</a></li>
64+
<li><a class="search-view-state" href="@search.getCsvRoute(request(), stream)">Download as CSV</a></li>
6565
</ul>
6666
</div>
6767

conf/routes

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ GET /startpage
1818

1919
# Search
2020
GET /search @controllers.SearchController.index(q ?= "", rangetype ?= "", relative:Integer ?= -1, from ?= "", to ?= "", keyword ?= "", interval ?= "", page:Integer ?= 1, saved:String ?= "", sortField:String ?= "", sortOrder:String ?= "", fields:String ?= "")
21-
GET /search/csv @controllers.SearchController.exportAsCsv(q ?= "", filter ?= "", rangetype ?= "", relative:Integer ?= -1, from ?= "", to ?= "", keyword ?= "")
21+
GET /search/csv @controllers.SearchController.exportAsCsv(q ?= "", filter ?= "", rangetype ?= "", relative:Integer ?= -1, from ?= "", to ?= "", keyword ?= "", fields:String ?= "")
2222

2323
# Messages
2424
GET /messages/:index/:id @controllers.MessagesController.show(index: String, id: String)
@@ -40,7 +40,7 @@ GET /streams/:stream_id/edit
4040
POST /streams/:stream_id/update @controllers.StreamsController.update(stream_id: String)
4141
GET /streams/:stream_id/clone @controllers.StreamsController.cloneStreamForm(stream_id: String)
4242
POST /streams/:stream_id/clone @controllers.StreamsController.cloneStream(stream_id: String)
43-
GET /streams/:stream_id/csv @controllers.StreamSearchController.exportAsCsv(q ?= "", stream_id: String, rangetype ?= "", relative:Integer ?= -1, from ?= "", to ?= "", keyword ?= "")
43+
GET /streams/:stream_id/csv @controllers.StreamSearchController.exportAsCsv(q ?= "", stream_id: String, rangetype ?= "", relative:Integer ?= -1, from ?= "", to ?= "", keyword ?= "", fields:String ?="")
4444

4545
# Alerts
4646
GET /streams/:stream_id/alerts @controllers.AlertsController.index(stream_id: String)

0 commit comments

Comments
 (0)