Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a template parameter to override auto_create_index value #61858

Merged
merged 78 commits into from
Oct 26, 2020
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
78 commits
Select commit Hold shift + click to select a range
ee50924
Override auto-create index behaviour via a template flag
pugnascotia Aug 3, 2020
f62c83b
WIP - trying to test watcher
pugnascotia Aug 4, 2020
097d9f5
Merge remote-tracking branch 'upstream/master' into 20640-auto-create…
pugnascotia Sep 1, 2020
3bb580c
Fixes
pugnascotia Sep 2, 2020
42cfc00
Remove logging
pugnascotia Sep 2, 2020
8c17371
Merge remote-tracking branch 'upstream/master' into 20640-auto-create…
pugnascotia Sep 2, 2020
9a1e10a
Merge remote-tracking branch 'upstream/master' into 20640-auto-create…
pugnascotia Sep 4, 2020
961cfcf
Use AutoCreateIndex in AutoCreateAction
pugnascotia Sep 9, 2020
41fdcb3
Imports
pugnascotia Sep 10, 2020
2228033
Merge remote-tracking branch 'upstream/master' into 20640-auto-create…
pugnascotia Sep 10, 2020
b00297e
Fixes
pugnascotia Sep 14, 2020
ad5021d
Merge remote-tracking branch 'upstream/master' into 20640-auto-create…
pugnascotia Sep 14, 2020
ad9e699
Fix compile error
pugnascotia Sep 14, 2020
c42e3ce
Tweak ComposableIndexTemplate serialisation under code changes land i…
pugnascotia Sep 14, 2020
6a689b2
Fix auto create index bug
pugnascotia Sep 16, 2020
f81a510
Merge remote-tracking branch 'upstream/master' into 20640-auto-create…
pugnascotia Sep 16, 2020
2d54d2c
Test fix
pugnascotia Sep 16, 2020
85abcbc
Handle null Boolean
pugnascotia Sep 16, 2020
eb299a0
Merge remote-tracking branch 'upstream/master' into 20640-auto-create…
pugnascotia Sep 18, 2020
a3e3691
Imports
pugnascotia Sep 18, 2020
9421140
Checkstyle
pugnascotia Sep 18, 2020
ebb42d4
Tweaks
pugnascotia Sep 18, 2020
a93cfb2
Merge remote-tracking branch 'upstream/master' into 20640-auto-create…
pugnascotia Sep 18, 2020
bfe8c8c
Post-merge fix
pugnascotia Sep 18, 2020
2694fb2
Update synthentics template to add allow_auto_create
pugnascotia Sep 18, 2020
5d5eeb4
Merge remote-tracking branch 'upstream/master' into 20640-auto-create…
pugnascotia Sep 22, 2020
39abb38
Address review feedback
pugnascotia Sep 22, 2020
4b9034a
Address review feedback
pugnascotia Sep 22, 2020
ce8c2ed
Merge remote-tracking branch 'upstream/master' into 20640-auto-create…
pugnascotia Sep 22, 2020
2e9a4c7
Specify the same version for ser/deser
pugnascotia Sep 22, 2020
d5db431
Merge remote-tracking branch 'upstream/master' into 20640-auto-create…
pugnascotia Sep 24, 2020
1d07709
Fix stupid typo
pugnascotia Sep 24, 2020
36b9ca8
Merge remote-tracking branch 'upstream/master' into 20640-auto-create…
pugnascotia Sep 28, 2020
93e2440
Address review comments
pugnascotia Sep 28, 2020
4a2e64c
Increment some template versions due to the new setting
pugnascotia Sep 28, 2020
82ad6e4
Add Java REST tests for auto-creating indices
pugnascotia Sep 28, 2020
6022b3c
Checkstyle
pugnascotia Sep 28, 2020
41b2fc6
Merge remote-tracking branch 'upstream/master' into 20640-auto-create…
pugnascotia Oct 12, 2020
6127caf
Update component template docs
pugnascotia Oct 12, 2020
9d6b6cf
Checkstyle
pugnascotia Oct 12, 2020
c0394e4
Docs tweak
pugnascotia Oct 13, 2020
cbfbb98
Merge remote-tracking branch 'upstream/master' into 20640-auto-create…
pugnascotia Oct 13, 2020
383d6ff
Merge remote-tracking branch 'upstream/master' into 20640-auto-create…
pugnascotia Oct 19, 2020
61ab28e
Make data stream subject to auto_create_index
pugnascotia Oct 19, 2020
6c4c817
Add tests for auto-creating data streams
pugnascotia Oct 19, 2020
ed692c7
Formatting
pugnascotia Oct 19, 2020
e8617b6
Merge branch 'master' into 20640-auto-create-templates
elasticmachine Oct 19, 2020
4f051af
Fix max/min aggs for unsigned_long (#63904)
mayya-sharipova Oct 19, 2020
44d7d66
Add APM configuration index to Kibana system indices (#63756)
williamrandolph Oct 19, 2020
e145266
[ML] Rename evaluation metric result fields to value (#63809)
dimitris-athanasiou Oct 20, 2020
9e8221a
Update gradle wrapper to Gradle 6.7 (#62386)
breskeby Oct 20, 2020
dd7a22f
Add snapshot shard size based test in DiskThresholdDeciderTests (#63546)
tlrx Oct 20, 2020
cfca1e4
DocumentMapperParser to no longer depend directly on MapperService (#…
javanna Oct 20, 2020
85c0b54
Composite aggregation must check live docs when the index is sorted (…
jimczi Oct 20, 2020
0204f0a
Fix build tools integTest failure after vault update (#63914)
breskeby Oct 20, 2020
eae0eaa
Upgrade to lucene-8.7.0-snapshot-72d8528c3a6 (#63912)
iverase Oct 20, 2020
d9aea1c
[ML] fix inference binary classification predication label and featur…
benwtrent Oct 20, 2020
13ef3ab
Move clone snapshot API page. (#63902)
Oct 20, 2020
4bdc322
Remove two redundant DocumentMapper methods (#63922)
javanna Oct 20, 2020
c3d1981
make sure AggregationTest creates reduced aggregations. (#63931)
iverase Oct 20, 2020
ae05665
[ML] adding new flag exclude_generated that removes generated fields …
benwtrent Oct 20, 2020
2cd82f2
[Transform] add new exclude_generated flag to GET transform (#63093)
benwtrent Oct 20, 2020
8bf7976
Gradle - compatible REST test plugin - adopt bwc artifact (#63629)
jakelandis Oct 20, 2020
b4cc55c
Remove documentMapperParser method from MapperService (#63938)
javanna Oct 20, 2020
1545c0a
Minor FieldTypeLookup tweaks (#63944)
javanna Oct 20, 2020
55172b6
[Transform] add support for unsigned_long data type (#63940)
Oct 20, 2020
9a9b96b
Make agg test less confusing (#63952)
nik9000 Oct 20, 2020
7db889c
Add a test for regex usage to runtime fields (#63951)
nik9000 Oct 20, 2020
70f758e
[ML] Extend default evaluation metrics to all available (#63939)
dimitris-athanasiou Oct 21, 2020
1376afd
geo_point runtime field implementation (#63164)
iverase Oct 21, 2020
dec6ea9
Mute CoreValuesSourceTypeTests.testDatePrepareRoundingWithDocs (#63970)
javanna Oct 21, 2020
00b0bdf
Handle range query edge case (#63397)
Oct 21, 2020
473975c
Mute DatafeedJobsIT#testDatafeedTimingStats_DatafeedRecreated (#63974)
javanna Oct 21, 2020
f45ea30
Mute FieldSortIT#testCastDate (#63972)
javanna Oct 21, 2020
0482f5c
Only subject data streams to allow_auto_create, not auto_create_index
pugnascotia Oct 21, 2020
421679d
Merge remote-tracking branch 'upstream/master' into 20640-auto-create…
pugnascotia Oct 21, 2020
6bd5456
Tweak docs
pugnascotia Oct 22, 2020
0fd0f84
Merge branch 'master' into 20640-auto-create-templates
elasticmachine Oct 22, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -1579,7 +1579,7 @@ public void testDataStreams() throws Exception {
CompressedXContent mappings = new CompressedXContent("{\"properties\":{\"@timestamp\":{\"type\":\"date\"}}}");
Template template = new Template(null, mappings, null);
ComposableIndexTemplate indexTemplate = new ComposableIndexTemplate(Collections.singletonList(dataStreamName), template,
Collections.emptyList(), 1L, 1L, new HashMap<>(), new ComposableIndexTemplate.DataStreamTemplate());
Collections.emptyList(), 1L, 1L, new HashMap<>(), new ComposableIndexTemplate.DataStreamTemplate(), null);
PutComposableIndexTemplateRequest putComposableIndexTemplateRequest =
new PutComposableIndexTemplateRequest().name("ds-template").create(true).indexTemplate(indexTemplate);
AcknowledgedResponse response = execute(putComposableIndexTemplateRequest,
Expand Down Expand Up @@ -1658,7 +1658,7 @@ public void testIndexTemplates() throws Exception {
Template template = new Template(settings, mappings, Map.of("alias", alias));
List<String> pattern = List.of("pattern");
ComposableIndexTemplate indexTemplate =
new ComposableIndexTemplate(pattern, template, Collections.emptyList(), 1L, 1L, new HashMap<>(), null);
new ComposableIndexTemplate(pattern, template, Collections.emptyList(), 1L, 1L, new HashMap<>(), null, null);
PutComposableIndexTemplateRequest putComposableIndexTemplateRequest =
new PutComposableIndexTemplateRequest().name(templateName).create(true).indexTemplate(indexTemplate);

Expand Down Expand Up @@ -1705,7 +1705,7 @@ public void testSimulateIndexTemplate() throws Exception {
Template template = new Template(settings, mappings, Map.of("alias", alias));
List<String> pattern = List.of("pattern");
ComposableIndexTemplate indexTemplate =
new ComposableIndexTemplate(pattern, template, Collections.emptyList(), 1L, 1L, new HashMap<>(), null);
new ComposableIndexTemplate(pattern, template, Collections.emptyList(), 1L, 1L, new HashMap<>(), null, null);
PutComposableIndexTemplateRequest putComposableIndexTemplateRequest =
new PutComposableIndexTemplateRequest().name(templateName).create(true).indexTemplate(indexTemplate);

Expand All @@ -1716,7 +1716,7 @@ public void testSimulateIndexTemplate() throws Exception {
SimulateIndexTemplateRequest simulateIndexTemplateRequest = new SimulateIndexTemplateRequest("pattern");
AliasMetadata simulationAlias = AliasMetadata.builder("simulation-alias").writeIndex(true).build();
ComposableIndexTemplate simulationTemplate = new ComposableIndexTemplate(pattern, new Template(null, null,
Map.of("simulation-alias", simulationAlias)), Collections.emptyList(), 2L, 1L, new HashMap<>(), null);
Map.of("simulation-alias", simulationAlias)), Collections.emptyList(), 2L, 1L, new HashMap<>(), null, null);
PutComposableIndexTemplateRequest newIndexTemplateReq =
new PutComposableIndexTemplateRequest().name("used-for-simulation").create(true).indexTemplate(indexTemplate);
newIndexTemplateReq.indexTemplate(simulationTemplate);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,6 @@ private static ComposableIndexTemplate randomIndexTemplate() {
if (randomBoolean()) {
dataStreamTemplate = new ComposableIndexTemplate.DataStreamTemplate();
}
return new ComposableIndexTemplate(patterns, randomTemplate(), composedOf, priority, version, meta, dataStreamTemplate);
return new ComposableIndexTemplate(patterns, randomTemplate(), composedOf, priority, version, meta, dataStreamTemplate, null);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ public void testUsageOfDataStreamFails() throws IOException {
Exception expectedException = expectThrows(Exception.class, () -> ComposableIndexTemplate.parse(parser));

ComposableIndexTemplate template = new ComposableIndexTemplate(List.of("logs-*-*"), null, null, null, null,
null, new ComposableIndexTemplate.DataStreamTemplate());
null, new ComposableIndexTemplate.DataStreamTemplate(), null);
Exception e = expectThrows(IllegalArgumentException.class, () -> client().execute(PutComposableIndexTemplateAction.INSTANCE,
new PutComposableIndexTemplateAction.Request("my-it").indexTemplate(template)).actionGet());
Exception actualException = (Exception) e.getCause();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -216,73 +216,70 @@ protected void doInternalExecute(Task task, BulkRequest bulkRequest, ActionListe
return;
}

if (needToCheck()) {
// Attempt to create all the indices that we're going to need during the bulk before we start.
// Step 1: collect all the indices in the request
final Map<String, Boolean> indices = bulkRequest.requests.stream()
// delete requests should not attempt to create the index (if the index does not
// exists), unless an external versioning is used
.filter(request -> request.opType() != DocWriteRequest.OpType.DELETE
|| request.versionType() == VersionType.EXTERNAL
|| request.versionType() == VersionType.EXTERNAL_GTE)
.collect(Collectors.toMap(DocWriteRequest::index, DocWriteRequest::isRequireAlias, (v1, v2) -> v1 || v2));
/* Step 2: filter that to indices that don't exist and we can create. At the same time build a map of indices we can't create
* that we'll use when we try to run the requests. */
final Map<String, IndexNotFoundException> indicesThatCannotBeCreated = new HashMap<>();
Set<String> autoCreateIndices = new HashSet<>();
ClusterState state = clusterService.state();
for (Map.Entry<String, Boolean> indexAndFlag : indices.entrySet()) {
boolean shouldAutoCreate;
final String index = indexAndFlag.getKey();
try {
shouldAutoCreate = shouldAutoCreate(index, state);
} catch (IndexNotFoundException e) {
shouldAutoCreate = false;
indicesThatCannotBeCreated.put(index, e);
}
// We should only auto create if we are not requiring it to be an alias
if (shouldAutoCreate && (indexAndFlag.getValue() == false)) {
autoCreateIndices.add(index);
}
// Attempt to create all the indices that we're going to need during the bulk before we start.
// Step 1: collect all the indices in the request
final Map<String, Boolean> indices = bulkRequest.requests.stream()
// delete requests should not attempt to create the index (if the index does not
// exists), unless an external versioning is used
.filter(request -> request.opType() != DocWriteRequest.OpType.DELETE
|| request.versionType() == VersionType.EXTERNAL
|| request.versionType() == VersionType.EXTERNAL_GTE)
.collect(Collectors.toMap(DocWriteRequest::index, DocWriteRequest::isRequireAlias, (v1, v2) -> v1 || v2));
/* Step 2: filter that to indices that don't exist and we can create. At the same time build a map of indices we can't create
* that we'll use when we try to run the requests. */
final Map<String, IndexNotFoundException> indicesThatCannotBeCreated = new HashMap<>();
Set<String> autoCreateIndices = new HashSet<>();
ClusterState state = clusterService.state();
for (Map.Entry<String, Boolean> indexAndFlag : indices.entrySet()) {
boolean shouldAutoCreate;
final String index = indexAndFlag.getKey();
try {
shouldAutoCreate = shouldAutoCreate(index, state);
} catch (IndexNotFoundException e) {
shouldAutoCreate = false;
indicesThatCannotBeCreated.put(index, e);
}
// Step 3: create all the indices that are missing, if there are any missing. start the bulk after all the creates come back.
if (autoCreateIndices.isEmpty()) {
executeBulk(task, bulkRequest, startTime, listener, responses, indicesThatCannotBeCreated);
} else {
final AtomicInteger counter = new AtomicInteger(autoCreateIndices.size());
for (String index : autoCreateIndices) {
createIndex(index, bulkRequest.timeout(), minNodeVersion, new ActionListener<>() {
@Override
public void onResponse(CreateIndexResponse result) {
if (counter.decrementAndGet() == 0) {
threadPool.executor(ThreadPool.Names.WRITE).execute(
() -> executeBulk(task, bulkRequest, startTime, listener, responses, indicesThatCannotBeCreated));
}
// We should only auto create if we are not requiring it to be an alias
if (shouldAutoCreate && (indexAndFlag.getValue() == false)) {
autoCreateIndices.add(index);
}
}

// Step 3: create all the indices that are missing, if there are any missing. start the bulk after all the creates come back.
if (autoCreateIndices.isEmpty()) {
executeBulk(task, bulkRequest, startTime, listener, responses, indicesThatCannotBeCreated);
} else {
final AtomicInteger counter = new AtomicInteger(autoCreateIndices.size());
for (String index : autoCreateIndices) {
createIndex(index, bulkRequest.timeout(), minNodeVersion, new ActionListener<>() {
@Override
public void onResponse(CreateIndexResponse result) {
if (counter.decrementAndGet() == 0) {
threadPool.executor(ThreadPool.Names.WRITE).execute(
() -> executeBulk(task, bulkRequest, startTime, listener, responses, indicesThatCannotBeCreated));
}
}

@Override
public void onFailure(Exception e) {
if (!(ExceptionsHelper.unwrapCause(e) instanceof ResourceAlreadyExistsException)) {
// fail all requests involving this index, if create didn't work
for (int i = 0; i < bulkRequest.requests.size(); i++) {
DocWriteRequest<?> request = bulkRequest.requests.get(i);
if (request != null && setResponseFailureIfIndexMatches(responses, i, request, index, e)) {
bulkRequest.requests.set(i, null);
}
@Override
public void onFailure(Exception e) {
if (!(ExceptionsHelper.unwrapCause(e) instanceof ResourceAlreadyExistsException)) {
// fail all requests involving this index, if create didn't work
for (int i = 0; i < bulkRequest.requests.size(); i++) {
DocWriteRequest<?> request = bulkRequest.requests.get(i);
if (request != null && setResponseFailureIfIndexMatches(responses, i, request, index, e)) {
bulkRequest.requests.set(i, null);
}
}
if (counter.decrementAndGet() == 0) {
executeBulk(task, bulkRequest, startTime, ActionListener.wrap(listener::onResponse, inner -> {
inner.addSuppressed(e);
listener.onFailure(inner);
}), responses, indicesThatCannotBeCreated);
}
}
});
}
if (counter.decrementAndGet() == 0) {
executeBulk(task, bulkRequest, startTime, ActionListener.wrap(listener::onResponse, inner -> {
inner.addSuppressed(e);
listener.onFailure(inner);
}), responses, indicesThatCannotBeCreated);
}
}
});
}
} else {
executeBulk(task, bulkRequest, startTime, listener, responses, emptyMap());
}
}

Expand Down Expand Up @@ -336,10 +333,6 @@ static void prohibitCustomRoutingOnDataStream(DocWriteRequest<?> writeRequest, M
}
}

boolean needToCheck() {
return autoCreateIndex.needToCheck();
}

boolean shouldAutoCreate(String index, ClusterState state) {
return autoCreateIndex.shouldAutoCreate(index, state);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@
package org.elasticsearch.action.support;

import org.elasticsearch.cluster.ClusterState;
import org.elasticsearch.cluster.metadata.ComposableIndexTemplate;
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
import org.elasticsearch.cluster.metadata.Metadata;
import org.elasticsearch.cluster.metadata.MetadataIndexTemplateService;
import org.elasticsearch.common.Booleans;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.collect.Tuple;
Expand All @@ -39,7 +42,6 @@
* a write operation is about to happen in a non existing index.
*/
public final class AutoCreateIndex {

public static final Setting<AutoCreate> AUTO_CREATE_INDEX_SETTING =
new Setting<>("action.auto_create_index", "true", AutoCreate::new, Property.NodeScope, Setting.Property.Dynamic);

Expand All @@ -52,13 +54,6 @@ public AutoCreateIndex(Settings settings, ClusterSettings clusterSettings, Index
clusterSettings.addSettingsUpdateConsumer(AUTO_CREATE_INDEX_SETTING, this::setAutoCreate);
}

/**
* Do we really need to check if an index should be auto created?
*/
public boolean needToCheck() {
return this.autoCreate.autoCreateIndex;
}

/**
* Should the index be auto created?
* @throws IndexNotFoundException if the index doesn't exist and shouldn't be auto created
Expand All @@ -67,6 +62,13 @@ public boolean shouldAutoCreate(String index, ClusterState state) {
if (resolver.hasIndexAbstraction(index, state)) {
return false;
}

// Templates can override the AUTO_CREATE_INDEX_SETTING setting
final ComposableIndexTemplate template = findTemplate(index, state.metadata());
if (template != null && template.getAllowAutoCreate()) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We talked about the auto create index logic and the allow auto create template flag yesterday. This logic is invoked from the bulk action and is evaluated on the coordinating node. While the decision the auto create an index or data stream is done in the AutoCreateAction on the elected master node.

The reason why we decided to make the decision to auto create an index or data stream in the AutoCreateAction and not here is, because if for some reason a node is lacking behind and doesn't have all the templates then an index is auto created instead of a data stream. Fixing the erroneous situation requires a lot of manual work, hence we moved making this decision to elected master node.

The question is whether the auto create index check (with this enhancement) should be moved to AutoCreateAction class too, so that all the decisions are made on the elected master node.

I'm currently thinking the following:

  • In the case a coordinating node doesn't have the latest action.auto_create_index setting values or composable index templates then the worst that can happen is a new few write requests fail, because the target index doesn't exist.
  • Currently if action.auto_create_index is set to false then also data streams are no longer created. I think this is a bug, because the name of the setting implies auto creation of indices only.
  • If this logic is moved to AutoCreateAction class then the overhead is that remote requests are made to the elected master node in the case target indices don't exist. Most requests will index into an existing data stream or index, so the cost is acceptable.
  • I remember that we eventually want to deprecate and remove the action.auto_create_index setting, but I may be mistaken.

If we are going to remove action.auto_create_index with the new allow auto create template flag then I think let's keep it here? And then maybe also add logic here that if a non existing index matches with a template that auto create data streams then checking the action.auto_create_index setting should be ignored?

return true;
}

// One volatile read, so that all checks are done against the same instance:
final AutoCreate autoCreate = this.autoCreate;
if (autoCreate.autoCreateIndex == false) {
Expand Down Expand Up @@ -100,6 +102,11 @@ void setAutoCreate(AutoCreate autoCreate) {
this.autoCreate = autoCreate;
}

private ComposableIndexTemplate findTemplate(String name, Metadata metadata) {
final String templateName = MetadataIndexTemplateService.findV2Template(metadata, name, false);
return metadata.templatesV2().get(templateName);
}

static class AutoCreate {
private final boolean autoCreateIndex;
private final List<Tuple<String, Boolean>> expressions;
Expand Down
Loading