diff --git a/changelog/unreleased/pr-21197.toml b/changelog/unreleased/pr-21197.toml new file mode 100644 index 000000000000..89604ad1f796 --- /dev/null +++ b/changelog/unreleased/pr-21197.toml @@ -0,0 +1,5 @@ +type = "fixed" +message = "Add archive restore retry on mapper parsing exception." + +issues = ["graylog-plugin-enterprise#9208"] +pulls = ["21197", "Graylog2/graylog-plugin-enterprise#9413"] diff --git a/graylog-storage-elasticsearch7/src/main/java/org/graylog/storage/elasticsearch7/ElasticsearchClient.java b/graylog-storage-elasticsearch7/src/main/java/org/graylog/storage/elasticsearch7/ElasticsearchClient.java index c6c45d1f2de8..4f16148a0cb6 100644 --- a/graylog-storage-elasticsearch7/src/main/java/org/graylog/storage/elasticsearch7/ElasticsearchClient.java +++ b/graylog-storage-elasticsearch7/src/main/java/org/graylog/storage/elasticsearch7/ElasticsearchClient.java @@ -42,6 +42,7 @@ import org.graylog2.indexer.BatchSizeTooLargeException; import org.graylog2.indexer.IndexNotFoundException; import org.graylog2.indexer.InvalidWriteTargetException; +import org.graylog2.indexer.MapperParsingException; import org.graylog2.indexer.MasterNotDiscoveredException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -202,6 +203,9 @@ private ElasticsearchException exceptionFrom(Exception e, String errorMessage) { if (isBatchSizeTooLargeException(elasticsearchException)) { throw new BatchSizeTooLargeException(elasticsearchException.getMessage()); } + if (isMapperParsingExceptionException(elasticsearchException)) { + throw new MapperParsingException(elasticsearchException.getMessage()); + } } else if (e instanceof IOException && e.getCause() instanceof ContentTooLongException) { throw new BatchSizeTooLargeException(e.getMessage()); } @@ -231,6 +235,10 @@ private boolean isIndexNotFoundException(ElasticsearchException elasticsearchExc return elasticsearchException.getMessage().contains("index_not_found_exception"); } + private boolean isMapperParsingExceptionException(ElasticsearchException openSearchException) { + return openSearchException.getMessage().contains("mapper_parsing_exception"); + } + private boolean isBatchSizeTooLargeException(ElasticsearchException elasticsearchException) { if (elasticsearchException instanceof ElasticsearchStatusException statusException) { if (statusException.getCause() instanceof ResponseException responseException) { diff --git a/graylog-storage-opensearch2/src/main/java/org/graylog/storage/opensearch2/OpenSearchClient.java b/graylog-storage-opensearch2/src/main/java/org/graylog/storage/opensearch2/OpenSearchClient.java index e12b820a3a14..0bc939e48e6d 100644 --- a/graylog-storage-opensearch2/src/main/java/org/graylog/storage/opensearch2/OpenSearchClient.java +++ b/graylog-storage-opensearch2/src/main/java/org/graylog/storage/opensearch2/OpenSearchClient.java @@ -42,6 +42,7 @@ import org.graylog2.indexer.BatchSizeTooLargeException; import org.graylog2.indexer.IndexNotFoundException; import org.graylog2.indexer.InvalidWriteTargetException; +import org.graylog2.indexer.MapperParsingException; import org.graylog2.indexer.MasterNotDiscoveredException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -202,6 +203,9 @@ private OpenSearchException exceptionFrom(Exception e, String errorMessage) { if (isBatchSizeTooLargeException(openSearchException)) { throw new BatchSizeTooLargeException(openSearchException.getMessage()); } + if (isMapperParsingExceptionException(openSearchException)) { + throw new MapperParsingException(openSearchException.getMessage()); + } } else if (e instanceof IOException && e.getCause() instanceof ContentTooLongException) { throw new BatchSizeTooLargeException(e.getMessage()); } @@ -231,6 +235,10 @@ private boolean isIndexNotFoundException(OpenSearchException openSearchException return openSearchException.getMessage().contains("index_not_found_exception"); } + private boolean isMapperParsingExceptionException(OpenSearchException openSearchException) { + return openSearchException.getMessage().contains("mapper_parsing_exception"); + } + private boolean isBatchSizeTooLargeException(OpenSearchException openSearchException) { if (openSearchException instanceof OpenSearchStatusException statusException) { if (statusException.getCause() instanceof ResponseException responseException) { diff --git a/graylog2-server/src/main/java/org/graylog2/indexer/MapperParsingException.java b/graylog2-server/src/main/java/org/graylog2/indexer/MapperParsingException.java new file mode 100644 index 000000000000..e7c656adf015 --- /dev/null +++ b/graylog2-server/src/main/java/org/graylog2/indexer/MapperParsingException.java @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2020 Graylog, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the Server Side Public License, version 1, + * as published by MongoDB, Inc. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Server Side Public License for more details. + * + * You should have received a copy of the Server Side Public License + * along with this program. If not, see + * . + */ +package org.graylog2.indexer; + +public class MapperParsingException extends ElasticsearchException { + public MapperParsingException(String errorMessage) { + super(errorMessage); + } +} diff --git a/graylog2-server/src/main/java/org/graylog2/indexer/indices/Indices.java b/graylog2-server/src/main/java/org/graylog2/indexer/indices/Indices.java index 5dd979d9a055..1a98434c011c 100644 --- a/graylog2-server/src/main/java/org/graylog2/indexer/indices/Indices.java +++ b/graylog2-server/src/main/java/org/graylog2/indexer/indices/Indices.java @@ -36,6 +36,7 @@ import org.graylog2.indexer.IndexNotFoundException; import org.graylog2.indexer.IndexSet; import org.graylog2.indexer.IndexTemplateNotFoundException; +import org.graylog2.indexer.MapperParsingException; import org.graylog2.indexer.indexset.CustomFieldMappings; import org.graylog2.indexer.indexset.IndexSetConfig; import org.graylog2.indexer.indexset.IndexSetMappingTemplate; @@ -227,7 +228,7 @@ public void deleteIndexTemplate(IndexSet indexSet) { } public boolean create(String indexName, IndexSet indexSet) { - return create(indexName, indexSet, null, null ); + return create(indexName, indexSet, null, null); } public boolean create(String indexName, @@ -248,6 +249,10 @@ public boolean create(String indexName, indicesAdapter.create(indexName, settings, mappings); } catch (Exception e) { + if ((indexSettings != null || indexMapping != null) && e instanceof MapperParsingException) { + LOG.info("Couldn't create index {}. Error: {}. Fall back to default settings/mappings and retry.", indexName, e.getMessage(), e); + return create(indexName, indexSet, null, null); + } LOG.warn("Couldn't create index {}. Error: {}", indexName, e.getMessage(), e); auditEventSender.failure(AuditActor.system(nodeId), ES_INDEX_CREATE, ImmutableMap.of("indexName", indexName)); return false; @@ -259,7 +264,7 @@ public boolean create(String indexName, private Optional indexMapping(IndexSet indexSet) { try { return Optional.of(indexMappingFactory.createIndexMapping(indexSet.getConfig())); - }catch (IgnoreIndexTemplate e){ + } catch (IgnoreIndexTemplate e) { return Optional.empty(); } }