Skip to content

Commit 6830b7a

Browse files
authored
[7.x] Migrate aliased indices to data stream (#66176)
1 parent 22bdecd commit 6830b7a

File tree

16 files changed

+1088
-47
lines changed

16 files changed

+1088
-47
lines changed

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,12 @@ public ComposableIndexTemplate(List<String> indexPatterns, @Nullable Template te
112112
this(indexPatterns, template, componentTemplates, priority, version, metadata, null, null);
113113
}
114114

115+
public ComposableIndexTemplate(List<String> indexPatterns, @Nullable Template template, @Nullable List<String> componentTemplates,
116+
@Nullable Long priority, @Nullable Long version, @Nullable Map<String, Object> metadata,
117+
@Nullable DataStreamTemplate dataStreamTemplate) {
118+
this(indexPatterns, template, componentTemplates, priority, version, metadata, dataStreamTemplate, null);
119+
}
120+
115121
public ComposableIndexTemplate(List<String> indexPatterns, @Nullable Template template, @Nullable List<String> componentTemplates,
116122
@Nullable Long priority, @Nullable Long version, @Nullable Map<String, Object> metadata,
117123
@Nullable DataStreamTemplate dataStreamTemplate, @Nullable Boolean allowAutoCreate) {

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,6 @@ public DataStream(String name, TimestampField timeStampField, List<Index> indice
7171
this.hidden = hidden;
7272
this.replicated = replicated;
7373
assert indices.size() > 0;
74-
assert indices.get(indices.size() - 1).getName().equals(getDefaultBackingIndexName(name, generation));
7574
}
7675

7776
public DataStream(String name, TimestampField timeStampField, List<Index> indices) {
@@ -94,6 +93,10 @@ public long getGeneration() {
9493
return generation;
9594
}
9695

96+
public Index getWriteIndex() {
97+
return indices.get(indices.size() - 1);
98+
}
99+
97100
@Nullable
98101
public Map<String, Object> getMetadata() {
99102
return metadata;

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

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@
3131
import java.util.Objects;
3232
import java.util.stream.Collectors;
3333

34-
import static org.elasticsearch.cluster.metadata.DataStream.getDefaultBackingIndexName;
3534
import static org.elasticsearch.cluster.metadata.IndexMetadata.INDEX_HIDDEN_SETTING;
3635
import static org.elasticsearch.common.collect.List.copyOf;
3736

@@ -309,7 +308,6 @@ public DataStream(org.elasticsearch.cluster.metadata.DataStream dataStream, List
309308
this.dataStream = dataStream;
310309
this.dataStreamIndices = copyOf(dataStreamIndices);
311310
this.writeIndex = dataStreamIndices.get(dataStreamIndices.size() - 1);
312-
assert writeIndex.getIndex().getName().equals(getDefaultBackingIndexName(dataStream.getName(), dataStream.getGeneration()));
313311
}
314312

315313
@Override

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

Lines changed: 63 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -33,21 +33,24 @@
3333
import org.elasticsearch.cluster.ack.ClusterStateUpdateRequest;
3434
import org.elasticsearch.cluster.service.ClusterService;
3535
import org.elasticsearch.common.Priority;
36+
import org.elasticsearch.common.Strings;
3637
import org.elasticsearch.common.settings.Settings;
3738
import org.elasticsearch.common.unit.TimeValue;
3839
import org.elasticsearch.common.xcontent.NamedXContentRegistry;
3940
import org.elasticsearch.common.xcontent.ObjectPath;
41+
import org.elasticsearch.index.Index;
4042
import org.elasticsearch.index.mapper.MapperService;
4143
import org.elasticsearch.index.mapper.MetadataFieldMapper;
4244
import org.elasticsearch.rest.RestStatus;
4345
import org.elasticsearch.threadpool.ThreadPool;
4446

4547
import java.io.IOException;
46-
import java.util.Collections;
47-
import java.util.HashMap;
48+
import java.util.List;
4849
import java.util.Locale;
4950
import java.util.Map;
51+
import java.util.Objects;
5052
import java.util.concurrent.atomic.AtomicReference;
53+
import java.util.stream.Collectors;
5154

5255
public class MetadataCreateDataStreamService {
5356

@@ -116,54 +119,81 @@ public CreateDataStreamClusterStateUpdateRequest(String name,
116119
static ClusterState createDataStream(MetadataCreateIndexService metadataCreateIndexService,
117120
ClusterState currentState,
118121
CreateDataStreamClusterStateUpdateRequest request) throws Exception {
122+
return createDataStream(metadataCreateIndexService, currentState, request.name, org.elasticsearch.common.collect.List.of(), null);
123+
}
124+
125+
/**
126+
* Creates a data stream with the specified properties.
127+
*
128+
* @param metadataCreateIndexService Used if a new write index must be created
129+
* @param currentState Cluster state
130+
* @param dataStreamName Name of the data stream
131+
* @param backingIndices List of backing indices. May be empty
132+
* @param writeIndex Write index for the data stream. If null, a new write index will be created.
133+
* @return Cluster state containing the new data stream
134+
*/
135+
static ClusterState createDataStream(MetadataCreateIndexService metadataCreateIndexService,
136+
ClusterState currentState,
137+
String dataStreamName,
138+
List<IndexMetadata> backingIndices,
139+
IndexMetadata writeIndex) throws Exception
140+
{
119141
if (currentState.nodes().getMinNodeVersion().before(Version.V_7_9_0)) {
120142
throw new IllegalStateException("data streams require minimum node version of " + Version.V_7_9_0);
121143
}
122-
123-
if (currentState.metadata().dataStreams().containsKey(request.name)) {
124-
throw new ResourceAlreadyExistsException("data_stream [" + request.name + "] already exists");
144+
if (writeIndex == null) {
145+
Objects.requireNonNull(metadataCreateIndexService);
146+
}
147+
Objects.requireNonNull(currentState);
148+
Objects.requireNonNull(backingIndices);
149+
if (currentState.metadata().dataStreams().containsKey(dataStreamName)) {
150+
throw new ResourceAlreadyExistsException("data_stream [" + dataStreamName + "] already exists");
125151
}
126152

127-
MetadataCreateIndexService.validateIndexOrAliasName(request.name,
153+
MetadataCreateIndexService.validateIndexOrAliasName(dataStreamName,
128154
(s1, s2) -> new IllegalArgumentException("data_stream [" + s1 + "] " + s2));
129155

130-
if (request.name.toLowerCase(Locale.ROOT).equals(request.name) == false) {
131-
throw new IllegalArgumentException("data_stream [" + request.name + "] must be lowercase");
156+
if (dataStreamName.toLowerCase(Locale.ROOT).equals(dataStreamName) == false) {
157+
throw new IllegalArgumentException("data_stream [" + dataStreamName + "] must be lowercase");
132158
}
133-
if (request.name.startsWith(DataStream.BACKING_INDEX_PREFIX)) {
134-
throw new IllegalArgumentException("data_stream [" + request.name + "] must not start with '"
159+
if (dataStreamName.startsWith(DataStream.BACKING_INDEX_PREFIX)) {
160+
throw new IllegalArgumentException("data_stream [" + dataStreamName + "] must not start with '"
135161
+ DataStream.BACKING_INDEX_PREFIX + "'");
136162
}
137163

138-
ComposableIndexTemplate template = lookupTemplateForDataStream(request.name, currentState.metadata());
139-
140-
String firstBackingIndexName = DataStream.getDefaultBackingIndexName(request.name, 1);
141-
CreateIndexClusterStateUpdateRequest createIndexRequest =
142-
new CreateIndexClusterStateUpdateRequest("initialize_data_stream", firstBackingIndexName, firstBackingIndexName)
143-
.dataStreamName(request.name)
144-
.settings(Settings.builder().put("index.hidden", true).build());
145-
try {
146-
currentState = metadataCreateIndexService.applyCreateIndexRequest(currentState, createIndexRequest, false);
147-
} catch (ResourceAlreadyExistsException e) {
148-
// Rethrow as ElasticsearchStatusException, so that bulk transport action doesn't ignore it during
149-
// auto index/data stream creation.
150-
// (otherwise bulk execution fails later, because data stream will also not have been created)
151-
throw new ElasticsearchStatusException("data stream could not be created because backing index [{}] already exists",
152-
RestStatus.BAD_REQUEST, e, firstBackingIndexName);
164+
ComposableIndexTemplate template = lookupTemplateForDataStream(dataStreamName, currentState.metadata());
165+
166+
if (writeIndex == null) {
167+
String firstBackingIndexName = DataStream.getDefaultBackingIndexName(dataStreamName, 1);
168+
CreateIndexClusterStateUpdateRequest createIndexRequest =
169+
new CreateIndexClusterStateUpdateRequest("initialize_data_stream", firstBackingIndexName, firstBackingIndexName)
170+
.dataStreamName(dataStreamName)
171+
.settings(Settings.builder().put("index.hidden", true).build());
172+
try {
173+
currentState = metadataCreateIndexService.applyCreateIndexRequest(currentState, createIndexRequest, false);
174+
} catch (ResourceAlreadyExistsException e) {
175+
// Rethrow as ElasticsearchStatusException, so that bulk transport action doesn't ignore it during
176+
// auto index/data stream creation.
177+
// (otherwise bulk execution fails later, because data stream will also not have been created)
178+
throw new ElasticsearchStatusException("data stream could not be created because backing index [{}] already exists",
179+
RestStatus.BAD_REQUEST, e, firstBackingIndexName);
180+
}
181+
writeIndex = currentState.metadata().index(firstBackingIndexName);
153182
}
154-
IndexMetadata firstBackingIndex = currentState.metadata().index(firstBackingIndexName);
155-
assert firstBackingIndex != null;
156-
assert firstBackingIndex.mapping() != null : "no mapping found for backing index [" + firstBackingIndexName + "]";
183+
assert writeIndex != null;
184+
assert writeIndex.mapping() != null : "no mapping found for backing index [" + writeIndex.getIndex().getName() + "]";
157185

158186
String fieldName = template.getDataStreamTemplate().getTimestampField();
159187
DataStream.TimestampField timestampField = new DataStream.TimestampField(fieldName);
188+
List<Index> dsBackingIndices = backingIndices.stream().map(IndexMetadata::getIndex).collect(Collectors.toList());
189+
dsBackingIndices.add(writeIndex.getIndex());
160190
boolean hidden = template.getDataStreamTemplate().isHidden();
161-
DataStream newDataStream =
162-
new DataStream(request.name, timestampField,
163-
Collections.singletonList(firstBackingIndex.getIndex()), 1L,
164-
template.metadata() != null ? Collections.unmodifiableMap(new HashMap<>(template.metadata())) : null, hidden, false);
191+
DataStream newDataStream = new DataStream(dataStreamName, timestampField, dsBackingIndices, 1L,
192+
template.metadata() != null ? org.elasticsearch.common.collect.Map.copyOf(template.metadata()) : null, hidden, false);
165193
Metadata.Builder builder = Metadata.builder(currentState.metadata()).put(newDataStream);
166-
logger.info("adding data stream [{}]", request.name);
194+
logger.info("adding data stream [{}] with write index [{}] and backing indices [{}]", dataStreamName,
195+
writeIndex.getIndex().getName(),
196+
Strings.arrayToCommaDelimitedString(backingIndices.stream().map(i -> i.getIndex().getName()).toArray()));
167197
return ClusterState.builder(currentState).metadata(builder).build();
168198
}
169199

0 commit comments

Comments
 (0)