Skip to content

Commit

Permalink
Use Multi Search in Searches to prevent large HTTP request headers (#…
Browse files Browse the repository at this point in the history
…4149)

Instead of artificially restricting the number of indices in a search request and
resorting to using index wildcards if the list of indices threatens to hit the default
HTTP header size limit of Elasticsearch (4 KB), the `Searches` class is now using the
Multi Search API of Elasticsearch which allows specifying the list of indices in the
request body instead of the URI path.

Refs https://www.elastic.co/guide/en/elasticsearch/reference/5.6/search-multi-search.html
Refs elastic/elasticsearch#26360
Refs #4054
  • Loading branch information
joschi authored and bernd committed Sep 20, 2017
1 parent 87b651f commit ec7f57e
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 132 deletions.
Expand Up @@ -17,7 +17,6 @@
package org.graylog2.indexer.cluster.jest; package org.graylog2.indexer.cluster.jest;


import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
import com.google.common.collect.ImmutableList;
import io.searchbox.action.Action; import io.searchbox.action.Action;
import io.searchbox.client.JestClient; import io.searchbox.client.JestClient;
import io.searchbox.client.JestResult; import io.searchbox.client.JestResult;
Expand All @@ -29,10 +28,10 @@
import org.graylog2.indexer.QueryParsingException; import org.graylog2.indexer.QueryParsingException;


import java.io.IOException; import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.function.Supplier; import java.util.function.Supplier;
import java.util.stream.Collectors;




public class JestUtils { public class JestUtils {
Expand Down Expand Up @@ -64,24 +63,29 @@ public static <T extends JestResult> T execute(JestClient client, Action<T> requ
} }


public static ElasticsearchException specificException(Supplier<String> errorMessage, JsonNode errorNode) { public static ElasticsearchException specificException(Supplier<String> errorMessage, JsonNode errorNode) {
final List<JsonNode> rootCauses = extractRootCauses(errorNode); final JsonNode rootCauses = errorNode.path("root_cause");
final List<String> reasons = extractReasons(rootCauses); final List<String> reasons = new ArrayList<>(rootCauses.size());


for (JsonNode rootCause : rootCauses) { for (JsonNode rootCause : rootCauses) {
final String type = rootCause.path("type").asText(null); final JsonNode reason = rootCause.path("reason");
if (type == null) { if (reason.isTextual()) {
reasons.add(reason.asText());
}

final JsonNode type = rootCause.path("type");
if (!type.isTextual()) {
continue; continue;
} }
switch(type) { switch(type.asText()) {
case "query_parsing_exception": case "query_parsing_exception":
return buildQueryParsingException(errorMessage, rootCause, reasons); return buildQueryParsingException(errorMessage, rootCause, reasons);
case "index_not_found_exception": case "index_not_found_exception":
final String indexName = rootCause.path("resource.id").asText(); final String indexName = rootCause.path("resource.id").asText();
return buildIndexNotFoundException(errorMessage, indexName); return buildIndexNotFoundException(errorMessage, indexName);
case "illegal_argument_exception": case "illegal_argument_exception":
final String reason = rootCause.path("reason").asText(); final String reasonText = reason.asText();
if (reason.startsWith("Expected numeric type on field")) { if (reasonText.startsWith("Expected numeric type on field")) {
return buildFieldTypeException(errorMessage, reason); return buildFieldTypeException(errorMessage, reasonText);
} }
break; break;
} }
Expand All @@ -98,16 +102,6 @@ private static FieldTypeException buildFieldTypeException(Supplier<String> error
return new FieldTypeException(errorMessage.get(), reason); return new FieldTypeException(errorMessage.get(), reason);
} }


private static List<String> extractReasons(List<JsonNode> rootCauses) {
return rootCauses.stream()
.map(rootCause -> rootCause.path("reason").asText(null))
.collect(Collectors.toList());
}

private static List<JsonNode> extractRootCauses(JsonNode jsonObject) {
return ImmutableList.copyOf(jsonObject.path("root_cause").iterator());
}

private static QueryParsingException buildQueryParsingException(Supplier<String> errorMessage, private static QueryParsingException buildQueryParsingException(Supplier<String> errorMessage,
JsonNode rootCause, JsonNode rootCause,
List<String> reasons) { List<String> reasons) {
Expand Down

0 comments on commit ec7f57e

Please sign in to comment.