Change separator for shards preference

The shards preference on a search request enables specifying a list of
shards to hit, and then a secondary preference (e.g., "_primary") can be
added. Today, the separator between the shards list and the secondary
preference is ';'. Unfortunately, this is also a valid separtor for URL
query parameters. This means that a preference like "_shards:0;_primary"
will be parsed into two URL parameters: "_shards:0" and "_primary". With
the recent change to strict URL parsing, the second parameter will be
rejected, "_primary" is not a valid URL parameter on a search
request. This means that this feature has never worked (unless the ';'
is escaped, but no one does that because our docs do not that, and there
was no indication from Elasticsearch that this did not work). This
commit changes the separator to '|'.

Relates #20786
This commit is contained in:
Jason Tedor 2016-10-07 07:17:01 -05:00 committed by GitHub
parent 194a6b1df0
commit d01a62908a
3 changed files with 5 additions and 5 deletions

View File

@ -126,7 +126,7 @@ public class OperationRouting extends AbstractComponent {
Preference preferenceType = Preference.parse(preference); Preference preferenceType = Preference.parse(preference);
if (preferenceType == Preference.SHARDS) { if (preferenceType == Preference.SHARDS) {
// starts with _shards, so execute on specific ones // starts with _shards, so execute on specific ones
int index = preference.indexOf(';'); int index = preference.indexOf('|');
String shards; String shards;
if (index == -1) { if (index == -1) {

View File

@ -385,7 +385,7 @@ public class RoutingIteratorTests extends ESAllocationTestCase {
assertThat(shardIterators.iterator().next().shardId().id(), equalTo(1)); assertThat(shardIterators.iterator().next().shardId().id(), equalTo(1));
//check node preference, first without preference to see they switch //check node preference, first without preference to see they switch
shardIterators = operationRouting.searchShards(clusterState, new String[]{"test"}, null, "_shards:0;"); shardIterators = operationRouting.searchShards(clusterState, new String[]{"test"}, null, "_shards:0|");
assertThat(shardIterators.size(), equalTo(1)); assertThat(shardIterators.size(), equalTo(1));
assertThat(shardIterators.iterator().next().shardId().id(), equalTo(0)); assertThat(shardIterators.iterator().next().shardId().id(), equalTo(0));
String firstRoundNodeId = shardIterators.iterator().next().nextOrNull().currentNodeId(); String firstRoundNodeId = shardIterators.iterator().next().nextOrNull().currentNodeId();
@ -395,12 +395,12 @@ public class RoutingIteratorTests extends ESAllocationTestCase {
assertThat(shardIterators.iterator().next().shardId().id(), equalTo(0)); assertThat(shardIterators.iterator().next().shardId().id(), equalTo(0));
assertThat(shardIterators.iterator().next().nextOrNull().currentNodeId(), not(equalTo(firstRoundNodeId))); assertThat(shardIterators.iterator().next().nextOrNull().currentNodeId(), not(equalTo(firstRoundNodeId)));
shardIterators = operationRouting.searchShards(clusterState, new String[]{"test"}, null, "_shards:0;_prefer_nodes:node1"); shardIterators = operationRouting.searchShards(clusterState, new String[]{"test"}, null, "_shards:0|_prefer_nodes:node1");
assertThat(shardIterators.size(), equalTo(1)); assertThat(shardIterators.size(), equalTo(1));
assertThat(shardIterators.iterator().next().shardId().id(), equalTo(0)); assertThat(shardIterators.iterator().next().shardId().id(), equalTo(0));
assertThat(shardIterators.iterator().next().nextOrNull().currentNodeId(), equalTo("node1")); assertThat(shardIterators.iterator().next().nextOrNull().currentNodeId(), equalTo("node1"));
shardIterators = operationRouting.searchShards(clusterState, new String[]{"test"}, null, "_shards:0;_prefer_nodes:node1,node2"); shardIterators = operationRouting.searchShards(clusterState, new String[]{"test"}, null, "_shards:0|_prefer_nodes:node1,node2");
assertThat(shardIterators.size(), equalTo(1)); assertThat(shardIterators.size(), equalTo(1));
Iterator<ShardIterator> iterator = shardIterators.iterator(); Iterator<ShardIterator> iterator = shardIterators.iterator();
final ShardIterator it = iterator.next(); final ShardIterator it = iterator.next();

View File

@ -34,7 +34,7 @@ The `preference` is a query string parameter which can be set to:
`_shards:2,3`:: `_shards:2,3`::
Restricts the operation to the specified shards. (`2` Restricts the operation to the specified shards. (`2`
and `3` in this case). This preference can be combined with other and `3` in this case). This preference can be combined with other
preferences but it has to appear first: `_shards:2,3;_primary` preferences but it has to appear first: `_shards:2,3|_primary`
`_only_nodes`:: `_only_nodes`::
Restricts the operation to nodes specified in node specification Restricts the operation to nodes specified in node specification