Merge pull request #15371 from jimferenczi/alias_routing

Resolves the conflict between alias routing and parent routing by applying the alias routing and ignoring the parent routing.
This commit is contained in:
Jim Ferenczi 2015-12-21 09:58:45 +01:00
commit 1ec44dcdda
20 changed files with 180 additions and 57 deletions

View File

@ -62,4 +62,12 @@ public interface DocumentRequest<T> extends IndicesRequest {
* @return the Routing * @return the Routing
*/ */
String routing(); String routing();
/**
* Get the parent for this request
* @return the Parent
*/
String parent();
} }

View File

@ -239,7 +239,7 @@ public class TransportBulkAction extends HandledTransportAction<BulkRequest, Bul
} }
} else { } else {
concreteIndices.resolveIfAbsent(req); concreteIndices.resolveIfAbsent(req);
req.routing(clusterState.metaData().resolveIndexRouting(req.routing(), req.index())); req.routing(clusterState.metaData().resolveIndexRouting(req.parent(), req.routing(), req.index()));
} }
} }
} }

View File

@ -50,6 +50,8 @@ public class DeleteRequest extends ReplicationRequest<DeleteRequest> implements
private String id; private String id;
@Nullable @Nullable
private String routing; private String routing;
@Nullable
private String parent;
private boolean refresh; private boolean refresh;
private long version = Versions.MATCH_ANY; private long version = Versions.MATCH_ANY;
private VersionType versionType = VersionType.INTERNAL; private VersionType versionType = VersionType.INTERNAL;
@ -94,6 +96,7 @@ public class DeleteRequest extends ReplicationRequest<DeleteRequest> implements
this.type = request.type(); this.type = request.type();
this.id = request.id(); this.id = request.id();
this.routing = request.routing(); this.routing = request.routing();
this.parent = request.parent();
this.refresh = request.refresh(); this.refresh = request.refresh();
this.version = request.version(); this.version = request.version();
this.versionType = request.versionType(); this.versionType = request.versionType();
@ -155,13 +158,18 @@ public class DeleteRequest extends ReplicationRequest<DeleteRequest> implements
} }
/** /**
* Sets the parent id of this document. Will simply set the routing to this value, as it is only * @return The parent for this request.
* used for routing with delete requests. */
@Override
public String parent() {
return parent;
}
/**
* Sets the parent id of this document.
*/ */
public DeleteRequest parent(String parent) { public DeleteRequest parent(String parent) {
if (routing == null) { this.parent = parent;
routing = parent;
}
return this; return this;
} }
@ -230,6 +238,7 @@ public class DeleteRequest extends ReplicationRequest<DeleteRequest> implements
type = in.readString(); type = in.readString();
id = in.readString(); id = in.readString();
routing = in.readOptionalString(); routing = in.readOptionalString();
parent = in.readOptionalString();
refresh = in.readBoolean(); refresh = in.readBoolean();
version = in.readLong(); version = in.readLong();
versionType = VersionType.fromValue(in.readByte()); versionType = VersionType.fromValue(in.readByte());
@ -241,6 +250,7 @@ public class DeleteRequest extends ReplicationRequest<DeleteRequest> implements
out.writeString(type); out.writeString(type);
out.writeString(id); out.writeString(id);
out.writeOptionalString(routing()); out.writeOptionalString(routing());
out.writeOptionalString(parent());
out.writeBoolean(refresh); out.writeBoolean(refresh);
out.writeLong(version); out.writeLong(version);
out.writeByte(versionType.getValue()); out.writeByte(versionType.getValue());

View File

@ -95,7 +95,7 @@ public class TransportDeleteAction extends TransportReplicationAction<DeleteRequ
@Override @Override
protected void resolveRequest(final MetaData metaData, String concreteIndex, DeleteRequest request) { protected void resolveRequest(final MetaData metaData, String concreteIndex, DeleteRequest request) {
request.routing(metaData.resolveIndexRouting(request.routing(), request.index())); request.routing(metaData.resolveIndexRouting(request.parent(), request.routing(), request.index()));
if (metaData.hasIndex(concreteIndex)) { if (metaData.hasIndex(concreteIndex)) {
// check if routing is required, if so, do a broadcast delete // check if routing is required, if so, do a broadcast delete
MappingMetaData mappingMd = metaData.index(concreteIndex).mappingOrDefault(request.type()); MappingMetaData mappingMd = metaData.index(concreteIndex).mappingOrDefault(request.type());

View File

@ -49,6 +49,7 @@ public class GetRequest extends SingleShardRequest<GetRequest> implements Realti
private String type; private String type;
private String id; private String id;
private String routing; private String routing;
private String parent;
private String preference; private String preference;
private String[] fields; private String[] fields;
@ -77,6 +78,7 @@ public class GetRequest extends SingleShardRequest<GetRequest> implements Realti
this.type = getRequest.type; this.type = getRequest.type;
this.id = getRequest.id; this.id = getRequest.id;
this.routing = getRequest.routing; this.routing = getRequest.routing;
this.parent = getRequest.parent;
this.preference = getRequest.preference; this.preference = getRequest.preference;
this.fields = getRequest.fields; this.fields = getRequest.fields;
this.fetchSourceContext = getRequest.fetchSourceContext; this.fetchSourceContext = getRequest.fetchSourceContext;
@ -153,13 +155,17 @@ public class GetRequest extends SingleShardRequest<GetRequest> implements Realti
} }
/** /**
* Sets the parent id of this document. Will simply set the routing to this value, as it is only * @return The parent for this request.
* used for routing with delete requests. */
public String parent() {
return parent;
}
/**
* Sets the parent id of this document.
*/ */
public GetRequest parent(String parent) { public GetRequest parent(String parent) {
if (routing == null) { this.parent = parent;
routing = parent;
}
return this; return this;
} }
@ -291,6 +297,7 @@ public class GetRequest extends SingleShardRequest<GetRequest> implements Realti
type = in.readString(); type = in.readString();
id = in.readString(); id = in.readString();
routing = in.readOptionalString(); routing = in.readOptionalString();
parent = in.readOptionalString();
preference = in.readOptionalString(); preference = in.readOptionalString();
refresh = in.readBoolean(); refresh = in.readBoolean();
int size = in.readInt(); int size = in.readInt();
@ -320,6 +327,7 @@ public class GetRequest extends SingleShardRequest<GetRequest> implements Realti
out.writeString(type); out.writeString(type);
out.writeString(id); out.writeString(id);
out.writeOptionalString(routing); out.writeOptionalString(routing);
out.writeOptionalString(parent);
out.writeOptionalString(preference); out.writeOptionalString(preference);
out.writeBoolean(refresh); out.writeBoolean(refresh);

View File

@ -57,6 +57,7 @@ public class MultiGetRequest extends ActionRequest<MultiGetRequest> implements I
private String type; private String type;
private String id; private String id;
private String routing; private String routing;
private String parent;
private String[] fields; private String[] fields;
private long version = Versions.MATCH_ANY; private long version = Versions.MATCH_ANY;
private VersionType versionType = VersionType.INTERNAL; private VersionType versionType = VersionType.INTERNAL;
@ -124,12 +125,17 @@ public class MultiGetRequest extends ActionRequest<MultiGetRequest> implements I
} }
public Item parent(String parent) { public Item parent(String parent) {
if (routing == null) { this.parent = parent;
this.routing = parent;
}
return this; return this;
} }
/**
* @return The parent for this request.
*/
public String parent() {
return parent;
}
public Item fields(String... fields) { public Item fields(String... fields) {
this.fields = fields; this.fields = fields;
return this; return this;
@ -181,6 +187,7 @@ public class MultiGetRequest extends ActionRequest<MultiGetRequest> implements I
type = in.readOptionalString(); type = in.readOptionalString();
id = in.readString(); id = in.readString();
routing = in.readOptionalString(); routing = in.readOptionalString();
parent = in.readOptionalString();
int size = in.readVInt(); int size = in.readVInt();
if (size > 0) { if (size > 0) {
fields = new String[size]; fields = new String[size];
@ -200,6 +207,7 @@ public class MultiGetRequest extends ActionRequest<MultiGetRequest> implements I
out.writeOptionalString(type); out.writeOptionalString(type);
out.writeString(id); out.writeString(id);
out.writeOptionalString(routing); out.writeOptionalString(routing);
out.writeOptionalString(parent);
if (fields == null) { if (fields == null) {
out.writeVInt(0); out.writeVInt(0);
} else { } else {
@ -229,6 +237,7 @@ public class MultiGetRequest extends ActionRequest<MultiGetRequest> implements I
if (!id.equals(item.id)) return false; if (!id.equals(item.id)) return false;
if (!index.equals(item.index)) return false; if (!index.equals(item.index)) return false;
if (routing != null ? !routing.equals(item.routing) : item.routing != null) return false; if (routing != null ? !routing.equals(item.routing) : item.routing != null) return false;
if (parent != null ? !parent.equals(item.parent) : item.parent != null) return false;
if (type != null ? !type.equals(item.type) : item.type != null) return false; if (type != null ? !type.equals(item.type) : item.type != null) return false;
if (versionType != item.versionType) return false; if (versionType != item.versionType) return false;
@ -241,6 +250,7 @@ public class MultiGetRequest extends ActionRequest<MultiGetRequest> implements I
result = 31 * result + (type != null ? type.hashCode() : 0); result = 31 * result + (type != null ? type.hashCode() : 0);
result = 31 * result + id.hashCode(); result = 31 * result + id.hashCode();
result = 31 * result + (routing != null ? routing.hashCode() : 0); result = 31 * result + (routing != null ? routing.hashCode() : 0);
result = 31 * result + (parent != null ? parent.hashCode() : 0);
result = 31 * result + (fields != null ? Arrays.hashCode(fields) : 0); result = 31 * result + (fields != null ? Arrays.hashCode(fields) : 0);
result = 31 * result + Long.hashCode(version); result = 31 * result + Long.hashCode(version);
result = 31 * result + versionType.hashCode(); result = 31 * result + versionType.hashCode();

View File

@ -82,7 +82,7 @@ public class TransportGetAction extends TransportSingleShardAction<GetRequest, G
request.request().preference(Preference.PRIMARY.type()); request.request().preference(Preference.PRIMARY.type());
} }
// update the routing (request#index here is possibly an alias) // update the routing (request#index here is possibly an alias)
request.request().routing(state.metaData().resolveIndexRouting(request.request().routing(), request.request().index())); request.request().routing(state.metaData().resolveIndexRouting(request.request().parent(), request.request().routing(), request.request().index()));
// Fail fast on the node that received the request. // Fail fast on the node that received the request.
if (request.request().routing() == null && state.getMetaData().routingRequired(request.concreteIndex(), request.request().type())) { if (request.request().routing() == null && state.getMetaData().routingRequired(request.concreteIndex(), request.request().type())) {
throw new RoutingMissingException(request.concreteIndex(), request.request().type(), request.request().id()); throw new RoutingMissingException(request.concreteIndex(), request.request().type(), request.request().id());

View File

@ -68,7 +68,7 @@ public class TransportMultiGetAction extends HandledTransportAction<MultiGetRequ
responses.set(i, new MultiGetItemResponse(null, new MultiGetResponse.Failure(item.index(), item.type(), item.id(), new IndexNotFoundException(item.index())))); responses.set(i, new MultiGetItemResponse(null, new MultiGetResponse.Failure(item.index(), item.type(), item.id(), new IndexNotFoundException(item.index()))));
continue; continue;
} }
item.routing(clusterState.metaData().resolveIndexRouting(item.routing(), item.index())); item.routing(clusterState.metaData().resolveIndexRouting(item.parent(), item.routing(), item.index()));
String concreteSingleIndex = indexNameExpressionResolver.concreteSingleIndex(clusterState, item); String concreteSingleIndex = indexNameExpressionResolver.concreteSingleIndex(clusterState, item);
if (item.routing() == null && clusterState.getMetaData().routingRequired(concreteSingleIndex, item.type())) { if (item.routing() == null && clusterState.getMetaData().routingRequired(concreteSingleIndex, item.type())) {
responses.set(i, new MultiGetItemResponse(null, new MultiGetResponse.Failure(concreteSingleIndex, item.type(), item.id(), responses.set(i, new MultiGetItemResponse(null, new MultiGetResponse.Failure(concreteSingleIndex, item.type(), item.id(),

View File

@ -312,14 +312,10 @@ public class IndexRequest extends ReplicationRequest<IndexRequest> implements Do
} }
/** /**
* Sets the parent id of this document. If routing is not set, automatically set it as the * Sets the parent id of this document.
* routing as well.
*/ */
public IndexRequest parent(String parent) { public IndexRequest parent(String parent) {
this.parent = parent; this.parent = parent;
if (routing == null) {
routing = parent;
}
return this; return this;
} }
@ -601,7 +597,7 @@ public class IndexRequest extends ReplicationRequest<IndexRequest> implements Do
public void process(MetaData metaData, @Nullable MappingMetaData mappingMd, boolean allowIdGeneration, String concreteIndex) { public void process(MetaData metaData, @Nullable MappingMetaData mappingMd, boolean allowIdGeneration, String concreteIndex) {
// resolve the routing if needed // resolve the routing if needed
routing(metaData.resolveIndexRouting(routing, index)); routing(metaData.resolveIndexRouting(parent, routing, index));
// resolve timestamp if provided externally // resolve timestamp if provided externally
if (timestamp != null) { if (timestamp != null) {

View File

@ -65,6 +65,8 @@ public class TermVectorsRequest extends SingleShardRequest<TermVectorsRequest> i
private String routing; private String routing;
private String parent;
private VersionType versionType = VersionType.INTERNAL; private VersionType versionType = VersionType.INTERNAL;
private long version = Versions.MATCH_ANY; private long version = Versions.MATCH_ANY;
@ -162,6 +164,7 @@ public class TermVectorsRequest extends SingleShardRequest<TermVectorsRequest> i
this.flagsEnum = other.getFlags().clone(); this.flagsEnum = other.getFlags().clone();
this.preference = other.preference(); this.preference = other.preference();
this.routing = other.routing(); this.routing = other.routing();
this.parent = other.parent();
if (other.selectedFields != null) { if (other.selectedFields != null) {
this.selectedFields = new HashSet<>(other.selectedFields); this.selectedFields = new HashSet<>(other.selectedFields);
} }
@ -181,6 +184,7 @@ public class TermVectorsRequest extends SingleShardRequest<TermVectorsRequest> i
this.type = item.type(); this.type = item.type();
this.selectedFields(item.fields()); this.selectedFields(item.fields());
this.routing(item.routing()); this.routing(item.routing());
this.parent(item.parent());
} }
public EnumSet<Flag> getFlags() { public EnumSet<Flag> getFlags() {
@ -259,14 +263,16 @@ public class TermVectorsRequest extends SingleShardRequest<TermVectorsRequest> i
return this; return this;
} }
@Override
public String parent() {
return parent;
}
/** /**
* Sets the parent id of this document. Will simply set the routing to this * Sets the parent id of this document.
* value, as it is only used for routing with delete requests.
*/ */
public TermVectorsRequest parent(String parent) { public TermVectorsRequest parent(String parent) {
if (routing == null) { this.parent = parent;
routing = parent;
}
return this; return this;
} }
@ -506,6 +512,7 @@ public class TermVectorsRequest extends SingleShardRequest<TermVectorsRequest> i
doc = in.readBytesReference(); doc = in.readBytesReference();
} }
routing = in.readOptionalString(); routing = in.readOptionalString();
parent = in.readOptionalString();
preference = in.readOptionalString(); preference = in.readOptionalString();
long flags = in.readVLong(); long flags = in.readVLong();
@ -545,6 +552,7 @@ public class TermVectorsRequest extends SingleShardRequest<TermVectorsRequest> i
out.writeBytesReference(doc); out.writeBytesReference(doc);
} }
out.writeOptionalString(routing); out.writeOptionalString(routing);
out.writeOptionalString(parent);
out.writeOptionalString(preference); out.writeOptionalString(preference);
long longFlags = 0; long longFlags = 0;
for (Flag flag : flagsEnum) { for (Flag flag : flagsEnum) {
@ -629,6 +637,8 @@ public class TermVectorsRequest extends SingleShardRequest<TermVectorsRequest> i
termVectorsRequest.doc(jsonBuilder().copyCurrentStructure(parser)); termVectorsRequest.doc(jsonBuilder().copyCurrentStructure(parser));
} else if ("_routing".equals(currentFieldName) || "routing".equals(currentFieldName)) { } else if ("_routing".equals(currentFieldName) || "routing".equals(currentFieldName)) {
termVectorsRequest.routing = parser.text(); termVectorsRequest.routing = parser.text();
} else if ("_parent".equals(currentFieldName) || "parent".equals(currentFieldName)) {
termVectorsRequest.parent = parser.text();
} else if ("_version".equals(currentFieldName) || "version".equals(currentFieldName)) { } else if ("_version".equals(currentFieldName) || "version".equals(currentFieldName)) {
termVectorsRequest.version = parser.longValue(); termVectorsRequest.version = parser.longValue();
} else if ("_version_type".equals(currentFieldName) || "_versionType".equals(currentFieldName) || "version_type".equals(currentFieldName) || "versionType".equals(currentFieldName)) { } else if ("_version_type".equals(currentFieldName) || "_versionType".equals(currentFieldName) || "version_type".equals(currentFieldName) || "versionType".equals(currentFieldName)) {

View File

@ -66,7 +66,7 @@ public class TransportMultiTermVectorsAction extends HandledTransportAction<Mult
for (int i = 0; i < request.requests.size(); i++) { for (int i = 0; i < request.requests.size(); i++) {
TermVectorsRequest termVectorsRequest = request.requests.get(i); TermVectorsRequest termVectorsRequest = request.requests.get(i);
termVectorsRequest.startTime = System.currentTimeMillis(); termVectorsRequest.startTime = System.currentTimeMillis();
termVectorsRequest.routing(clusterState.metaData().resolveIndexRouting(termVectorsRequest.routing(), termVectorsRequest.index())); termVectorsRequest.routing(clusterState.metaData().resolveIndexRouting(termVectorsRequest.parent(), termVectorsRequest.routing(), termVectorsRequest.index()));
if (!clusterState.metaData().hasConcreteIndex(termVectorsRequest.index())) { if (!clusterState.metaData().hasConcreteIndex(termVectorsRequest.index())) {
responses.set(i, new MultiTermVectorsItemResponse(null, new MultiTermVectorsResponse.Failure(termVectorsRequest.index(), responses.set(i, new MultiTermVectorsItemResponse(null, new MultiTermVectorsResponse.Failure(termVectorsRequest.index(),
termVectorsRequest.type(), termVectorsRequest.id(), new IndexNotFoundException(termVectorsRequest.index())))); termVectorsRequest.type(), termVectorsRequest.id(), new IndexNotFoundException(termVectorsRequest.index()))));
@ -88,12 +88,12 @@ public class TransportMultiTermVectorsAction extends HandledTransportAction<Mult
} }
shardRequest.add(i, termVectorsRequest); shardRequest.add(i, termVectorsRequest);
} }
if (shardRequests.size() == 0) { if (shardRequests.size() == 0) {
// only failures.. // only failures..
listener.onResponse(new MultiTermVectorsResponse(responses.toArray(new MultiTermVectorsItemResponse[responses.length()]))); listener.onResponse(new MultiTermVectorsResponse(responses.toArray(new MultiTermVectorsItemResponse[responses.length()])));
} }
final AtomicInteger counter = new AtomicInteger(shardRequests.size()); final AtomicInteger counter = new AtomicInteger(shardRequests.size());
for (final MultiTermVectorsShardRequest shardRequest : shardRequests.values()) { for (final MultiTermVectorsShardRequest shardRequest : shardRequests.values()) {
shardAction.execute(shardRequest, new ActionListener<MultiTermVectorsShardResponse>() { shardAction.execute(shardRequest, new ActionListener<MultiTermVectorsShardResponse>() {

View File

@ -71,8 +71,8 @@ public class TransportTermVectorsAction extends TransportSingleShardAction<TermV
@Override @Override
protected void resolveRequest(ClusterState state, InternalRequest request) { protected void resolveRequest(ClusterState state, InternalRequest request) {
// update the routing (request#index here is possibly an alias) // update the routing (request#index here is possibly an alias or a parent)
request.request().routing(state.metaData().resolveIndexRouting(request.request().routing(), request.request().index())); request.request().routing(state.metaData().resolveIndexRouting(request.request().parent(), request.request().routing(), request.request().index()));
// Fail fast on the node that received the request. // Fail fast on the node that received the request.
if (request.request().routing() == null && state.getMetaData().routingRequired(request.concreteIndex(), request.request().type())) { if (request.request().routing() == null && state.getMetaData().routingRequired(request.concreteIndex(), request.request().type())) {
throw new RoutingMissingException(request.concreteIndex(), request.request().type(), request.request().id()); throw new RoutingMissingException(request.concreteIndex(), request.request().type(), request.request().id());

View File

@ -101,7 +101,7 @@ public class TransportUpdateAction extends TransportInstanceSingleOperationActio
@Override @Override
protected boolean resolveRequest(ClusterState state, UpdateRequest request, ActionListener<UpdateResponse> listener) { protected boolean resolveRequest(ClusterState state, UpdateRequest request, ActionListener<UpdateResponse> listener) {
request.routing((state.metaData().resolveIndexRouting(request.routing(), request.index()))); request.routing((state.metaData().resolveIndexRouting(request.parent(), request.routing(), request.index())));
// Fail fast on the node that received the request, rather than failing when translating on the index or delete request. // Fail fast on the node that received the request, rather than failing when translating on the index or delete request.
if (request.routing() == null && state.getMetaData().routingRequired(request.concreteIndex(), request.type())) { if (request.routing() == null && state.getMetaData().routingRequired(request.concreteIndex(), request.type())) {
throw new RoutingMissingException(request.concreteIndex(), request.type(), request.id()); throw new RoutingMissingException(request.concreteIndex(), request.type(), request.id());

View File

@ -184,13 +184,10 @@ public class UpdateRequest extends InstanceShardOperationRequest<UpdateRequest>
} }
/** /**
* The parent id is used for the upsert request and also implicitely sets the routing if not already set. * The parent id is used for the upsert request.
*/ */
public UpdateRequest parent(String parent) { public UpdateRequest parent(String parent) {
this.parent = parent; this.parent = parent;
if (routing == null) {
routing = parent;
}
return this; return this;
} }

View File

@ -440,13 +440,19 @@ public class MetaData implements Iterable<IndexMetaData>, Diffable<MetaData>, Fr
*/ */
// TODO: This can be moved to IndexNameExpressionResolver too, but this means that we will support wildcards and other expressions // TODO: This can be moved to IndexNameExpressionResolver too, but this means that we will support wildcards and other expressions
// in the index,bulk,update and delete apis. // in the index,bulk,update and delete apis.
public String resolveIndexRouting(@Nullable String routing, String aliasOrIndex) { public String resolveIndexRouting(@Nullable String parent, @Nullable String routing, String aliasOrIndex) {
if (aliasOrIndex == null) { if (aliasOrIndex == null) {
if (routing == null) {
return parent;
}
return routing; return routing;
} }
AliasOrIndex result = getAliasAndIndexLookup().get(aliasOrIndex); AliasOrIndex result = getAliasAndIndexLookup().get(aliasOrIndex);
if (result == null || result.isAlias() == false) { if (result == null || result.isAlias() == false) {
if (routing == null) {
return parent;
}
return routing; return routing;
} }
AliasOrIndex.Alias alias = (AliasOrIndex.Alias) result; AliasOrIndex.Alias alias = (AliasOrIndex.Alias) result;
@ -460,17 +466,19 @@ public class MetaData implements Iterable<IndexMetaData>, Diffable<MetaData>, Fr
} }
AliasMetaData aliasMd = alias.getFirstAliasMetaData(); AliasMetaData aliasMd = alias.getFirstAliasMetaData();
if (aliasMd.indexRouting() != null) { if (aliasMd.indexRouting() != null) {
if (aliasMd.indexRouting().indexOf(',') != -1) {
throw new IllegalArgumentException("index/alias [" + aliasOrIndex + "] provided with routing value [" + aliasMd.getIndexRouting() + "] that resolved to several routing values, rejecting operation");
}
if (routing != null) { if (routing != null) {
if (!routing.equals(aliasMd.indexRouting())) { if (!routing.equals(aliasMd.indexRouting())) {
throw new IllegalArgumentException("Alias [" + aliasOrIndex + "] has index routing associated with it [" + aliasMd.indexRouting() + "], and was provided with routing value [" + routing + "], rejecting operation"); throw new IllegalArgumentException("Alias [" + aliasOrIndex + "] has index routing associated with it [" + aliasMd.indexRouting() + "], and was provided with routing value [" + routing + "], rejecting operation");
} }
} }
routing = aliasMd.indexRouting(); // Alias routing overrides the parent routing (if any).
return aliasMd.indexRouting();
} }
if (routing != null) { if (routing == null) {
if (routing.indexOf(',') != -1) { return parent;
throw new IllegalArgumentException("index/alias [" + aliasOrIndex + "] provided with routing value [" + routing + "] that resolved to several routing values, rejecting operation");
}
} }
return routing; return routing;
} }

View File

@ -255,7 +255,7 @@ public class TermVectorsUnitTests extends ESTestCase {
assertThat(request.positions(), equalTo(req2.positions())); assertThat(request.positions(), equalTo(req2.positions()));
assertThat(request.termStatistics(), equalTo(req2.termStatistics())); assertThat(request.termStatistics(), equalTo(req2.termStatistics()));
assertThat(request.preference(), equalTo(pref)); assertThat(request.preference(), equalTo(pref));
assertThat(request.routing(), equalTo(parent)); assertThat(request.routing(), equalTo(null));
} }
} }

View File

@ -24,6 +24,7 @@ import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.test.ESTestCase; import org.elasticsearch.test.ESTestCase;
import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
public class MetaDataTests extends ESTestCase { public class MetaDataTests extends ESTestCase {
@ -41,4 +42,72 @@ public class MetaDataTests extends ESTestCase {
} }
} }
public void testResolveIndexRouting() {
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("alias1").routing("1").build())
.putAlias(AliasMetaData.builder("alias2").routing("1,2").build());
MetaData metaData = MetaData.builder().put(builder).build();
// no alias, no index
assertEquals(metaData.resolveIndexRouting(null, null, null), null);
assertEquals(metaData.resolveIndexRouting(null, "0", null), "0");
assertEquals(metaData.resolveIndexRouting("32", "0", null), "0");
assertEquals(metaData.resolveIndexRouting("32", null, null), "32");
// index, no alias
assertEquals(metaData.resolveIndexRouting("32", "0", "index"), "0");
assertEquals(metaData.resolveIndexRouting("32", null, "index"), "32");
assertEquals(metaData.resolveIndexRouting(null, null, "index"), null);
assertEquals(metaData.resolveIndexRouting(null, "0", "index"), "0");
// alias with no index routing
assertEquals(metaData.resolveIndexRouting(null, null, "alias0"), null);
assertEquals(metaData.resolveIndexRouting(null, "0", "alias0"), "0");
assertEquals(metaData.resolveIndexRouting("32", null, "alias0"), "32");
assertEquals(metaData.resolveIndexRouting("32", "0", "alias0"), "0");
// alias with index routing.
assertEquals(metaData.resolveIndexRouting(null, null, "alias1"), "1");
assertEquals(metaData.resolveIndexRouting("32", null, "alias1"), "1");
assertEquals(metaData.resolveIndexRouting("32", "1", "alias1"), "1");
try {
metaData.resolveIndexRouting(null, "0", "alias1");
fail("should fail");
} catch (IllegalArgumentException ex) {
assertThat(ex.getMessage(), is("Alias [alias1] has index routing associated with it [1], and was provided with routing value [0], rejecting operation"));
}
try {
metaData.resolveIndexRouting("32", "0", "alias1");
fail("should fail");
} catch (IllegalArgumentException ex) {
assertThat(ex.getMessage(), is("Alias [alias1] has index routing associated with it [1], and was provided with routing value [0], rejecting operation"));
}
// alias with invalid index routing.
try {
metaData.resolveIndexRouting(null, null, "alias2");
fail("should fail");
} catch (IllegalArgumentException ex) {
assertThat(ex.getMessage(), is("index/alias [alias2] provided with routing value [1,2] that resolved to several routing values, rejecting operation"));
}
try {
metaData.resolveIndexRouting(null, "1", "alias2");
fail("should fail");
} catch (IllegalArgumentException ex) {
assertThat(ex.getMessage(), is("index/alias [alias2] provided with routing value [1,2] that resolved to several routing values, rejecting operation"));
}
try {
metaData.resolveIndexRouting("32", null, "alias2");
fail("should fail");
} catch (IllegalArgumentException ex) {
assertThat(ex.getMessage(), is("index/alias [alias2] provided with routing value [1,2] that resolved to several routing values, rejecting operation"));
}
}
} }

View File

@ -51,24 +51,27 @@ public class AliasResolveRoutingIT extends ESIntegTestCase {
client().admin().indices().prepareAliases().addAliasAction(newAddAliasAction("test1", "alias0").routing("0")).execute().actionGet(); client().admin().indices().prepareAliases().addAliasAction(newAddAliasAction("test1", "alias0").routing("0")).execute().actionGet();
client().admin().indices().prepareAliases().addAliasAction(newAddAliasAction("test2", "alias0").routing("0")).execute().actionGet(); client().admin().indices().prepareAliases().addAliasAction(newAddAliasAction("test2", "alias0").routing("0")).execute().actionGet();
assertThat(clusterService().state().metaData().resolveIndexRouting(null, "test1"), nullValue()); assertThat(clusterService().state().metaData().resolveIndexRouting(null, null, "test1"), nullValue());
assertThat(clusterService().state().metaData().resolveIndexRouting(null, "alias"), nullValue()); assertThat(clusterService().state().metaData().resolveIndexRouting(null, null, "alias"), nullValue());
assertThat(clusterService().state().metaData().resolveIndexRouting(null, "test1"), nullValue()); assertThat(clusterService().state().metaData().resolveIndexRouting(null, null, "test1"), nullValue());
assertThat(clusterService().state().metaData().resolveIndexRouting(null, "alias10"), equalTo("0")); assertThat(clusterService().state().metaData().resolveIndexRouting(null, null, "alias10"), equalTo("0"));
assertThat(clusterService().state().metaData().resolveIndexRouting(null, "alias20"), equalTo("0")); assertThat(clusterService().state().metaData().resolveIndexRouting(null, null, "alias20"), equalTo("0"));
assertThat(clusterService().state().metaData().resolveIndexRouting(null, "alias21"), equalTo("1")); assertThat(clusterService().state().metaData().resolveIndexRouting(null, null, "alias21"), equalTo("1"));
assertThat(clusterService().state().metaData().resolveIndexRouting("3", "test1"), equalTo("3")); assertThat(clusterService().state().metaData().resolveIndexRouting(null, "3", "test1"), equalTo("3"));
assertThat(clusterService().state().metaData().resolveIndexRouting("0", "alias10"), equalTo("0")); assertThat(clusterService().state().metaData().resolveIndexRouting(null, "0", "alias10"), equalTo("0"));
// Force the alias routing and ignore the parent.
assertThat(clusterService().state().metaData().resolveIndexRouting("1", null, "alias10"), equalTo("0"));
try { try {
clusterService().state().metaData().resolveIndexRouting("1", "alias10"); clusterService().state().metaData().resolveIndexRouting(null, "1", "alias10");
fail("should fail"); fail("should fail");
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
// all is well, we can't have two mappings, one provided, and one in the alias // all is well, we can't have two mappings, one provided, and one in the alias
} }
try { try {
clusterService().state().metaData().resolveIndexRouting(null, "alias0"); clusterService().state().metaData().resolveIndexRouting(null, null, "alias0");
fail("should fail"); fail("should fail");
} catch (IllegalArgumentException ex) { } catch (IllegalArgumentException ex) {
// Expected // Expected

View File

@ -223,6 +223,7 @@ Can't be used to update the routing of an existing document.
Parent is used to route the update request to the right shard and sets the Parent is used to route the update request to the right shard and sets the
parent for the upsert request if the document being updated doesn't exist. parent for the upsert request if the document being updated doesn't exist.
Can't be used to update the `parent` of an existing document. Can't be used to update the `parent` of an existing document.
If an alias index routing is specified then it overrides the parent routing and it is used to route the request.
`timeout`:: `timeout`::

View File

@ -193,8 +193,8 @@ curl -XPOST 'http://localhost:9200/_aliases' -d '
As shown in the example above, search routing may contain several values As shown in the example above, search routing may contain several values
separated by comma. Index routing can contain only a single value. separated by comma. Index routing can contain only a single value.
If an operation that uses routing alias also has a routing parameter, an If a search operation that uses routing alias also has a routing parameter, an
intersection of both alias routing and routing specified in the intersection of both search alias routing and routing specified in the
parameter is used. For example the following command will use "2" as a parameter is used. For example the following command will use "2" as a
routing value: routing value:
@ -203,6 +203,9 @@ routing value:
curl -XGET 'http://localhost:9200/alias2/_search?q=user:kimchy&routing=2,3' curl -XGET 'http://localhost:9200/alias2/_search?q=user:kimchy&routing=2,3'
-------------------------------------------------- --------------------------------------------------
If an index operation that uses index routing alias also has a parent routing, the
parent routing is ignored.
[float] [float]
[[alias-adding]] [[alias-adding]]
=== Add a single alias === Add a single alias