Allow routing table to be filtered by index pattern

Before this commit when an index pattern is used to filter the cluster state, only indices metadata are populated and routing table is just empty. This commit aligns the behavior of the filtering of cluster state's routing table with the filtering of cluster state's metadata so that coherent data are returned for both routing table & metadata when index pattern is requested.
This commit is contained in:
Tanguy Leroux 2016-07-29 15:58:14 +02:00
parent bf51247ec0
commit 7d4f557aa3
3 changed files with 67 additions and 11 deletions

View File

@ -81,7 +81,8 @@ public class TransportClusterStateAction extends TransportMasterNodeReadAction<C
if (request.routingTable()) { if (request.routingTable()) {
if (request.indices().length > 0) { if (request.indices().length > 0) {
RoutingTable.Builder routingTableBuilder = RoutingTable.builder(); RoutingTable.Builder routingTableBuilder = RoutingTable.builder();
for (String filteredIndex : request.indices()) { String[] indices = indexNameExpressionResolver.concreteIndexNames(currentState, request);
for (String filteredIndex : indices) {
if (currentState.routingTable().getIndicesRouting().containsKey(filteredIndex)) { if (currentState.routingTable().getIndicesRouting().containsKey(filteredIndex)) {
routingTableBuilder.add(currentState.routingTable().getIndicesRouting().get(filteredIndex)); routingTableBuilder.add(currentState.routingTable().getIndicesRouting().get(filteredIndex));
} }

View File

@ -26,7 +26,11 @@ import org.elasticsearch.client.Client;
import org.elasticsearch.client.Requests; import org.elasticsearch.client.Requests;
import org.elasticsearch.cluster.metadata.IndexMetaData; import org.elasticsearch.cluster.metadata.IndexMetaData;
import org.elasticsearch.cluster.metadata.MappingMetaData; import org.elasticsearch.cluster.metadata.MappingMetaData;
import org.elasticsearch.cluster.metadata.MetaData;
import org.elasticsearch.cluster.routing.RoutingTable;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.UUIDs; import org.elasticsearch.common.UUIDs;
import org.elasticsearch.common.collect.ImmutableOpenMap;
import org.elasticsearch.common.unit.ByteSizeValue; import org.elasticsearch.common.unit.ByteSizeValue;
import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory; import org.elasticsearch.common.xcontent.XContentFactory;
@ -112,18 +116,38 @@ public class SimpleClusterStateIT extends ESIntegTestCase {
} }
public void testThatFilteringByIndexWorksForMetadataAndRoutingTable() throws Exception { public void testThatFilteringByIndexWorksForMetadataAndRoutingTable() throws Exception {
ClusterStateResponse clusterStateResponseFiltered = client().admin().cluster().prepareState().clear() testFilteringByIndexWorks(new String[]{"foo", "fuu", "non-existent"}, new String[]{"foo", "fuu"});
.setMetaData(true).setRoutingTable(true).setIndices("foo", "fuu", "non-existent").get(); testFilteringByIndexWorks(new String[]{"baz"}, new String[]{"baz"});
testFilteringByIndexWorks(new String[]{"f*"}, new String[]{"foo", "fuu"});
testFilteringByIndexWorks(new String[]{"b*"}, new String[]{"baz"});
testFilteringByIndexWorks(new String[]{"*u"}, new String[]{"fuu"});
// metadata String[] randomIndices = randomFrom(new String[]{"*"}, new String[]{MetaData.ALL}, Strings.EMPTY_ARRAY, new String[]{"f*", "b*"});
assertThat(clusterStateResponseFiltered.getState().metaData().indices().size(), is(2)); testFilteringByIndexWorks(randomIndices, new String[]{"foo", "fuu", "baz"});
assertThat(clusterStateResponseFiltered.getState().metaData().indices(), CollectionAssertions.hasKey("foo")); }
assertThat(clusterStateResponseFiltered.getState().metaData().indices(), CollectionAssertions.hasKey("fuu"));
// routing table /**
assertThat(clusterStateResponseFiltered.getState().routingTable().hasIndex("foo"), is(true)); * Retrieves the cluster state for the given indices and then checks
assertThat(clusterStateResponseFiltered.getState().routingTable().hasIndex("fuu"), is(true)); * that the cluster state returns coherent data for both routing table and metadata.
assertThat(clusterStateResponseFiltered.getState().routingTable().hasIndex("baz"), is(false)); */
private void testFilteringByIndexWorks(String[] indices, String[] expected) {
ClusterStateResponse clusterState = client().admin().cluster().prepareState()
.clear()
.setMetaData(true)
.setRoutingTable(true)
.setIndices(indices)
.get();
ImmutableOpenMap<String, IndexMetaData> metaData = clusterState.getState().getMetaData().indices();
assertThat(metaData.size(), is(expected.length));
RoutingTable routingTable = clusterState.getState().getRoutingTable();
assertThat(routingTable.indicesRouting().size(), is(expected.length));
for (String expectedIndex : expected) {
assertThat(metaData, CollectionAssertions.hasKey(expectedIndex));
assertThat(routingTable.hasIndex(expectedIndex), is(true));
}
} }
public void testLargeClusterStatePublishing() throws Exception { public void testLargeClusterStatePublishing() throws Exception {

View File

@ -130,3 +130,34 @@ setup:
- is_true: metadata - is_true: metadata
- is_true: routing_table - is_true: routing_table
- is_true: routing_nodes - is_true: routing_nodes
---
"Filtering the cluster state by indices using wildcards should work in routing table and metadata":
- do:
index:
index: index1
type: type
id: testing_document
body:
"text" : "The quick brown fox is brown."
- do:
index:
index: index2
type: type
id: testing_document
body:
"text" : "The quick brown fox is brown."
- do:
cluster.state:
metric: [ routing_table, metadata ]
index: [ index* ]
- is_false: metadata.indices.testidx
- is_false: routing_table.indices.testidx
- is_true: metadata.indices.index1
- is_true: routing_table.indices.index1
- is_true: metadata.indices.index2
- is_true: routing_table.indices.index2