use of org.graylog2.indexer.ElasticsearchException in project graylog2-server by Graylog2.
the class JestUtils method checkForFailedShards.
public static Optional<ElasticsearchException> checkForFailedShards(JestResult result) {
// unwrap shard failure due to non-numeric mapping. this happens when searching across index sets
// if at least one of the index sets comes back with a result, the overall result will have the aggregation
// but not considered failed entirely. however, if one shard has the error, we will refuse to respond
// otherwise we would be showing empty graphs for non-numeric fields.
final JsonNode shards = result.getJsonObject().path("_shards");
final double failedShards = shards.path("failed").asDouble();
if (failedShards > 0) {
final List<String> errors = StreamSupport.stream(shards.path("failures").spliterator(), false).map(failure -> failure.path("reason").path("reason").asText()).filter(s -> !s.isEmpty()).collect(Collectors.toList());
final List<String> nonNumericFieldErrors = errors.stream().filter(error -> error.startsWith("Expected numeric type on field")).collect(Collectors.toList());
if (!nonNumericFieldErrors.isEmpty()) {
return Optional.of(new FieldTypeException("Unable to perform search query: ", deduplicateErrors(nonNumericFieldErrors)));
}
return Optional.of(new ElasticsearchException("Unable to perform search query: ", deduplicateErrors(errors)));
}
return Optional.empty();
}
use of org.graylog2.indexer.ElasticsearchException in project graylog2-server by Graylog2.
the class JestUtils method specificException.
public static ElasticsearchException specificException(Supplier<String> errorMessage, JsonNode errorNode) {
final JsonNode rootCauses = errorNode.path("root_cause");
final List<String> reasons = new ArrayList<>(rootCauses.size());
for (JsonNode rootCause : rootCauses) {
final JsonNode reason = rootCause.path("reason");
if (reason.isTextual()) {
reasons.add(reason.asText());
}
final JsonNode type = rootCause.path("type");
if (!type.isTextual()) {
continue;
}
switch(type.asText()) {
case "master_not_discovered_exception":
return new MasterNotDiscoveredException();
case "cluster_block_exception":
if (reason.asText().contains("no master")) {
return new MasterNotDiscoveredException();
}
case "query_parsing_exception":
return buildQueryParsingException(errorMessage, rootCause, reasons);
case "index_not_found_exception":
final String indexName = rootCause.path("resource.id").asText();
return IndexNotFoundException.create(errorMessage.get(), indexName);
case "illegal_argument_exception":
final String reasonText = reason.asText();
if (reasonText.startsWith("Expected numeric type on field")) {
return buildFieldTypeException(errorMessage, reasonText);
}
if (reasonText.startsWith("no write index is defined for alias")) {
final Matcher matcher = invalidWriteTarget.matcher(reasonText);
if (matcher.find()) {
final String target = matcher.group("target");
return InvalidWriteTargetException.create(target);
}
}
break;
}
}
if (reasons.isEmpty()) {
return new ElasticsearchException(errorMessage.get(), Collections.singletonList(errorNode.toString()));
}
return new ElasticsearchException(errorMessage.get(), deduplicateErrors(reasons));
}
use of org.graylog2.indexer.ElasticsearchException in project graylog2-server by Graylog2.
the class MultiSearch method wrap.
public SearchResult wrap(Search search, Supplier<String> errorMessage) {
final io.searchbox.core.MultiSearch multiSearch = new io.searchbox.core.MultiSearch.Builder(search).build();
final MultiSearchResult multiSearchResult = JestUtils.execute(jestClient, multiSearch, errorMessage);
final List<MultiSearchResult.MultiSearchResponse> responses = multiSearchResult.getResponses();
if (responses.size() != 1) {
throw new ElasticsearchException("Expected exactly 1 search result, but got " + responses.size());
}
final MultiSearchResult.MultiSearchResponse response = responses.get(0);
if (response.isError) {
throw JestUtils.specificException(errorMessage, response.error);
}
final Optional<ElasticsearchException> elasticsearchException = checkForFailedShards(response.searchResult);
elasticsearchException.ifPresent(e -> {
throw e;
});
return response.searchResult;
}
use of org.graylog2.indexer.ElasticsearchException in project graylog2-server by Graylog2.
the class IndicesAdapterES6 method updateIndexMapping.
@Override
public void updateIndexMapping(@Nonnull String indexName, @Nonnull String mappingType, @Nonnull Map<String, Object> mapping) {
final PutMapping request = new PutMapping.Builder(indexName, mappingType, mapping).build();
final JestResult jestResult;
try {
jestResult = jestClient.execute(request);
} catch (IOException e) {
throw new ElasticsearchException("Couldn't update index mapping " + indexName + "/" + mappingType, e);
}
if (!jestResult.isSucceeded()) {
throw new ElasticsearchException(jestResult.getErrorMessage());
}
}
use of org.graylog2.indexer.ElasticsearchException in project graylog2-server by Graylog2.
the class IndicesAdapterES6 method move.
@Override
public void move(String source, String target, Consumer<IndexMoveResult> resultCallback) {
// TODO: This method should use the Re-index API: https://www.elastic.co/guide/en/elasticsearch/reference/5.3/docs-reindex.html
final String query = SearchSourceBuilder.searchSource().query(QueryBuilders.matchAllQuery()).size(350).sort(SortBuilders.fieldSort(FieldSortBuilder.DOC_FIELD_NAME)).toString();
final Search request = new Search.Builder(query).setParameter(Parameters.SCROLL, "10s").addIndex(source).build();
final SearchResult searchResult = JestUtils.execute(jestClient, request, () -> "Couldn't process search query response");
final String scrollId = searchResult.getJsonObject().path("_scroll_id").asText(null);
if (scrollId == null) {
throw new ElasticsearchException("Couldn't find scroll ID in search query response");
}
while (true) {
final SearchScroll scrollRequest = new SearchScroll.Builder(scrollId, "1m").build();
final JestResult scrollResult = JestUtils.execute(jestClient, scrollRequest, () -> "Couldn't process result of scroll query");
final JsonNode scrollHits = scrollResult.getJsonObject().path("hits").path("hits");
// No more hits.
if (scrollHits.size() == 0) {
break;
}
final Bulk.Builder bulkRequestBuilder = new Bulk.Builder();
for (JsonNode jsonElement : scrollHits) {
Optional.ofNullable(jsonElement.path("_source")).map(sourceJson -> objectMapper.<Map<String, Object>>convertValue(sourceJson, TypeReferences.MAP_STRING_OBJECT)).ifPresent(doc -> {
final String id = (String) doc.remove("_id");
if (!Strings.isNullOrEmpty(id)) {
bulkRequestBuilder.addAction(indexingHelper.prepareIndexRequest(target, doc, id));
}
});
}
final BulkResult bulkResult = JestUtils.execute(jestClient, bulkRequestBuilder.build(), () -> "Couldn't bulk index messages into index " + target);
final boolean hasFailedItems = !bulkResult.getFailedItems().isEmpty();
final IndexMoveResult result = IndexMoveResult.create(bulkResult.getItems().size(), bulkResult.getJsonObject().path("took").asLong(), hasFailedItems);
resultCallback.accept(result);
}
}
Aggregations