Skip to content

Commit bd8da2a

Browse files
Fail with correct error if first backing index exists when auto creating data stream (elastic#62825)
Today if a data stream is auto created, but an index with same name as the first backing index already exists then internally that error is ignored, which then result that later in the execution of a bulk request, the bulk item fails due to that the data stream hasn't been auto created. This situation can only occur if an index with same is created that will be the backing index of a data stream prior to the creation of the data stream. Co-authored-by: Dan Hermann <[email protected]>
1 parent be0dd12 commit bd8da2a

File tree

2 files changed

+60
-1
lines changed

2 files changed

+60
-1
lines changed

server/src/main/java/org/elasticsearch/cluster/metadata/MetadataCreateDataStreamService.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
import org.apache.logging.log4j.LogManager;
2222
import org.apache.logging.log4j.Logger;
23+
import org.elasticsearch.ElasticsearchStatusException;
2324
import org.elasticsearch.ResourceAlreadyExistsException;
2425
import org.elasticsearch.action.ActionListener;
2526
import org.elasticsearch.action.admin.indices.create.CreateIndexClusterStateUpdateRequest;
@@ -38,6 +39,7 @@
3839
import org.elasticsearch.common.xcontent.ObjectPath;
3940
import org.elasticsearch.index.mapper.MapperService;
4041
import org.elasticsearch.index.mapper.MetadataFieldMapper;
42+
import org.elasticsearch.rest.RestStatus;
4143
import org.elasticsearch.threadpool.ThreadPool;
4244

4345
import java.io.IOException;
@@ -143,7 +145,15 @@ static ClusterState createDataStream(MetadataCreateIndexService metadataCreateIn
143145
new CreateIndexClusterStateUpdateRequest("initialize_data_stream", firstBackingIndexName, firstBackingIndexName)
144146
.dataStreamName(request.name)
145147
.settings(Settings.builder().put("index.hidden", true).build());
146-
currentState = metadataCreateIndexService.applyCreateIndexRequest(currentState, createIndexRequest, false);
148+
try {
149+
currentState = metadataCreateIndexService.applyCreateIndexRequest(currentState, createIndexRequest, false);
150+
} catch (ResourceAlreadyExistsException e) {
151+
// Rethrow as ElasticsearchStatusException, so that bulk transport action doesn't ignore it during
152+
// auto index/data stream creation.
153+
// (otherwise bulk execution fails later, because data stream will also not have been created)
154+
throw new ElasticsearchStatusException("data stream could not be created because backing index [{}] already exists",
155+
RestStatus.BAD_REQUEST, e, firstBackingIndexName);
156+
}
147157
IndexMetadata firstBackingIndex = currentState.metadata().index(firstBackingIndexName);
148158
assert firstBackingIndex != null;
149159
assert firstBackingIndex.mapping() != null : "no mapping found for backing index [" + firstBackingIndexName + "]";

x-pack/plugin/data-streams/src/internalClusterTest/java/org/elasticsearch/datastreams/DataStreamIT.java

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
*/
66
package org.elasticsearch.datastreams;
77

8+
import org.elasticsearch.ElasticsearchStatusException;
89
import org.elasticsearch.ExceptionsHelper;
910
import org.elasticsearch.action.ActionRequestBuilder;
1011
import org.elasticsearch.action.DocWriteRequest;
@@ -1044,6 +1045,54 @@ public void testAutoCreateV1TemplateNoDataStream() {
10441045
assertThat(getIndexResponse.getSettings().get("logs-foobar").get(IndexMetadata.SETTING_NUMBER_OF_REPLICAS), equalTo("0"));
10451046
}
10461047

1048+
public void testCreatingDataStreamAndFirstBackingIndexExistsFails() throws Exception {
1049+
String dataStreamName = "logs-foobar";
1050+
String backingIndex = DataStream.getDefaultBackingIndexName(dataStreamName, 1);
1051+
1052+
createIndex(backingIndex);
1053+
putComposableIndexTemplate("id", List.of("logs-*"));
1054+
CreateDataStreamAction.Request createDataStreamRequest = new CreateDataStreamAction.Request(dataStreamName);
1055+
Exception e = expectThrows(
1056+
ElasticsearchStatusException.class,
1057+
() -> client().execute(CreateDataStreamAction.INSTANCE, createDataStreamRequest).actionGet()
1058+
);
1059+
assertThat(e.getMessage(), equalTo("data stream could not be created because backing index [" + backingIndex + "] already exists"));
1060+
}
1061+
1062+
public void testAutoCreatingDataStreamAndFirstBackingIndexExistsFails() throws Exception {
1063+
String dataStreamName = "logs-foobar";
1064+
String backingIndex = DataStream.getDefaultBackingIndexName(dataStreamName, 1);
1065+
1066+
createIndex(backingIndex);
1067+
putComposableIndexTemplate("id", List.of("logs-*"));
1068+
1069+
IndexRequest indexRequest = new IndexRequest(dataStreamName).opType("create")
1070+
.source("{\"@timestamp\": \"2020-12-12\"}", XContentType.JSON);
1071+
Exception e = expectThrows(ElasticsearchStatusException.class, () -> client().index(indexRequest).actionGet());
1072+
assertThat(e.getMessage(), equalTo("data stream could not be created because backing index [" + backingIndex + "] already exists"));
1073+
}
1074+
1075+
public void testCreatingDataStreamAndBackingIndexExistsFails() throws Exception {
1076+
String dataStreamName = "logs-foobar";
1077+
String backingIndex = DataStream.getDefaultBackingIndexName(dataStreamName, 2);
1078+
1079+
createIndex(backingIndex);
1080+
putComposableIndexTemplate("id", List.of("logs-*"));
1081+
1082+
CreateDataStreamAction.Request createDataStreamRequest = new CreateDataStreamAction.Request(dataStreamName);
1083+
Exception e = expectThrows(
1084+
IllegalStateException.class,
1085+
() -> client().execute(CreateDataStreamAction.INSTANCE, createDataStreamRequest).actionGet()
1086+
);
1087+
assertThat(
1088+
e.getMessage(),
1089+
equalTo(
1090+
"data stream [logs-foobar] could create backing indices that conflict with 1 "
1091+
+ "existing index(s) or alias(s) including '.ds-logs-foobar-000002'"
1092+
)
1093+
);
1094+
}
1095+
10471096
private static void verifyResolvability(String dataStream, ActionRequestBuilder<?, ?> requestBuilder, boolean fail) {
10481097
verifyResolvability(dataStream, requestBuilder, fail, 0);
10491098
}

0 commit comments

Comments
 (0)