-
Notifications
You must be signed in to change notification settings - Fork 24.7k
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 support for write index resolution when creating/updating documents #31520
Changes from 1 commit
9e86921
df8fabd
7c75916
113ebc5
fb7c168
c1d2d4e
b585835
42893bf
54d0a3d
b5e5e81
d4a5ebd
2f8a004
9238cb5
8ae0967
e8cf8c8
2f2af95
3df26bd
5d47213
00eb394
7c753db
f1032e4
347149e
e58a3fb
222ae13
ae372f3
b54efe4
cda911f
eb097c2
cc969d1
284d3ee
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -20,13 +20,21 @@ | |
|
||
package org.elasticsearch.action.bulk; | ||
|
||
import org.elasticsearch.action.admin.indices.alias.Alias; | ||
import org.elasticsearch.action.admin.indices.mapping.get.GetMappingsResponse; | ||
import org.elasticsearch.action.get.GetRequestBuilder; | ||
import org.elasticsearch.action.index.IndexRequest; | ||
import org.elasticsearch.cluster.metadata.IndexMetaData; | ||
import org.elasticsearch.common.xcontent.XContentType; | ||
import org.elasticsearch.rest.RestStatus; | ||
import org.elasticsearch.test.ESIntegTestCase; | ||
|
||
import java.nio.charset.StandardCharsets; | ||
import java.util.Collections; | ||
import java.util.Map; | ||
|
||
import static org.elasticsearch.test.StreamsUtils.copyToStringFromClasspath; | ||
import static org.hamcrest.Matchers.equalTo; | ||
|
||
public class BulkIntegrationIT extends ESIntegTestCase { | ||
public void testBulkIndexCreatesMapping() throws Exception { | ||
|
@@ -40,4 +48,51 @@ public void testBulkIndexCreatesMapping() throws Exception { | |
assertTrue(mappingsResponse.getMappings().get("logstash-2014.03.30").containsKey("logs")); | ||
}); | ||
} | ||
|
||
/** | ||
* This tests that the {@link TransportBulkAction} evaluates alias routing values correctly when dealing with | ||
* an alias pointing to multiple indices, while a write index exits. | ||
*/ | ||
public void testBulkWithWriteIndexAndRouting() { | ||
Map<String, Integer> twoShardsSettings = Collections.singletonMap(IndexMetaData.SETTING_NUMBER_OF_SHARDS, 2); | ||
client().admin().indices().prepareCreate("index1") | ||
.addAlias(new Alias("alias1").indexRouting("0")).setSettings(twoShardsSettings).get(); | ||
client().admin().indices().prepareCreate("index2") | ||
.addAlias(new Alias("alias1").indexRouting("0").writeIndex(randomFrom(false, null))) | ||
.setSettings(twoShardsSettings).get(); | ||
client().admin().indices().prepareCreate("index3") | ||
.addAlias(new Alias("alias1").indexRouting("1").writeIndex(true)).setSettings(twoShardsSettings).get(); | ||
|
||
IndexRequest indexRequest = new IndexRequest("index3", "type", "id"); | ||
boolean indexWithRouting = randomBoolean(); | ||
if (indexWithRouting) { | ||
indexRequest.routing("0"); | ||
} | ||
indexRequest.source(Collections.singletonMap("foo", "bar")); | ||
IndexRequest indexRequestWithAlias = new IndexRequest("alias1", "type", "id"); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. randomly set the routing to "1"? |
||
indexRequestWithAlias.source(Collections.singletonMap("foo", "baz")); | ||
BulkResponse bulkResponse = client().prepareBulk() | ||
.add(indexRequest).add(indexRequestWithAlias).get(); | ||
assertThat(bulkResponse.getItems()[0].getResponse().getIndex(), equalTo("index3")); | ||
assertThat(bulkResponse.getItems()[0].getResponse().getShardId().getId(), equalTo(1)); | ||
assertThat(bulkResponse.getItems()[0].getResponse().getVersion(), equalTo(1L)); | ||
assertThat(bulkResponse.getItems()[0].getResponse().status(), equalTo(RestStatus.CREATED)); | ||
assertThat(bulkResponse.getItems()[1].getResponse().getIndex(), equalTo("index3")); | ||
assertThat(bulkResponse.getItems()[1].getResponse().getShardId().getId(), equalTo(0)); | ||
assertThat(bulkResponse.getItems()[1].getResponse().getVersion(), equalTo(1L)); | ||
assertThat(bulkResponse.getItems()[1].getResponse().status(), equalTo(RestStatus.CREATED)); | ||
GetRequestBuilder getBuilder = client().prepareGet("index3", "type", "id"); | ||
if (indexWithRouting) { | ||
getBuilder.setRouting("0"); | ||
} | ||
assertThat(getBuilder.get().getSource().get("foo"), equalTo("bar")); | ||
assertThat(client().prepareGet("index3", "type", "id").setRouting("1").get().getSource().get("foo"), equalTo("baz")); | ||
|
||
client().prepareBulk().add(client().prepareUpdate("alias1", "type", "id").setDoc("foo", "updated")).get(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we should check errors here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. will add. didn't think this was necessary since there are get-action calls verifying success of this operation |
||
assertThat(getBuilder.get().getSource().get("foo"), equalTo("bar")); | ||
assertThat(client().prepareGet("index3", "type", "id").setRouting("1").get().getSource().get("foo"), equalTo("updated")); | ||
client().prepareBulk().add(client().prepareDelete("alias1", "type", "id")).get(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure what we're testing here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. TransportBulkAction resolves routing for delete requests just as it does for index and update. This delete request is here to verify this |
||
assertThat(getBuilder.get().getSource().get("foo"), equalTo("bar")); | ||
assertFalse(client().prepareGet("index3", "type", "id").setRouting("1").get().isExists()); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -66,7 +66,6 @@ public class TransportBulkActionTests extends ESTestCase { | |
private ThreadPool threadPool; | ||
|
||
private TestTransportBulkAction bulkAction; | ||
private TransportShardBulkAction shardBulkAction; | ||
|
||
class TestTransportBulkAction extends TransportBulkAction { | ||
|
||
|
@@ -162,7 +161,6 @@ public void testDeleteNonExistingDocExternalGteVersionCreatesIndex() throws Exce | |
} | ||
|
||
public void testRoutingResolvesToWriteIndexAliasMetaData() throws Exception { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wonder if we need a test at this level. We already unit test MetaData and we have an IT test to check it works end to end. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. actually, I don't think we have an IT test, but we should There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I couldn't find an IT test that verifies this, and I thought that this level of unit test was sufficient. Will add IT test (will also double check that one doesn't exist) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this can be removed now that we have an IT test? this layer doesn't add anything to the write index resolving as it is all in the resolver? it's just glue and is covered well by the IT? |
||
ClusterState oldState = clusterService.state(); | ||
clusterService.submitStateUpdateTask("_update", new ClusterStateUpdateTask() { | ||
@Override | ||
public ClusterState execute(ClusterState currentState) { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -187,14 +187,16 @@ public void testResolveIndexRouting() { | |
} | ||
|
||
public void testResolveWriteIndexRouting() { | ||
boolean aliasZeroWrite = randomBoolean(); | ||
IndexMetaData.Builder builder = IndexMetaData.builder("index") | ||
.settings(Settings.builder().put(IndexMetaData.SETTING_VERSION_CREATED, Version.CURRENT)) | ||
.numberOfShards(1) | ||
.numberOfReplicas(0) | ||
.putAlias(AliasMetaData.builder("alias0").build()) | ||
.putAlias(AliasMetaData.builder("alias0").writeIndex(aliasZeroWrite).build()) | ||
.putAlias(AliasMetaData.builder("alias1").routing("1").build()) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we don't have an explicit is_write_index set to true in this test. Set it here randomly? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'll take a look. I didn't add it here since I didn't feel like it was this test's duty to worry about such things since There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. didn't hurt to add. added |
||
.putAlias(AliasMetaData.builder("alias2").routing("1,2").build()) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't believe we check rejection of multi value routings with is_write_index set to true. Can we add a test that it fails (preferably but rejecting it when building the metadata objects?) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I will add a new
I think this touches the previous comment about failing invalid routing values early. Although I agree, I do not feel comfortable introducing this change in this PR There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ++ |
||
.putAlias(AliasMetaData.builder("alias3").writeIndex(false).build()); | ||
.putAlias(AliasMetaData.builder("alias3").writeIndex(false).build()) | ||
.putAlias(AliasMetaData.builder("alias4").routing("1,2").writeIndex(true).build()); | ||
MetaData metaData = MetaData.builder().put(builder).build(); | ||
|
||
// no alias, no index | ||
|
@@ -222,6 +224,9 @@ public void testResolveWriteIndexRouting() { | |
exception = expectThrows(IllegalArgumentException.class, () -> metaData.resolveWriteIndexRouting("1", "alias2")); | ||
assertThat(exception.getMessage(), | ||
is("index/alias [alias2] provided with routing value [1,2] that resolved to several routing values, rejecting operation")); | ||
exception = expectThrows(IllegalArgumentException.class, () -> metaData.resolveWriteIndexRouting(randomFrom("1", null), "alias4")); | ||
assertThat(exception.getMessage(), | ||
is("index/alias [alias4] provided with routing value [1,2] that resolved to several routing values, rejecting operation")); | ||
|
||
// alias with no write index | ||
exception = expectThrows(IllegalArgumentException.class, () -> metaData.resolveWriteIndexRouting("1", "alias3")); | ||
|
@@ -234,7 +239,7 @@ public void testResolveWriteIndexRouting() { | |
.settings(Settings.builder().put(IndexMetaData.SETTING_VERSION_CREATED, Version.CURRENT)) | ||
.numberOfShards(1) | ||
.numberOfReplicas(0) | ||
.putAlias(AliasMetaData.builder("alias0").writeIndex(true).build()) | ||
.putAlias(AliasMetaData.builder("alias0").writeIndex(!aliasZeroWrite).build()) | ||
.putAlias(AliasMetaData.builder("alias1").routing("0").writeIndex(true).build()) | ||
.putAlias(AliasMetaData.builder("alias2").writeIndex(true).build()); | ||
MetaData metaDataTwoIndices = MetaData.builder(metaData).put(builder2).build(); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we use different ids for the different indices? I find this super confusing to reason about. Maybe also add the routing value you expect to be used to the id.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it is also OK to remove the first index request entirely. I just wanted to it to demonstrate that the two calls do not interact with the same document, even though they have the same index/type/id.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On second thought, I remember the purpose of this other index request. It is to verify the other branches of the routing resolution. The reason I think it is OK to remove is that this IT test is meant to test the connection to this method, not all its branches. The Unit tests do that.