{
@Inject
- public TransportGetIndexTemplatesAction(Settings settings, TransportService transportService, ClusterService clusterService, ThreadPool threadPool, ActionFilters actionFilters) {
- super(settings, GetIndexTemplatesAction.NAME, transportService, clusterService, threadPool, actionFilters, GetIndexTemplatesRequest.class);
+ public TransportGetIndexTemplatesAction(Settings settings, TransportService transportService, ClusterService clusterService,
+ ThreadPool threadPool, ActionFilters actionFilters, IndexNameExpressionResolver indexNameExpressionResolver) {
+ super(settings, GetIndexTemplatesAction.NAME, transportService, clusterService, threadPool, actionFilters, indexNameExpressionResolver, GetIndexTemplatesRequest.class);
}
@Override
diff --git a/core/src/main/java/org/elasticsearch/action/admin/indices/template/put/TransportPutIndexTemplateAction.java b/core/src/main/java/org/elasticsearch/action/admin/indices/template/put/TransportPutIndexTemplateAction.java
index 492dbf352c7..186d2288841 100644
--- a/core/src/main/java/org/elasticsearch/action/admin/indices/template/put/TransportPutIndexTemplateAction.java
+++ b/core/src/main/java/org/elasticsearch/action/admin/indices/template/put/TransportPutIndexTemplateAction.java
@@ -25,6 +25,7 @@ import org.elasticsearch.cluster.ClusterService;
import org.elasticsearch.cluster.ClusterState;
import org.elasticsearch.cluster.block.ClusterBlockException;
import org.elasticsearch.cluster.block.ClusterBlockLevel;
+import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
import org.elasticsearch.cluster.metadata.MetaDataIndexTemplateService;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.settings.Settings;
@@ -40,8 +41,9 @@ public class TransportPutIndexTemplateAction extends TransportMasterNodeAction> routingMap = clusterState.metaData().resolveSearchRouting(Integer.toString(ThreadLocalRandom.current().nextInt(1000)), request.indices());
- return clusterService.operationRouting().searchShards(clusterState, request.indices(), concreteIndices, routingMap, "_local");
+ Map> routingMap = indexNameExpressionResolver.resolveSearchRouting(clusterState, Integer.toString(ThreadLocalRandom.current().nextInt(1000)), request.indices());
+ return clusterService.operationRouting().searchShards(clusterState, concreteIndices, routingMap, "_local");
}
@Override
@@ -168,7 +173,8 @@ public class TransportValidateQueryAction extends TransportBroadcastAction {
@Inject
- public TransportDeleteWarmerAction(Settings settings, TransportService transportService, ClusterService clusterService, ThreadPool threadPool, ActionFilters actionFilters) {
- super(settings, DeleteWarmerAction.NAME, transportService, clusterService, threadPool, actionFilters, DeleteWarmerRequest.class);
+ public TransportDeleteWarmerAction(Settings settings, TransportService transportService, ClusterService clusterService,
+ ThreadPool threadPool, ActionFilters actionFilters, IndexNameExpressionResolver indexNameExpressionResolver) {
+ super(settings, DeleteWarmerAction.NAME, transportService, clusterService, threadPool, actionFilters, indexNameExpressionResolver, DeleteWarmerRequest.class);
}
@Override
@@ -67,12 +68,12 @@ public class TransportDeleteWarmerAction extends TransportMasterNodeAction listener) {
- final String[] concreteIndices = clusterService.state().metaData().concreteIndices(request.indicesOptions(), request.indices());
+ final String[] concreteIndices = indexNameExpressionResolver.concreteIndices(state, request);
clusterService.submitStateUpdateTask("delete_warmer [" + Arrays.toString(request.names()) + "]", new AckedClusterStateUpdateTask(request, listener) {
@Override
@@ -94,7 +95,7 @@ public class TransportDeleteWarmerAction extends TransportMasterNodeAction {
@Inject
- public TransportGetWarmersAction(Settings settings, TransportService transportService, ClusterService clusterService, ThreadPool threadPool, ActionFilters actionFilters) {
- super(settings, GetWarmersAction.NAME, transportService, clusterService, threadPool, actionFilters, GetWarmersRequest.class);
+ public TransportGetWarmersAction(Settings settings, TransportService transportService, ClusterService clusterService,
+ ThreadPool threadPool, ActionFilters actionFilters, IndexNameExpressionResolver indexNameExpressionResolver) {
+ super(settings, GetWarmersAction.NAME, transportService, clusterService, threadPool, actionFilters, indexNameExpressionResolver, GetWarmersRequest.class);
}
@Override
@@ -54,7 +56,7 @@ public class TransportGetWarmersAction extends TransportClusterInfoAction 0) {
@@ -127,7 +127,7 @@ public class TransportPutWarmerAction extends TransportMasterNodeAction indices = new HashMap<>();
- private final MetaData metaData;
- ConcreteIndices(MetaData metaData) {
- this.metaData = metaData;
+ ConcreteIndices(ClusterState state, IndexNameExpressionResolver indexNameExpressionResolver) {
+ this.state = state;
+ this.indexNameExpressionResolver = indexNameExpressionResolver;
}
String getConcreteIndex(String indexOrAlias) {
return indices.get(indexOrAlias);
}
- String resolveIfAbsent(String indexOrAlias, IndicesOptions indicesOptions) {
- String concreteIndex = indices.get(indexOrAlias);
+ String resolveIfAbsent(DocumentRequest request) {
+ String concreteIndex = indices.get(request.index());
if (concreteIndex == null) {
- concreteIndex = metaData.concreteSingleIndex(indexOrAlias, indicesOptions);
- indices.put(indexOrAlias, concreteIndex);
+ concreteIndex = indexNameExpressionResolver.concreteSingleIndex(state, request);
+ indices.put(request.index(), concreteIndex);
}
return concreteIndex;
}
diff --git a/core/src/main/java/org/elasticsearch/action/bulk/TransportShardBulkAction.java b/core/src/main/java/org/elasticsearch/action/bulk/TransportShardBulkAction.java
index 09157f7ba4c..70b3e1d7ac5 100644
--- a/core/src/main/java/org/elasticsearch/action/bulk/TransportShardBulkAction.java
+++ b/core/src/main/java/org/elasticsearch/action/bulk/TransportShardBulkAction.java
@@ -36,6 +36,7 @@ import org.elasticsearch.cluster.ClusterService;
import org.elasticsearch.cluster.ClusterState;
import org.elasticsearch.cluster.action.index.MappingUpdatedAction;
import org.elasticsearch.cluster.action.shard.ShardStateAction;
+import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
import org.elasticsearch.cluster.metadata.MappingMetaData;
import org.elasticsearch.cluster.routing.ShardIterator;
import org.elasticsearch.common.bytes.BytesReference;
@@ -78,9 +79,10 @@ public class TransportShardBulkAction extends TransportReplicationAction> routingMap = clusterState.metaData().resolveSearchRouting(request.routing(), request.indices());
- return clusterService.operationRouting().searchShards(clusterState, request.indices(), concreteIndices, routingMap, request.preference());
+ Map> routingMap = indexNameExpressionResolver.resolveSearchRouting(clusterState, request.routing(), request.indices());
+ return clusterService.operationRouting().searchShards(clusterState, concreteIndices, routingMap, request.preference());
}
@Override
@@ -151,7 +154,9 @@ public class TransportExistsAction extends TransportBroadcastAction, ToXContent {
@@ -40,17 +43,17 @@ public class MultiGetResponse extends ActionResponse implements Iterablenull if there was error.
- */
- @Nullable
- public PercolateResponse response() {
- return response;
- }
-
- /**
- * @return An error description if there was an error or null
if the percolate request was successful
- */
- @Nullable
- public String errorMessage() {
- return errorMessage;
- }
/**
* @return The percolator response or null
if there was error.
@@ -154,7 +138,7 @@ public class MultiPercolateResponse extends ActionResponse implements Iterablefalse is returned.
*/
public boolean isFailure() {
- return errorMessage != null;
+ return throwable != null;
+ }
+
+ public Throwable getFailure() {
+ return throwable;
}
@Override
@@ -171,7 +159,7 @@ public class MultiPercolateResponse extends ActionResponse implements Iterable> routing = clusterState.metaData().resolveSearchRouting(percolateRequest.routing(), percolateRequest.indices());
+ Map> routing = indexNameExpressionResolver.resolveSearchRouting(clusterState, percolateRequest.routing(), percolateRequest.indices());
// TODO: I only need shardIds, ShardIterator(ShardRouting) is only needed in TransportShardMultiPercolateAction
GroupShardsIterator shards = clusterService.operationRouting().searchShards(
- clusterState, percolateRequest.indices(), concreteIndices, routing, percolateRequest.preference()
+ clusterState, concreteIndices, routing, percolateRequest.preference()
);
if (shards.size() == 0) {
reducedResponses.set(slot, new UnavailableShardsException(null, "No shards available"));
@@ -184,7 +184,7 @@ public class TransportMultiPercolateAction extends HandledTransportAction> routingMap = clusterState.metaData().resolveSearchRouting(request.routing(), request.indices());
- return clusterService.operationRouting().searchShards(clusterState, request.indices(), concreteIndices, routingMap, request.preference());
+ Map> routingMap = indexNameExpressionResolver.resolveSearchRouting(clusterState, request.routing(), request.indices());
+ return clusterService.operationRouting().searchShards(clusterState, concreteIndices, routingMap, request.preference());
}
@Override
diff --git a/core/src/main/java/org/elasticsearch/action/percolate/TransportShardMultiPercolateAction.java b/core/src/main/java/org/elasticsearch/action/percolate/TransportShardMultiPercolateAction.java
index adca1883470..036197d483d 100644
--- a/core/src/main/java/org/elasticsearch/action/percolate/TransportShardMultiPercolateAction.java
+++ b/core/src/main/java/org/elasticsearch/action/percolate/TransportShardMultiPercolateAction.java
@@ -30,6 +30,7 @@ import org.elasticsearch.action.support.single.shard.SingleShardRequest;
import org.elasticsearch.action.support.single.shard.TransportSingleShardAction;
import org.elasticsearch.cluster.ClusterService;
import org.elasticsearch.cluster.ClusterState;
+import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
import org.elasticsearch.cluster.routing.ShardIterator;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.io.stream.StreamInput;
@@ -56,8 +57,10 @@ public class TransportShardMultiPercolateAction extends TransportSingleShardActi
private static final String ACTION_NAME = MultiPercolateAction.NAME + "[shard]";
@Inject
- public TransportShardMultiPercolateAction(Settings settings, ThreadPool threadPool, ClusterService clusterService, TransportService transportService, PercolatorService percolatorService, ActionFilters actionFilters) {
- super(settings, ACTION_NAME, threadPool, clusterService, transportService, actionFilters,
+ public TransportShardMultiPercolateAction(Settings settings, ThreadPool threadPool, ClusterService clusterService,
+ TransportService transportService, PercolatorService percolatorService,
+ ActionFilters actionFilters, IndexNameExpressionResolver indexNameExpressionResolver) {
+ super(settings, ACTION_NAME, threadPool, clusterService, transportService, actionFilters, indexNameExpressionResolver,
Request.class, ThreadPool.Names.PERCOLATE);
this.percolatorService = percolatorService;
}
diff --git a/core/src/main/java/org/elasticsearch/action/search/MultiSearchResponse.java b/core/src/main/java/org/elasticsearch/action/search/MultiSearchResponse.java
index 0d7ae75d66f..80745652be3 100644
--- a/core/src/main/java/org/elasticsearch/action/search/MultiSearchResponse.java
+++ b/core/src/main/java/org/elasticsearch/action/search/MultiSearchResponse.java
@@ -154,27 +154,13 @@ public class MultiSearchResponse extends ActionResponse implements Iterable> routingMap = clusterState.metaData().resolveSearchRouting(searchRequest.routing(), searchRequest.indices());
- int shardCount = clusterService.operationRouting().searchShardsCount(clusterState, searchRequest.indices(), concreteIndices, routingMap, searchRequest.preference());
+ String[] concreteIndices = indexNameExpressionResolver.concreteIndices(clusterState, searchRequest);
+ Map> routingMap = indexNameExpressionResolver.resolveSearchRouting(clusterState, searchRequest.routing(), searchRequest.indices());
+ int shardCount = clusterService.operationRouting().searchShardsCount(clusterState, concreteIndices, routingMap);
if (shardCount == 1) {
// if we only have one group, then we always want Q_A_F, no need for DFS, and no need to do THEN since we hit one shard
searchRequest.searchType(QUERY_AND_FETCH);
}
- } catch (IndexMissingException|IndexClosedException e) {
+ } catch (IndexNotFoundException | IndexClosedException e) {
// ignore these failures, we will notify the search response if its really the case from the actual action
} catch (Exception e) {
logger.debug("failed to optimize search type, continue as normal", e);
diff --git a/core/src/main/java/org/elasticsearch/action/search/TransportSearchScrollAction.java b/core/src/main/java/org/elasticsearch/action/search/TransportSearchScrollAction.java
index 0a36b6664e8..97b9f6e8082 100644
--- a/core/src/main/java/org/elasticsearch/action/search/TransportSearchScrollAction.java
+++ b/core/src/main/java/org/elasticsearch/action/search/TransportSearchScrollAction.java
@@ -26,6 +26,7 @@ import org.elasticsearch.action.search.type.TransportSearchScrollQueryThenFetchA
import org.elasticsearch.action.search.type.TransportSearchScrollScanAction;
import org.elasticsearch.action.support.ActionFilters;
import org.elasticsearch.action.support.HandledTransportAction;
+import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.threadpool.ThreadPool;
@@ -47,8 +48,9 @@ public class TransportSearchScrollAction extends HandledTransportAction> routingMap = clusterState.metaData().resolveSearchRouting(request.routing(), request.indices());
+ Map> routingMap = indexNameExpressionResolver.resolveSearchRouting(clusterState, request.routing(), request.indices());
- shardsIts = clusterService.operationRouting().searchShards(clusterState, request.indices(), concreteIndices, routingMap, request.preference());
+ shardsIts = clusterService.operationRouting().searchShards(clusterState, concreteIndices, routingMap, request.preference());
expectedSuccessfulOps = shardsIts.size();
// we need to add 1 for non active partition, since we count it in the total!
expectedTotalOps = shardsIts.totalSizeWith1ForEmpty();
@@ -157,7 +159,7 @@ public abstract class TransportSearchTypeAction extends TransportAction() {
@Override
public void onResponse(FirstResult result) {
diff --git a/core/src/main/java/org/elasticsearch/action/suggest/TransportSuggestAction.java b/core/src/main/java/org/elasticsearch/action/suggest/TransportSuggestAction.java
index 27caf314b0d..2269856c072 100644
--- a/core/src/main/java/org/elasticsearch/action/suggest/TransportSuggestAction.java
+++ b/core/src/main/java/org/elasticsearch/action/suggest/TransportSuggestAction.java
@@ -29,6 +29,7 @@ import org.elasticsearch.cluster.ClusterService;
import org.elasticsearch.cluster.ClusterState;
import org.elasticsearch.cluster.block.ClusterBlockException;
import org.elasticsearch.cluster.block.ClusterBlockLevel;
+import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
import org.elasticsearch.cluster.routing.GroupShardsIterator;
import org.elasticsearch.cluster.routing.ShardRouting;
import org.elasticsearch.common.bytes.BytesReference;
@@ -65,8 +66,9 @@ public class TransportSuggestAction extends TransportBroadcastAction> routingMap = clusterState.metaData().resolveSearchRouting(request.routing(), request.indices());
- return clusterService.operationRouting().searchShards(clusterState, request.indices(), concreteIndices, routingMap, request.preference());
+ Map> routingMap = indexNameExpressionResolver.resolveSearchRouting(clusterState, request.routing(), request.indices());
+ return clusterService.operationRouting().searchShards(clusterState, concreteIndices, routingMap, request.preference());
}
@Override
diff --git a/core/src/main/java/org/elasticsearch/action/support/DefaultShardOperationFailedException.java b/core/src/main/java/org/elasticsearch/action/support/DefaultShardOperationFailedException.java
index 313692d75b1..17d8bcfb998 100644
--- a/core/src/main/java/org/elasticsearch/action/support/DefaultShardOperationFailedException.java
+++ b/core/src/main/java/org/elasticsearch/action/support/DefaultShardOperationFailedException.java
@@ -24,9 +24,7 @@ import org.elasticsearch.ExceptionsHelper;
import org.elasticsearch.action.ShardOperationFailedException;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
-import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.common.xcontent.XContentBuilder;
-import org.elasticsearch.index.shard.IndexShardException;
import org.elasticsearch.rest.RestStatus;
import java.io.IOException;
@@ -46,12 +44,12 @@ public class DefaultShardOperationFailedException implements ShardOperationFaile
private RestStatus status;
- private DefaultShardOperationFailedException() {
+ protected DefaultShardOperationFailedException() {
}
- public DefaultShardOperationFailedException(IndexShardException e) {
- this.index = e.shardId().index().name();
- this.shardId = e.shardId().id();
+ public DefaultShardOperationFailedException(ElasticsearchException e) {
+ this.index = e.getIndex();
+ this.shardId = e.getShardId().id();
this.reason = e;
this.status = e.status();
}
diff --git a/core/src/main/java/org/elasticsearch/action/support/HandledTransportAction.java b/core/src/main/java/org/elasticsearch/action/support/HandledTransportAction.java
index 001b410842e..e92eff3f29d 100644
--- a/core/src/main/java/org/elasticsearch/action/support/HandledTransportAction.java
+++ b/core/src/main/java/org/elasticsearch/action/support/HandledTransportAction.java
@@ -21,6 +21,7 @@ package org.elasticsearch.action.support;
import org.elasticsearch.action.ActionListener;
import org.elasticsearch.action.ActionRequest;
import org.elasticsearch.action.ActionResponse;
+import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.threadpool.ThreadPool;
import org.elasticsearch.transport.TransportChannel;
@@ -32,8 +33,8 @@ import org.elasticsearch.transport.TransportService;
*/
public abstract class HandledTransportAction extends TransportAction{
- protected HandledTransportAction(Settings settings, String actionName, ThreadPool threadPool, TransportService transportService, ActionFilters actionFilters, Class request) {
- super(settings, actionName, threadPool, actionFilters);
+ protected HandledTransportAction(Settings settings, String actionName, ThreadPool threadPool, TransportService transportService, ActionFilters actionFilters, IndexNameExpressionResolver indexNameExpressionResolver, Class request) {
+ super(settings, actionName, threadPool, actionFilters, indexNameExpressionResolver);
transportService.registerRequestHandler(actionName, request, ThreadPool.Names.SAME, new TransportHandler());
}
diff --git a/core/src/main/java/org/elasticsearch/action/support/TransportAction.java b/core/src/main/java/org/elasticsearch/action/support/TransportAction.java
index cc349332ac9..d278a992e93 100644
--- a/core/src/main/java/org/elasticsearch/action/support/TransportAction.java
+++ b/core/src/main/java/org/elasticsearch/action/support/TransportAction.java
@@ -20,6 +20,7 @@
package org.elasticsearch.action.support;
import org.elasticsearch.action.*;
+import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
import org.elasticsearch.common.ParseFieldMatcher;
import org.elasticsearch.common.component.AbstractComponent;
import org.elasticsearch.common.logging.ESLogger;
@@ -39,13 +40,16 @@ public abstract class TransportAction execute(Request request) {
diff --git a/core/src/main/java/org/elasticsearch/action/support/TransportActions.java b/core/src/main/java/org/elasticsearch/action/support/TransportActions.java
index 0b4b72befb5..1de3ef1aea8 100644
--- a/core/src/main/java/org/elasticsearch/action/support/TransportActions.java
+++ b/core/src/main/java/org/elasticsearch/action/support/TransportActions.java
@@ -21,9 +21,9 @@ package org.elasticsearch.action.support;
import org.elasticsearch.ExceptionsHelper;
import org.elasticsearch.action.NoShardAvailableActionException;
-import org.elasticsearch.index.IndexShardMissingException;
+import org.elasticsearch.index.IndexNotFoundException;
import org.elasticsearch.index.shard.IllegalIndexShardStateException;
-import org.elasticsearch.indices.IndexMissingException;
+import org.elasticsearch.index.shard.ShardNotFoundException;
/**
*/
@@ -31,16 +31,10 @@ public class TransportActions {
public static boolean isShardNotAvailableException(Throwable t) {
Throwable actual = ExceptionsHelper.unwrapCause(t);
- if (actual instanceof IllegalIndexShardStateException) {
- return true;
- }
- if (actual instanceof IndexMissingException) {
- return true;
- }
- if (actual instanceof IndexShardMissingException) {
- return true;
- }
- if (actual instanceof NoShardAvailableActionException) {
+ if (actual instanceof ShardNotFoundException ||
+ actual instanceof IndexNotFoundException ||
+ actual instanceof IllegalIndexShardStateException ||
+ actual instanceof NoShardAvailableActionException) {
return true;
}
return false;
diff --git a/core/src/main/java/org/elasticsearch/action/support/broadcast/BroadcastShardOperationFailedException.java b/core/src/main/java/org/elasticsearch/action/support/broadcast/BroadcastShardOperationFailedException.java
index ca761470e21..fb42c7a6e42 100644
--- a/core/src/main/java/org/elasticsearch/action/support/broadcast/BroadcastShardOperationFailedException.java
+++ b/core/src/main/java/org/elasticsearch/action/support/broadcast/BroadcastShardOperationFailedException.java
@@ -19,9 +19,9 @@
package org.elasticsearch.action.support.broadcast;
+import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.ElasticsearchWrapperException;
import org.elasticsearch.common.io.stream.StreamInput;
-import org.elasticsearch.index.shard.IndexShardException;
import org.elasticsearch.index.shard.ShardId;
import java.io.IOException;
@@ -31,18 +31,19 @@ import java.io.IOException;
*
*
*/
-public class BroadcastShardOperationFailedException extends IndexShardException implements ElasticsearchWrapperException {
+public class BroadcastShardOperationFailedException extends ElasticsearchException implements ElasticsearchWrapperException {
public BroadcastShardOperationFailedException(ShardId shardId, String msg) {
- super(shardId, msg, null);
+ this(shardId, msg, null);
}
public BroadcastShardOperationFailedException(ShardId shardId, Throwable cause) {
- super(shardId, "", cause);
+ this(shardId, "", cause);
}
public BroadcastShardOperationFailedException(ShardId shardId, String msg, Throwable cause) {
- super(shardId, msg, cause);
+ super(msg, cause);
+ setShard(shardId);
}
public BroadcastShardOperationFailedException(StreamInput in) throws IOException{
diff --git a/core/src/main/java/org/elasticsearch/action/support/broadcast/TransportBroadcastAction.java b/core/src/main/java/org/elasticsearch/action/support/broadcast/TransportBroadcastAction.java
index c77f3ec766b..dcb6952dc35 100644
--- a/core/src/main/java/org/elasticsearch/action/support/broadcast/TransportBroadcastAction.java
+++ b/core/src/main/java/org/elasticsearch/action/support/broadcast/TransportBroadcastAction.java
@@ -27,6 +27,7 @@ import org.elasticsearch.action.support.TransportActions;
import org.elasticsearch.cluster.ClusterService;
import org.elasticsearch.cluster.ClusterState;
import org.elasticsearch.cluster.block.ClusterBlockException;
+import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
import org.elasticsearch.cluster.node.DiscoveryNode;
import org.elasticsearch.cluster.node.DiscoveryNodes;
import org.elasticsearch.cluster.routing.GroupShardsIterator;
@@ -52,9 +53,10 @@ public abstract class TransportBroadcastAction request, Class shardRequest, String shardExecutor) {
- super(settings, actionName, threadPool, transportService, actionFilters, request);
+ super(settings, actionName, threadPool, transportService, actionFilters, indexNameExpressionResolver, request);
this.clusterService = clusterService;
this.transportService = transportService;
this.threadPool = threadPool;
@@ -108,7 +110,7 @@ public abstract class TransportBroadcastAction request) {
- super(settings, actionName, threadPool, transportService, actionFilters, request);
+ protected TransportMasterNodeAction(Settings settings, String actionName, TransportService transportService,
+ ClusterService clusterService, ThreadPool threadPool, ActionFilters actionFilters,
+ IndexNameExpressionResolver indexNameExpressionResolver, Class request) {
+ super(settings, actionName, threadPool, transportService, actionFilters, indexNameExpressionResolver, request);
this.transportService = transportService;
this.clusterService = clusterService;
this.executor = executor();
diff --git a/core/src/main/java/org/elasticsearch/action/support/master/TransportMasterNodeReadAction.java b/core/src/main/java/org/elasticsearch/action/support/master/TransportMasterNodeReadAction.java
index c33b9fde774..3faeb50bba2 100644
--- a/core/src/main/java/org/elasticsearch/action/support/master/TransportMasterNodeReadAction.java
+++ b/core/src/main/java/org/elasticsearch/action/support/master/TransportMasterNodeReadAction.java
@@ -22,6 +22,7 @@ package org.elasticsearch.action.support.master;
import org.elasticsearch.action.ActionResponse;
import org.elasticsearch.action.support.ActionFilters;
import org.elasticsearch.cluster.ClusterService;
+import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.threadpool.ThreadPool;
import org.elasticsearch.transport.TransportService;
@@ -36,8 +37,10 @@ public abstract class TransportMasterNodeReadAction request) {
- super(settings, actionName, transportService, clusterService, threadPool, actionFilters,request);
+ protected TransportMasterNodeReadAction(Settings settings, String actionName, TransportService transportService,
+ ClusterService clusterService, ThreadPool threadPool, ActionFilters actionFilters,
+ IndexNameExpressionResolver indexNameExpressionResolver, Class request) {
+ super(settings, actionName, transportService, clusterService, threadPool, actionFilters, indexNameExpressionResolver,request);
this.forceLocal = settings.getAsBoolean(FORCE_LOCAL_SETTING, null);
}
diff --git a/core/src/main/java/org/elasticsearch/action/support/master/info/TransportClusterInfoAction.java b/core/src/main/java/org/elasticsearch/action/support/master/info/TransportClusterInfoAction.java
index d1bdb86e1bb..560a699ddf1 100644
--- a/core/src/main/java/org/elasticsearch/action/support/master/info/TransportClusterInfoAction.java
+++ b/core/src/main/java/org/elasticsearch/action/support/master/info/TransportClusterInfoAction.java
@@ -24,6 +24,7 @@ import org.elasticsearch.action.support.ActionFilters;
import org.elasticsearch.action.support.master.TransportMasterNodeReadAction;
import org.elasticsearch.cluster.ClusterService;
import org.elasticsearch.cluster.ClusterState;
+import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.threadpool.ThreadPool;
import org.elasticsearch.transport.TransportService;
@@ -32,8 +33,10 @@ import org.elasticsearch.transport.TransportService;
*/
public abstract class TransportClusterInfoAction extends TransportMasterNodeReadAction {
- public TransportClusterInfoAction(Settings settings, String actionName, TransportService transportService, ClusterService clusterService, ThreadPool threadPool, ActionFilters actionFilters, Class request) {
- super(settings, actionName, transportService, clusterService, threadPool, actionFilters, request);
+ public TransportClusterInfoAction(Settings settings, String actionName, TransportService transportService,
+ ClusterService clusterService, ThreadPool threadPool, ActionFilters actionFilters,
+ IndexNameExpressionResolver indexNameExpressionResolver, Class request) {
+ super(settings, actionName, transportService, clusterService, threadPool, actionFilters, indexNameExpressionResolver, request);
}
@Override
@@ -44,7 +47,7 @@ public abstract class TransportClusterInfoAction listener) {
- String[] concreteIndices = state.metaData().concreteIndices(request.indicesOptions(), request.indices());
+ String[] concreteIndices = indexNameExpressionResolver.concreteIndices(state, request);
doMasterOperation(request, concreteIndices, state, listener);
}
diff --git a/core/src/main/java/org/elasticsearch/action/support/nodes/TransportNodesAction.java b/core/src/main/java/org/elasticsearch/action/support/nodes/TransportNodesAction.java
index 50e84379059..8383189f3ef 100644
--- a/core/src/main/java/org/elasticsearch/action/support/nodes/TransportNodesAction.java
+++ b/core/src/main/java/org/elasticsearch/action/support/nodes/TransportNodesAction.java
@@ -27,6 +27,7 @@ import org.elasticsearch.action.support.HandledTransportAction;
import org.elasticsearch.cluster.ClusterName;
import org.elasticsearch.cluster.ClusterService;
import org.elasticsearch.cluster.ClusterState;
+import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
import org.elasticsearch.cluster.node.DiscoveryNode;
import org.elasticsearch.cluster.node.DiscoveryNodes;
import org.elasticsearch.common.settings.Settings;
@@ -49,8 +50,9 @@ public abstract class TransportNodesAction request, Class nodeRequest, String nodeExecutor) {
- super(settings, actionName, threadPool, transportService, actionFilters, request);
+ IndexNameExpressionResolver indexNameExpressionResolver, Class request, Class nodeRequest,
+ String nodeExecutor) {
+ super(settings, actionName, threadPool, transportService, actionFilters, indexNameExpressionResolver, request);
this.clusterName = clusterName;
this.clusterService = clusterService;
this.transportService = transportService;
diff --git a/core/src/main/java/org/elasticsearch/action/support/replication/TransportReplicationAction.java b/core/src/main/java/org/elasticsearch/action/support/replication/TransportReplicationAction.java
index cac18813cfd..2e538385cb2 100644
--- a/core/src/main/java/org/elasticsearch/action/support/replication/TransportReplicationAction.java
+++ b/core/src/main/java/org/elasticsearch/action/support/replication/TransportReplicationAction.java
@@ -19,6 +19,7 @@
package org.elasticsearch.action.support.replication;
+import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.ExceptionsHelper;
import org.elasticsearch.action.ActionListener;
import org.elasticsearch.action.ActionWriteResponse;
@@ -39,6 +40,7 @@ import org.elasticsearch.cluster.action.shard.ShardStateAction;
import org.elasticsearch.cluster.block.ClusterBlockException;
import org.elasticsearch.cluster.block.ClusterBlockLevel;
import org.elasticsearch.cluster.metadata.IndexMetaData;
+import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
import org.elasticsearch.cluster.node.DiscoveryNode;
import org.elasticsearch.cluster.routing.*;
import org.elasticsearch.common.Nullable;
@@ -57,7 +59,6 @@ import org.elasticsearch.index.engine.VersionConflictEngineException;
import org.elasticsearch.index.mapper.Mapping;
import org.elasticsearch.index.mapper.SourceToParse;
import org.elasticsearch.index.shard.IndexShard;
-import org.elasticsearch.index.shard.IndexShardException;
import org.elasticsearch.index.shard.ShardId;
import org.elasticsearch.index.translog.Translog;
import org.elasticsearch.indices.IndicesService;
@@ -92,8 +93,9 @@ public abstract class TransportReplicationAction request, Class replicaRequest, String executor) {
- super(settings, actionName, threadPool, actionFilters);
+ IndexNameExpressionResolver indexNameExpressionResolver, Class request,
+ Class replicaRequest, String executor) {
+ super(settings, actionName, threadPool, actionFilters, indexNameExpressionResolver);
this.transportService = transportService;
this.clusterService = clusterService;
this.indicesService = indicesService;
@@ -240,10 +242,11 @@ public abstract class TransportReplicationAction request, String executor) {
- super(settings, actionName, threadPool, transportService, actionFilters, request);
+ super(settings, actionName, threadPool, transportService, actionFilters, indexNameExpressionResolver, request);
this.clusterService = clusterService;
this.transportService = transportService;
@@ -110,7 +113,7 @@ public abstract class TransportSingleCustomOperationAction request) {
- super(settings, actionName, threadPool, transportService, actionFilters, request);
+ protected TransportInstanceSingleOperationAction(Settings settings, String actionName, ThreadPool threadPool,
+ ClusterService clusterService, TransportService transportService,
+ ActionFilters actionFilters, IndexNameExpressionResolver indexNameExpressionResolver, Class request) {
+ super(settings, actionName, threadPool, transportService, actionFilters, indexNameExpressionResolver, request);
this.clusterService = clusterService;
this.transportService = transportService;
this.executor = executor();
@@ -128,7 +131,7 @@ public abstract class TransportInstanceSingleOperationAction request, String executor) {
- super(settings, actionName, threadPool, actionFilters);
+ super(settings, actionName, threadPool, actionFilters, indexNameExpressionResolver);
this.clusterService = clusterService;
this.transportService = transportService;
@@ -125,7 +127,7 @@ public abstract class TransportSingleShardAction> routingMap = clusterState.metaData().resolveSearchRouting(request.routing(), request.indices());
- return clusterService.operationRouting().searchShards(clusterState, request.indices(), concreteIndices, routingMap, request.preference());
+ Map> routingMap = indexNameExpressionResolver.resolveSearchRouting(clusterState, request.routing(), request.indices());
+ return clusterService.operationRouting().searchShards(clusterState, concreteIndices, routingMap, request.preference());
}
@Override
diff --git a/core/src/main/java/org/elasticsearch/action/update/TransportUpdateAction.java b/core/src/main/java/org/elasticsearch/action/update/TransportUpdateAction.java
index e14d687a860..1bc6ddd5a0e 100644
--- a/core/src/main/java/org/elasticsearch/action/update/TransportUpdateAction.java
+++ b/core/src/main/java/org/elasticsearch/action/update/TransportUpdateAction.java
@@ -39,6 +39,7 @@ import org.elasticsearch.action.support.TransportActions;
import org.elasticsearch.action.support.single.instance.TransportInstanceSingleOperationAction;
import org.elasticsearch.cluster.ClusterService;
import org.elasticsearch.cluster.ClusterState;
+import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
import org.elasticsearch.cluster.routing.PlainShardIterator;
import org.elasticsearch.cluster.routing.ShardIterator;
import org.elasticsearch.cluster.routing.ShardRouting;
@@ -73,8 +74,9 @@ public class TransportUpdateAction extends TransportInstanceSingleOperationActio
@Inject
public TransportUpdateAction(Settings settings, ThreadPool threadPool, ClusterService clusterService, TransportService transportService,
TransportIndexAction indexAction, TransportDeleteAction deleteAction, TransportCreateIndexAction createIndexAction,
- UpdateHelper updateHelper, ActionFilters actionFilters, IndicesService indicesService) {
- super(settings, UpdateAction.NAME, threadPool, clusterService, transportService, actionFilters, UpdateRequest.class);
+ UpdateHelper updateHelper, ActionFilters actionFilters, IndexNameExpressionResolver indexNameExpressionResolver,
+ IndicesService indicesService) {
+ super(settings, UpdateAction.NAME, threadPool, clusterService, transportService, actionFilters, indexNameExpressionResolver, UpdateRequest.class);
this.indexAction = indexAction;
this.deleteAction = deleteAction;
this.createIndexAction = createIndexAction;
diff --git a/core/src/main/java/org/elasticsearch/bootstrap/JarHell.java b/core/src/main/java/org/elasticsearch/bootstrap/JarHell.java
index c27d81abbeb..dd3ea21c5ef 100644
--- a/core/src/main/java/org/elasticsearch/bootstrap/JarHell.java
+++ b/core/src/main/java/org/elasticsearch/bootstrap/JarHell.java
@@ -19,6 +19,7 @@
package org.elasticsearch.bootstrap;
+import org.elasticsearch.Version;
import org.elasticsearch.common.SuppressForbidden;
import org.elasticsearch.common.io.PathUtils;
import org.elasticsearch.common.logging.ESLogger;
@@ -27,7 +28,6 @@ import org.elasticsearch.common.logging.Loggers;
import java.io.IOException;
import java.net.URL;
import java.net.URLClassLoader;
-import java.net.URLDecoder;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
@@ -90,7 +90,7 @@ public class JarHell {
logger.debug("excluding system resource: {}", path);
continue;
}
- if (path.endsWith(".jar")) {
+ if (path.toString().endsWith(".jar")) {
if (!seenJars.add(path)) {
logger.debug("excluding duplicate classpath element: {}", path);
continue; // we can't fail because of sheistiness with joda-time
@@ -99,23 +99,7 @@ public class JarHell {
try (JarFile file = new JarFile(path.toString())) {
Manifest manifest = file.getManifest();
if (manifest != null) {
- // inspect Manifest: give a nice error if jar requires a newer java version
- String systemVersion = System.getProperty("java.specification.version");
- String targetVersion = manifest.getMainAttributes().getValue("X-Compile-Target-JDK");
- if (targetVersion != null) {
- float current = Float.POSITIVE_INFINITY;
- float target = Float.NEGATIVE_INFINITY;
- try {
- current = Float.parseFloat(systemVersion);
- target = Float.parseFloat(targetVersion);
- } catch (NumberFormatException e) {
- // some spec changed, time for a more complex parser
- }
- if (current < target) {
- throw new IllegalStateException(path + " requires Java " + targetVersion
- + ", your system: " + systemVersion);
- }
- }
+ checkManifest(manifest, path);
}
// inspect entries
Enumeration elements = file.entries();
@@ -149,6 +133,35 @@ public class JarHell {
}
}
+ /** inspect manifest for sure incompatibilities */
+ static void checkManifest(Manifest manifest, Path jar) {
+ // give a nice error if jar requires a newer java version
+ String systemVersion = System.getProperty("java.specification.version");
+ String targetVersion = manifest.getMainAttributes().getValue("X-Compile-Target-JDK");
+ if (targetVersion != null) {
+ float current = Float.POSITIVE_INFINITY;
+ float target = Float.NEGATIVE_INFINITY;
+ try {
+ current = Float.parseFloat(systemVersion);
+ target = Float.parseFloat(targetVersion);
+ } catch (NumberFormatException e) {
+ // some spec changed, time for a more complex parser
+ }
+ if (current < target) {
+ throw new IllegalStateException(jar + " requires Java " + targetVersion
+ + ", your system: " + systemVersion);
+ }
+ }
+
+ // give a nice error if jar is compiled against different es version
+ String systemESVersion = Version.CURRENT.toString();
+ String targetESVersion = manifest.getMainAttributes().getValue("X-Compile-Elasticsearch-Version");
+ if (targetESVersion != null && targetESVersion.equals(systemESVersion) == false) {
+ throw new IllegalStateException(jar + " requires Elasticsearch " + targetESVersion
+ + ", your system: " + systemESVersion);
+ }
+ }
+
static void checkClass(Map clazzes, String clazz, Path jarpath) {
Path previous = clazzes.put(clazz, jarpath);
if (previous != null) {
diff --git a/core/src/main/java/org/elasticsearch/client/IndicesAdminClient.java b/core/src/main/java/org/elasticsearch/client/IndicesAdminClient.java
index 7ab5078b04b..755bf333e59 100644
--- a/core/src/main/java/org/elasticsearch/client/IndicesAdminClient.java
+++ b/core/src/main/java/org/elasticsearch/client/IndicesAdminClient.java
@@ -81,6 +81,9 @@ import org.elasticsearch.action.admin.indices.settings.get.GetSettingsResponse;
import org.elasticsearch.action.admin.indices.settings.put.UpdateSettingsRequest;
import org.elasticsearch.action.admin.indices.settings.put.UpdateSettingsRequestBuilder;
import org.elasticsearch.action.admin.indices.settings.put.UpdateSettingsResponse;
+import org.elasticsearch.action.admin.indices.shards.IndicesShardStoreRequestBuilder;
+import org.elasticsearch.action.admin.indices.shards.IndicesShardStoresResponse;
+import org.elasticsearch.action.admin.indices.shards.IndicesShardStoresRequest;
import org.elasticsearch.action.admin.indices.stats.IndicesStatsRequest;
import org.elasticsearch.action.admin.indices.stats.IndicesStatsRequestBuilder;
import org.elasticsearch.action.admin.indices.stats.IndicesStatsResponse;
@@ -221,6 +224,29 @@ public interface IndicesAdminClient extends ElasticsearchClient {
*/
IndicesSegmentsRequestBuilder prepareSegments(String... indices);
+ /**
+ * The shard stores info of one or more indices.
+ *
+ * @param request The indices shard stores request
+ * @return The result future
+ * @see Requests#indicesShardStoresRequest(String...)
+ */
+ ActionFuture shardStores(IndicesShardStoresRequest request);
+
+ /**
+ * The shard stores info of one or more indices.
+ *
+ * @param request The indices shard stores request
+ * @param listener A listener to be notified with a result
+ * @see Requests#indicesShardStoresRequest(String...)
+ */
+ void shardStores(IndicesShardStoresRequest request, ActionListener listener);
+
+ /**
+ * The shard stores info of one or more indices.
+ */
+ IndicesShardStoreRequestBuilder prepareShardStores(String... indices);
+
/**
* Creates an index using an explicit request allowing to specify the settings of the index.
*
diff --git a/core/src/main/java/org/elasticsearch/client/Requests.java b/core/src/main/java/org/elasticsearch/client/Requests.java
index 8a70c18b374..e36c26923d8 100644
--- a/core/src/main/java/org/elasticsearch/client/Requests.java
+++ b/core/src/main/java/org/elasticsearch/client/Requests.java
@@ -49,6 +49,7 @@ import org.elasticsearch.action.admin.indices.optimize.OptimizeRequest;
import org.elasticsearch.action.admin.indices.refresh.RefreshRequest;
import org.elasticsearch.action.admin.indices.segments.IndicesSegmentsRequest;
import org.elasticsearch.action.admin.indices.settings.put.UpdateSettingsRequest;
+import org.elasticsearch.action.admin.indices.shards.IndicesShardStoresRequest;
import org.elasticsearch.action.admin.indices.upgrade.post.UpgradeRequest;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.count.CountRequest;
@@ -184,6 +185,15 @@ public class Requests {
return new IndicesSegmentsRequest(indices);
}
+ /**
+ * Creates an indices shard stores info request.
+ * @param indices The indices to get shard store information on
+ * @return The indices shard stores request
+ * @see org.elasticsearch.client.IndicesAdminClient#shardStores(IndicesShardStoresRequest)
+ */
+ public static IndicesShardStoresRequest indicesShardStoresRequest(String... indices) {
+ return new IndicesShardStoresRequest(indices);
+ }
/**
* Creates an indices exists request.
*
diff --git a/core/src/main/java/org/elasticsearch/client/support/AbstractClient.java b/core/src/main/java/org/elasticsearch/client/support/AbstractClient.java
index a4d271dc599..f9abf2f0437 100644
--- a/core/src/main/java/org/elasticsearch/client/support/AbstractClient.java
+++ b/core/src/main/java/org/elasticsearch/client/support/AbstractClient.java
@@ -176,6 +176,10 @@ import org.elasticsearch.action.admin.indices.settings.put.UpdateSettingsAction;
import org.elasticsearch.action.admin.indices.settings.put.UpdateSettingsRequest;
import org.elasticsearch.action.admin.indices.settings.put.UpdateSettingsRequestBuilder;
import org.elasticsearch.action.admin.indices.settings.put.UpdateSettingsResponse;
+import org.elasticsearch.action.admin.indices.shards.IndicesShardStoreRequestBuilder;
+import org.elasticsearch.action.admin.indices.shards.IndicesShardStoresResponse;
+import org.elasticsearch.action.admin.indices.shards.IndicesShardStoresAction;
+import org.elasticsearch.action.admin.indices.shards.IndicesShardStoresRequest;
import org.elasticsearch.action.admin.indices.stats.IndicesStatsAction;
import org.elasticsearch.action.admin.indices.stats.IndicesStatsRequest;
import org.elasticsearch.action.admin.indices.stats.IndicesStatsRequestBuilder;
@@ -1498,6 +1502,21 @@ public abstract class AbstractClient extends AbstractComponent implements Client
return new IndicesSegmentsRequestBuilder(this, IndicesSegmentsAction.INSTANCE).setIndices(indices);
}
+ @Override
+ public ActionFuture shardStores(IndicesShardStoresRequest request) {
+ return execute(IndicesShardStoresAction.INSTANCE, request);
+ }
+
+ @Override
+ public void shardStores(IndicesShardStoresRequest request, ActionListener listener) {
+ execute(IndicesShardStoresAction.INSTANCE, request, listener);
+ }
+
+ @Override
+ public IndicesShardStoreRequestBuilder prepareShardStores(String... indices) {
+ return new IndicesShardStoreRequestBuilder(this, IndicesShardStoresAction.INSTANCE, indices);
+ }
+
@Override
public ActionFuture updateSettings(final UpdateSettingsRequest request) {
return execute(UpdateSettingsAction.INSTANCE, request);
diff --git a/core/src/main/java/org/elasticsearch/cluster/ClusterModule.java b/core/src/main/java/org/elasticsearch/cluster/ClusterModule.java
index d8e81d5a90a..b0b3c120c95 100644
--- a/core/src/main/java/org/elasticsearch/cluster/ClusterModule.java
+++ b/core/src/main/java/org/elasticsearch/cluster/ClusterModule.java
@@ -79,6 +79,7 @@ public class ClusterModule extends AbstractModule implements SpawnModules {
bind(MetaDataIndexAliasesService.class).asEagerSingleton();
bind(MetaDataUpdateSettingsService.class).asEagerSingleton();
bind(MetaDataIndexTemplateService.class).asEagerSingleton();
+ bind(IndexNameExpressionResolver.class).asEagerSingleton();
bind(RoutingService.class).asEagerSingleton();
diff --git a/core/src/main/java/org/elasticsearch/cluster/ClusterState.java b/core/src/main/java/org/elasticsearch/cluster/ClusterState.java
index ab44768d5a4..8fb86677487 100644
--- a/core/src/main/java/org/elasticsearch/cluster/ClusterState.java
+++ b/core/src/main/java/org/elasticsearch/cluster/ClusterState.java
@@ -76,7 +76,7 @@ import java.util.Map;
* to a node if this node was present in the previous version of the cluster state. If a node is not present was
* not present in the previous version of the cluster state, such node is unlikely to have the previous cluster
* state version and should be sent a complete version. In order to make sure that the differences are applied to
- * correct version of the cluster state, each cluster state version update generates {@link #uuid} that uniquely
+ * correct version of the cluster state, each cluster state version update generates {@link #stateUUID} that uniquely
* identifies this version of the state. This uuid is verified by the {@link ClusterStateDiff#apply} method to
* makes sure that the correct diffs are applied. If uuids don’t match, the {@link ClusterStateDiff#apply} method
* throws the {@link IncompatibleClusterStateVersionException}, which should cause the publishing mechanism to send
@@ -144,7 +144,7 @@ public class ClusterState implements ToXContent, Diffable {
private final long version;
- private final String uuid;
+ private final String stateUUID;
private final RoutingTable routingTable;
@@ -165,13 +165,13 @@ public class ClusterState implements ToXContent, Diffable {
private volatile ClusterStateStatus status;
- public ClusterState(long version, String uuid, ClusterState state) {
- this(state.clusterName, version, uuid, state.metaData(), state.routingTable(), state.nodes(), state.blocks(), state.customs(), false);
+ public ClusterState(long version, String stateUUID, ClusterState state) {
+ this(state.clusterName, version, stateUUID, state.metaData(), state.routingTable(), state.nodes(), state.blocks(), state.customs(), false);
}
- public ClusterState(ClusterName clusterName, long version, String uuid, MetaData metaData, RoutingTable routingTable, DiscoveryNodes nodes, ClusterBlocks blocks, ImmutableOpenMap customs, boolean wasReadFromDiff) {
+ public ClusterState(ClusterName clusterName, long version, String stateUUID, MetaData metaData, RoutingTable routingTable, DiscoveryNodes nodes, ClusterBlocks blocks, ImmutableOpenMap customs, boolean wasReadFromDiff) {
this.version = version;
- this.uuid = uuid;
+ this.stateUUID = stateUUID;
this.clusterName = clusterName;
this.metaData = metaData;
this.routingTable = routingTable;
@@ -200,11 +200,11 @@ public class ClusterState implements ToXContent, Diffable {
}
/**
- * This uuid is automatically generated for for each version of cluster state. It is used to make sure that
+ * This stateUUID is automatically generated for for each version of cluster state. It is used to make sure that
* we are applying diffs to the right previous state.
*/
- public String uuid() {
- return this.uuid;
+ public String stateUUID() {
+ return this.stateUUID;
}
public DiscoveryNodes nodes() {
@@ -283,7 +283,7 @@ public class ClusterState implements ToXContent, Diffable {
public String prettyPrint() {
StringBuilder sb = new StringBuilder();
sb.append("version: ").append(version).append("\n");
- sb.append("uuid: ").append(uuid).append("\n");
+ sb.append("state uuid: ").append(stateUUID).append("\n");
sb.append("from_diff: ").append(wasReadFromDiff).append("\n");
sb.append("meta data version: ").append(metaData.version()).append("\n");
sb.append(nodes().prettyPrint());
@@ -362,7 +362,7 @@ public class ClusterState implements ToXContent, Diffable {
if (metrics.contains(Metric.VERSION)) {
builder.field("version", version);
- builder.field("uuid", uuid);
+ builder.field("state_uuid", stateUUID);
}
if (metrics.contains(Metric.MASTER_NODE)) {
@@ -398,18 +398,8 @@ public class ClusterState implements ToXContent, Diffable {
// nodes
if (metrics.contains(Metric.NODES)) {
builder.startObject("nodes");
- for (DiscoveryNode node : nodes()) {
- builder.startObject(node.id(), XContentBuilder.FieldCaseConversion.NONE);
- builder.field("name", node.name());
- builder.field("transport_address", node.address().toString());
-
- builder.startObject("attributes");
- for (Map.Entry attr : node.attributes().entrySet()) {
- builder.field(attr.getKey(), attr.getValue());
- }
- builder.endObject();
-
- builder.endObject();
+ for (DiscoveryNode node : nodes) {
+ node.toXContent(builder, params);
}
builder.endObject();
}
@@ -417,7 +407,7 @@ public class ClusterState implements ToXContent, Diffable {
// meta data
if (metrics.contains(Metric.METADATA)) {
builder.startObject("metadata");
-
+ builder.field("cluster_uuid", metaData().clusterUUID());
builder.startObject("templates");
for (ObjectCursor cursor : metaData().templates().values()) {
IndexTemplateMetaData templateMetaData = cursor.value;
@@ -571,7 +561,7 @@ public class ClusterState implements ToXContent, Diffable {
public Builder(ClusterState state) {
this.clusterName = state.clusterName;
this.version = state.version();
- this.uuid = state.uuid();
+ this.uuid = state.stateUUID();
this.nodes = state.nodes();
this.routingTable = state.routingTable();
this.metaData = state.metaData();
@@ -637,7 +627,7 @@ public class ClusterState implements ToXContent, Diffable {
return this;
}
- public Builder uuid(String uuid) {
+ public Builder stateUUID(String uuid) {
this.uuid = uuid;
return this;
}
@@ -734,7 +724,7 @@ public class ClusterState implements ToXContent, Diffable {
public void writeTo(StreamOutput out) throws IOException {
clusterName.writeTo(out);
out.writeLong(version);
- out.writeString(uuid);
+ out.writeString(stateUUID);
metaData.writeTo(out);
routingTable.writeTo(out);
nodes.writeTo(out);
@@ -767,8 +757,8 @@ public class ClusterState implements ToXContent, Diffable {
private final Diff> customs;
public ClusterStateDiff(ClusterState before, ClusterState after) {
- fromUuid = before.uuid;
- toUuid = after.uuid;
+ fromUuid = before.stateUUID;
+ toUuid = after.stateUUID;
toVersion = after.version;
clusterName = after.clusterName;
routingTable = after.routingTable.diff(before.routingTable);
@@ -816,14 +806,14 @@ public class ClusterState implements ToXContent, Diffable {
@Override
public ClusterState apply(ClusterState state) {
Builder builder = new Builder(clusterName);
- if (toUuid.equals(state.uuid)) {
+ if (toUuid.equals(state.stateUUID)) {
// no need to read the rest - cluster state didn't change
return state;
}
- if (fromUuid.equals(state.uuid) == false) {
- throw new IncompatibleClusterStateVersionException(state.version, state.uuid, toVersion, fromUuid);
+ if (fromUuid.equals(state.stateUUID) == false) {
+ throw new IncompatibleClusterStateVersionException(state.version, state.stateUUID, toVersion, fromUuid);
}
- builder.uuid(toUuid);
+ builder.stateUUID(toUuid);
builder.version(toVersion);
builder.routingTable(routingTable.apply(state.routingTable));
builder.nodes(nodes.apply(state.nodes));
diff --git a/core/src/main/java/org/elasticsearch/cluster/action/shard/ShardStateAction.java b/core/src/main/java/org/elasticsearch/cluster/action/shard/ShardStateAction.java
index 80420e325eb..41ddb49bb65 100644
--- a/core/src/main/java/org/elasticsearch/cluster/action/shard/ShardStateAction.java
+++ b/core/src/main/java/org/elasticsearch/cluster/action/shard/ShardStateAction.java
@@ -19,6 +19,7 @@
package org.elasticsearch.cluster.action.shard;
+import org.elasticsearch.ExceptionsHelper;
import org.elasticsearch.cluster.ClusterService;
import org.elasticsearch.cluster.ClusterState;
import org.elasticsearch.cluster.ClusterStateUpdateTask;
@@ -30,11 +31,13 @@ import org.elasticsearch.cluster.routing.*;
import org.elasticsearch.cluster.routing.allocation.AllocationService;
import org.elasticsearch.cluster.routing.allocation.FailedRerouteAllocation;
import org.elasticsearch.cluster.routing.allocation.RoutingAllocation;
+import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.Priority;
import org.elasticsearch.common.component.AbstractComponent;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
+import org.elasticsearch.common.logging.ESLogger;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.util.concurrent.ConcurrentCollections;
import org.elasticsearch.threadpool.ThreadPool;
@@ -76,22 +79,22 @@ public class ShardStateAction extends AbstractComponent {
transportService.registerRequestHandler(SHARD_FAILED_ACTION_NAME, ShardRoutingEntry.class, ThreadPool.Names.SAME, new ShardFailedTransportHandler());
}
- public void shardFailed(final ShardRouting shardRouting, final String indexUUID, final String reason) {
+ public void shardFailed(final ShardRouting shardRouting, final String indexUUID, final String message, @Nullable final Throwable failure) {
DiscoveryNode masterNode = clusterService.state().nodes().masterNode();
if (masterNode == null) {
logger.warn("can't send shard failed for {}, no master known.", shardRouting);
return;
}
- innerShardFailed(shardRouting, indexUUID, reason, masterNode);
+ innerShardFailed(shardRouting, indexUUID, masterNode, message, failure);
}
- public void resendShardFailed(final ShardRouting shardRouting, final String indexUUID, final String reason, final DiscoveryNode masterNode) {
- logger.trace("{} re-sending failed shard for {}, indexUUID [{}], reason [{}]", shardRouting.shardId(), shardRouting, indexUUID, reason);
- innerShardFailed(shardRouting, indexUUID, reason, masterNode);
+ public void resendShardFailed(final ShardRouting shardRouting, final String indexUUID, final DiscoveryNode masterNode, final String message, @Nullable final Throwable failure) {
+ logger.trace("{} re-sending failed shard for {}, indexUUID [{}], reason [{}]", failure, shardRouting.shardId(), shardRouting, indexUUID, message);
+ innerShardFailed(shardRouting, indexUUID, masterNode, message, failure);
}
- private void innerShardFailed(final ShardRouting shardRouting, final String indexUUID, final String reason, final DiscoveryNode masterNode) {
- ShardRoutingEntry shardRoutingEntry = new ShardRoutingEntry(shardRouting, indexUUID, reason);
+ private void innerShardFailed(final ShardRouting shardRouting, final String indexUUID, final DiscoveryNode masterNode, final String message, final Throwable failure) {
+ ShardRoutingEntry shardRoutingEntry = new ShardRoutingEntry(shardRouting, indexUUID, message, failure);
transportService.sendRequest(masterNode,
SHARD_FAILED_ACTION_NAME, shardRoutingEntry, new EmptyTransportResponseHandler(ThreadPool.Names.SAME) {
@Override
@@ -104,20 +107,17 @@ public class ShardStateAction extends AbstractComponent {
public void shardStarted(final ShardRouting shardRouting, String indexUUID, final String reason) {
DiscoveryNode masterNode = clusterService.state().nodes().masterNode();
if (masterNode == null) {
- logger.warn("can't send shard started for {}. no master known.", shardRouting);
+ logger.warn("{} can't send shard started for {}, no master known.", shardRouting.shardId(), shardRouting);
return;
}
shardStarted(shardRouting, indexUUID, reason, masterNode);
}
public void shardStarted(final ShardRouting shardRouting, String indexUUID, final String reason, final DiscoveryNode masterNode) {
-
- ShardRoutingEntry shardRoutingEntry = new ShardRoutingEntry(shardRouting, indexUUID, reason);
-
- logger.debug("sending shard started for {}", shardRoutingEntry);
-
+ ShardRoutingEntry shardRoutingEntry = new ShardRoutingEntry(shardRouting, indexUUID, reason, null);
+ logger.debug("{} sending shard started for {}", shardRoutingEntry.shardRouting.shardId(), shardRoutingEntry);
transportService.sendRequest(masterNode,
- SHARD_STARTED_ACTION_NAME, new ShardRoutingEntry(shardRouting, indexUUID, reason), new EmptyTransportResponseHandler(ThreadPool.Names.SAME) {
+ SHARD_STARTED_ACTION_NAME, new ShardRoutingEntry(shardRouting, indexUUID, reason, null), new EmptyTransportResponseHandler(ThreadPool.Names.SAME) {
@Override
public void handleException(TransportException exp) {
logger.warn("failed to send shard started to [{}]", exp, masterNode);
@@ -127,9 +127,9 @@ public class ShardStateAction extends AbstractComponent {
}
private void handleShardFailureOnMaster(final ShardRoutingEntry shardRoutingEntry) {
- logger.warn("{} received shard failed for {}", shardRoutingEntry.shardRouting.shardId(), shardRoutingEntry);
+ logger.warn("{} received shard failed for {}", shardRoutingEntry.failure, shardRoutingEntry.shardRouting.shardId(), shardRoutingEntry);
failedShardQueue.add(shardRoutingEntry);
- clusterService.submitStateUpdateTask("shard-failed (" + shardRoutingEntry.shardRouting + "), reason [" + shardRoutingEntry.reason + "]", Priority.HIGH, new ProcessedClusterStateUpdateTask() {
+ clusterService.submitStateUpdateTask("shard-failed (" + shardRoutingEntry.shardRouting + "), message [" + shardRoutingEntry.message + "]", Priority.HIGH, new ProcessedClusterStateUpdateTask() {
@Override
public ClusterState execute(ClusterState currentState) {
@@ -145,26 +145,12 @@ public class ShardStateAction extends AbstractComponent {
return currentState;
}
- MetaData metaData = currentState.getMetaData();
-
List shardRoutingsToBeApplied = new ArrayList<>(shardRoutingEntries.size());
- for (int i = 0; i < shardRoutingEntries.size(); i++) {
- ShardRoutingEntry shardRoutingEntry = shardRoutingEntries.get(i);
- shardRoutingEntry.processed = true;
- ShardRouting shardRouting = shardRoutingEntry.shardRouting;
- IndexMetaData indexMetaData = metaData.index(shardRouting.index());
- // if there is no metadata or the current index is not of the right uuid, the index has been deleted while it was being allocated
- // which is fine, we should just ignore this
- if (indexMetaData == null) {
- continue;
- }
- if (!indexMetaData.isSameUUID(shardRoutingEntry.indexUUID)) {
- logger.debug("{} ignoring shard failed, different index uuid, current {}, got {}", shardRouting.shardId(), indexMetaData.getUUID(), shardRoutingEntry);
- continue;
- }
- logger.debug("{} will apply shard failed {}", shardRouting.shardId(), shardRoutingEntry);
- shardRoutingsToBeApplied.add(new FailedRerouteAllocation.FailedShard(shardRouting, shardRoutingEntry.reason));
+ // mark all entries as processed
+ for (ShardRoutingEntry entry : shardRoutingEntries) {
+ entry.processed = true;
+ shardRoutingsToBeApplied.add(new FailedRerouteAllocation.FailedShard(entry.shardRouting, entry.message, entry.failure));
}
RoutingAllocation.Result routingResult = allocationService.applyFailedShards(currentState, shardRoutingsToBeApplied);
@@ -197,7 +183,7 @@ public class ShardStateAction extends AbstractComponent {
// process started events as fast as possible, to make shards available
startedShardsQueue.add(shardRoutingEntry);
- clusterService.submitStateUpdateTask("shard-started (" + shardRoutingEntry.shardRouting + "), reason [" + shardRoutingEntry.reason + "]", Priority.URGENT,
+ clusterService.submitStateUpdateTask("shard-started (" + shardRoutingEntry.shardRouting + "), reason [" + shardRoutingEntry.message + "]", Priority.URGENT,
new ClusterStateUpdateTask() {
@Override
public ClusterState execute(ClusterState currentState) {
@@ -214,59 +200,12 @@ public class ShardStateAction extends AbstractComponent {
return currentState;
}
- RoutingTable routingTable = currentState.routingTable();
- MetaData metaData = currentState.getMetaData();
-
List shardRoutingToBeApplied = new ArrayList<>(shardRoutingEntries.size());
- for (int i = 0; i < shardRoutingEntries.size(); i++) {
- ShardRoutingEntry shardRoutingEntry = shardRoutingEntries.get(i);
- shardRoutingEntry.processed = true;
- ShardRouting shardRouting = shardRoutingEntry.shardRouting;
- try {
- IndexMetaData indexMetaData = metaData.index(shardRouting.index());
- IndexRoutingTable indexRoutingTable = routingTable.index(shardRouting.index());
- // if there is no metadata, no routing table or the current index is not of the right uuid, the index has been deleted while it was being allocated
- // which is fine, we should just ignore this
- if (indexMetaData == null) {
- continue;
- }
- if (indexRoutingTable == null) {
- continue;
- }
-
- if (!indexMetaData.isSameUUID(shardRoutingEntry.indexUUID)) {
- logger.debug("{} ignoring shard started, different index uuid, current {}, got {}", shardRouting.shardId(), indexMetaData.getUUID(), shardRoutingEntry);
- continue;
- }
-
- // find the one that maps to us, if its already started, no need to do anything...
- // the shard might already be started since the nodes that is starting the shards might get cluster events
- // with the shard still initializing, and it will try and start it again (until the verification comes)
-
- IndexShardRoutingTable indexShardRoutingTable = indexRoutingTable.shard(shardRouting.id());
-
- boolean applyShardEvent = true;
-
- for (ShardRouting entry : indexShardRoutingTable) {
- if (shardRouting.currentNodeId().equals(entry.currentNodeId())) {
- // we found the same shard that exists on the same node id
- if (!entry.initializing()) {
- // shard is in initialized state, skipping event (probable already started)
- logger.debug("{} ignoring shard started event for {}, current state: {}", shardRouting.shardId(), shardRoutingEntry, entry.state());
- applyShardEvent = false;
- }
- }
- }
-
- if (applyShardEvent) {
- shardRoutingToBeApplied.add(shardRouting);
- logger.debug("{} will apply shard started {}", shardRouting.shardId(), shardRoutingEntry);
- }
-
- } catch (Throwable t) {
- logger.error("{} unexpected failure while processing shard started [{}]", t, shardRouting.shardId(), shardRouting);
- }
+ // mark all entries as processed
+ for (ShardRoutingEntry entry : shardRoutingEntries) {
+ entry.processed = true;
+ shardRoutingToBeApplied.add(entry.shardRouting);
}
if (shardRoutingToBeApplied.isEmpty()) {
@@ -307,42 +246,44 @@ public class ShardStateAction extends AbstractComponent {
static class ShardRoutingEntry extends TransportRequest {
- private ShardRouting shardRouting;
-
- private String indexUUID = IndexMetaData.INDEX_UUID_NA_VALUE;
-
- private String reason;
+ ShardRouting shardRouting;
+ String indexUUID = IndexMetaData.INDEX_UUID_NA_VALUE;
+ String message;
+ Throwable failure;
volatile boolean processed; // state field, no need to serialize
ShardRoutingEntry() {
}
- private ShardRoutingEntry(ShardRouting shardRouting, String indexUUID, String reason) {
+ ShardRoutingEntry(ShardRouting shardRouting, String indexUUID, String message, @Nullable Throwable failure) {
this.shardRouting = shardRouting;
- this.reason = reason;
this.indexUUID = indexUUID;
+ this.message = message;
+ this.failure = failure;
}
@Override
public void readFrom(StreamInput in) throws IOException {
super.readFrom(in);
shardRouting = readShardRoutingEntry(in);
- reason = in.readString();
indexUUID = in.readString();
+ message = in.readString();
+ failure = in.readThrowable();
}
@Override
public void writeTo(StreamOutput out) throws IOException {
super.writeTo(out);
shardRouting.writeTo(out);
- out.writeString(reason);
out.writeString(indexUUID);
+ out.writeString(message);
+ out.writeThrowable(failure);
}
@Override
public String toString() {
- return "" + shardRouting + ", indexUUID [" + indexUUID + "], reason [" + reason + "]";
+ return "" + shardRouting + ", indexUUID [" + indexUUID + "], message [" + message + "], failure [" + ExceptionsHelper.detailedMessage(failure) + "]";
}
}
}
diff --git a/core/src/main/java/org/elasticsearch/cluster/metadata/AliasValidator.java b/core/src/main/java/org/elasticsearch/cluster/metadata/AliasValidator.java
index c5d603ccca6..f12824de4ee 100644
--- a/core/src/main/java/org/elasticsearch/cluster/metadata/AliasValidator.java
+++ b/core/src/main/java/org/elasticsearch/cluster/metadata/AliasValidator.java
@@ -145,7 +145,6 @@ public class AliasValidator extends AbstractComponent {
QueryParseContext context = indexQueryParserService.getParseContext();
try {
context.reset(parser);
- context.setAllowUnmappedFields(false);
context.parseInnerFilter();
} finally {
context.reset(null);
diff --git a/core/src/main/java/org/elasticsearch/cluster/metadata/IndexMetaData.java b/core/src/main/java/org/elasticsearch/cluster/metadata/IndexMetaData.java
index 4e7998ca381..deea1cec308 100644
--- a/core/src/main/java/org/elasticsearch/cluster/metadata/IndexMetaData.java
+++ b/core/src/main/java/org/elasticsearch/cluster/metadata/IndexMetaData.java
@@ -33,6 +33,7 @@ import org.elasticsearch.cluster.node.DiscoveryNodeFilters;
import org.elasticsearch.cluster.routing.HashFunction;
import org.elasticsearch.cluster.routing.Murmur3HashFunction;
import org.elasticsearch.common.Nullable;
+import org.elasticsearch.common.ParseFieldMatcher;
import org.elasticsearch.common.collect.ImmutableOpenMap;
import org.elasticsearch.common.collect.MapBuilder;
import org.elasticsearch.common.compress.CompressedXContent;
@@ -40,10 +41,7 @@ import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.settings.loader.SettingsLoader;
-import org.elasticsearch.common.xcontent.ToXContent;
-import org.elasticsearch.common.xcontent.XContentBuilder;
-import org.elasticsearch.common.xcontent.XContentFactory;
-import org.elasticsearch.common.xcontent.XContentParser;
+import org.elasticsearch.common.xcontent.*;
import org.elasticsearch.index.mapper.MapperService;
import org.elasticsearch.rest.RestStatus;
import org.elasticsearch.search.warmer.IndexWarmersMetaData;
@@ -64,7 +62,7 @@ import static org.elasticsearch.common.settings.Settings.*;
/**
*
*/
-public class IndexMetaData implements Diffable {
+public class IndexMetaData implements Diffable, FromXContentBuilder, ToXContent {
public static final IndexMetaData PROTO = IndexMetaData.builder("")
.settings(Settings.builder().put(IndexMetaData.SETTING_VERSION_CREATED, Version.CURRENT))
@@ -169,7 +167,7 @@ public class IndexMetaData implements Diffable {
public static final String SETTING_CREATION_DATE = "index.creation_date";
public static final String SETTING_PRIORITY = "index.priority";
public static final String SETTING_CREATION_DATE_STRING = "index.creation_date_string";
- public static final String SETTING_UUID = "index.uuid";
+ public static final String SETTING_INDEX_UUID = "index.uuid";
public static final String SETTING_LEGACY_ROUTING_HASH_FUNCTION = "index.legacy.routing.hash.type";
public static final String SETTING_LEGACY_ROUTING_USE_TYPE = "index.legacy.routing.use_type";
public static final String SETTING_DATA_PATH = "index.data_path";
@@ -268,12 +266,12 @@ public class IndexMetaData implements Diffable {
return index();
}
- public String uuid() {
- return settings.get(SETTING_UUID, INDEX_UUID_NA_VALUE);
+ public String indexUUID() {
+ return settings.get(SETTING_INDEX_UUID, INDEX_UUID_NA_VALUE);
}
- public String getUUID() {
- return uuid();
+ public String getIndexUUID() {
+ return indexUUID();
}
/**
@@ -281,11 +279,11 @@ public class IndexMetaData implements Diffable {
*/
public boolean isSameUUID(String otherUUID) {
assert otherUUID != null;
- assert uuid() != null;
- if (INDEX_UUID_NA_VALUE.equals(otherUUID) || INDEX_UUID_NA_VALUE.equals(uuid())) {
+ assert indexUUID() != null;
+ if (INDEX_UUID_NA_VALUE.equals(otherUUID) || INDEX_UUID_NA_VALUE.equals(indexUUID())) {
return true;
}
- return otherUUID.equals(getUUID());
+ return otherUUID.equals(getIndexUUID());
}
public long version() {
@@ -515,6 +513,17 @@ public class IndexMetaData implements Diffable {
return new IndexMetaDataDiff(in);
}
+ @Override
+ public IndexMetaData fromXContent(XContentParser parser, ParseFieldMatcher parseFieldMatcher) throws IOException {
+ return Builder.fromXContent(parser);
+ }
+
+ @Override
+ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
+ Builder.toXContent(this, builder, params);
+ return builder;
+ }
+
private static class IndexMetaDataDiff implements Diff {
private final String index;
diff --git a/core/src/main/java/org/elasticsearch/cluster/metadata/IndexNameExpressionResolver.java b/core/src/main/java/org/elasticsearch/cluster/metadata/IndexNameExpressionResolver.java
new file mode 100644
index 00000000000..77c35fdcf50
--- /dev/null
+++ b/core/src/main/java/org/elasticsearch/cluster/metadata/IndexNameExpressionResolver.java
@@ -0,0 +1,618 @@
+/*
+ * Licensed to Elasticsearch under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch licenses this file to you under
+ * the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.elasticsearch.cluster.metadata;
+
+import com.carrotsearch.hppc.cursors.ObjectCursor;
+import com.carrotsearch.hppc.cursors.ObjectObjectCursor;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import org.elasticsearch.action.IndicesRequest;
+import org.elasticsearch.action.support.IndicesOptions;
+import org.elasticsearch.cluster.ClusterState;
+import org.elasticsearch.common.Nullable;
+import org.elasticsearch.common.Strings;
+import org.elasticsearch.common.collect.ImmutableOpenMap;
+import org.elasticsearch.common.inject.Inject;
+import org.elasticsearch.common.regex.Regex;
+import org.elasticsearch.index.Index;
+import org.elasticsearch.index.IndexNotFoundException;
+import org.elasticsearch.indices.IndexClosedException;
+
+import java.util.*;
+
+import static com.google.common.collect.Lists.newArrayList;
+import static com.google.common.collect.Maps.newHashMap;
+
+public class IndexNameExpressionResolver {
+
+ private final ImmutableList expressionResolvers;
+
+ @Inject
+ public IndexNameExpressionResolver() {
+ expressionResolvers = ImmutableList.of(new WildcardExpressionResolver());
+ }
+
+ /**
+ * Same as {@link #concreteIndices(ClusterState, IndicesOptions, String...)}, but the index expressions and options
+ * are encapsulated in the specified request.
+ */
+ public String[] concreteIndices(ClusterState state, IndicesRequest request) {
+ Context context = new Context(state, request.indicesOptions());
+ return concreteIndices(context, request.indices());
+ }
+
+ /**
+ * Translates the provided index expression into actual concrete indices.
+ *
+ * @param state the cluster state containing all the data to resolve to expressions to concrete indices
+ * @param options defines how the aliases or indices need to be resolved to concrete indices
+ * @param indexExpressions expressions that can be resolved to alias or index names.
+ * @return the resolved concrete indices based on the cluster state, indices options and index expressions
+ * @throws IndexNotFoundException if one of the index expressions is pointing to a missing index or alias and the
+ * provided indices options in the context don't allow such a case, or if the final result of the indices resolution
+ * contains no indices and the indices options in the context don't allow such a case.
+ * @throws IllegalArgumentException if one of the aliases resolve to multiple indices and the provided
+ * indices options in the context don't allow such a case.
+ */
+ public String[] concreteIndices(ClusterState state, IndicesOptions options, String... indexExpressions) {
+ Context context = new Context(state, options);
+ return concreteIndices(context, indexExpressions);
+ }
+
+ String[] concreteIndices(Context context, String... indexExpressions) {
+ if (indexExpressions == null || indexExpressions.length == 0) {
+ indexExpressions = new String[]{MetaData.ALL};
+ }
+ MetaData metaData = context.getState().metaData();
+ IndicesOptions options = context.getOptions();
+ boolean failClosed = options.forbidClosedIndices() && options.ignoreUnavailable() == false;
+ boolean failNoIndices = options.ignoreUnavailable() == false;
+ // If only one index is specified then whether we fail a request if an index is missing depends on the allow_no_indices
+ // option. At some point we should change this, because there shouldn't be a reason why whether a single index
+ // or multiple indices are specified yield different behaviour.
+ if (indexExpressions.length == 1) {
+ failNoIndices = options.allowNoIndices() == false;
+ }
+
+ List expressions = Arrays.asList(indexExpressions);
+ for (ExpressionResolver expressionResolver : expressionResolvers) {
+ expressions = expressionResolver.resolve(context, expressions);
+ }
+
+ if (expressions.isEmpty()) {
+ if (!options.allowNoIndices()) {
+ IndexNotFoundException infe = new IndexNotFoundException((String)null);
+ infe.setResources("index_expression", indexExpressions);
+ throw infe;
+ } else {
+ return Strings.EMPTY_ARRAY;
+ }
+ }
+
+ List concreteIndices = new ArrayList<>(expressions.size());
+ for (String expression : expressions) {
+ List indexMetaDatas;
+ IndexMetaData indexMetaData = metaData.getIndices().get(expression);
+ if (indexMetaData == null) {
+ ImmutableOpenMap indexAliasMap = metaData.aliases().get(expression);
+ if (indexAliasMap == null) {
+ if (failNoIndices) {
+ IndexNotFoundException infe = new IndexNotFoundException(expression);
+ infe.setResources("index_expression", expression);
+ throw infe;
+
+ } else {
+ continue;
+ }
+ }
+ if (indexAliasMap.size() > 1 && !options.allowAliasesToMultipleIndices()) {
+ throw new IllegalArgumentException("Alias [" + expression + "] has more than one indices associated with it [" + Arrays.toString(indexAliasMap.keys().toArray(String.class)) + "], can't execute a single index op");
+ }
+ indexMetaDatas = new ArrayList<>(indexAliasMap.size());
+ for (ObjectObjectCursor cursor : indexAliasMap) {
+ indexMetaDatas.add(metaData.getIndices().get(cursor.key));
+ }
+ } else {
+ indexMetaDatas = Collections.singletonList(indexMetaData);
+ }
+
+ for (IndexMetaData found : indexMetaDatas) {
+ if (found.getState() == IndexMetaData.State.CLOSE) {
+ if (failClosed) {
+ throw new IndexClosedException(new Index(found.getIndex()));
+ } else {
+ if (options.forbidClosedIndices() == false) {
+ concreteIndices.add(found.getIndex());
+ }
+ }
+ } else if (found.getState() == IndexMetaData.State.OPEN) {
+ concreteIndices.add(found.getIndex());
+ } else {
+ throw new IllegalStateException("index state [" + found.getState() + "] not supported");
+ }
+ }
+ }
+
+ if (options.allowNoIndices() == false && concreteIndices.isEmpty()) {
+ IndexNotFoundException infe = new IndexNotFoundException((String)null);
+ infe.setResources("index_expression", indexExpressions);
+ throw infe;
+ }
+ return concreteIndices.toArray(new String[concreteIndices.size()]);
+ }
+
+ /**
+ * Utility method that allows to resolve an index expression to its corresponding single concrete index.
+ * Callers should make sure they provide proper {@link org.elasticsearch.action.support.IndicesOptions}
+ * that require a single index as a result. The indices resolution must in fact return a single index when
+ * using this method, an {@link IllegalArgumentException} gets thrown otherwise.
+ *
+ * @param request request containing the index or alias to be resolved to concrete index and
+ * the indices options to be used for the index resolution
+ * @throws IndexNotFoundException if the resolved index or alias provided doesn't exist
+ * @throws IllegalArgumentException if the index resolution lead to more than one index
+ * @return the concrete index obtained as a result of the index resolution
+ */
+ public String concreteSingleIndex(ClusterState state, IndicesRequest request) {
+ String indexOrAlias = request.indices() != null && request.indices().length > 0 ? request.indices()[0] : null;
+ String[] indices = concreteIndices(state, request.indicesOptions(), indexOrAlias);
+ if (indices.length != 1) {
+ throw new IllegalArgumentException("unable to return a single index as the index and options provided got resolved to multiple indices");
+ }
+ return indices[0];
+ }
+
+ /**
+ * Iterates through the list of indices and selects the effective list of filtering aliases for the
+ * given index.
+ *
+ * Only aliases with filters are returned. If the indices list contains a non-filtering reference to
+ * the index itself - null is returned. Returns null if no filtering is required.
+ */
+ public String[] filteringAliases(ClusterState state, String index, String... expressions) {
+ // expand the aliases wildcard
+ List resolvedExpressions = expressions != null ? Arrays.asList(expressions) : Collections.emptyList();
+ Context context = new Context(state, IndicesOptions.lenientExpandOpen());
+ for (ExpressionResolver expressionResolver : expressionResolvers) {
+ resolvedExpressions = expressionResolver.resolve(context, resolvedExpressions);
+ }
+
+ if (isAllIndices(resolvedExpressions)) {
+ return null;
+ }
+ // optimize for the most common single index/alias scenario
+ if (resolvedExpressions.size() == 1) {
+ String alias = resolvedExpressions.get(0);
+ IndexMetaData indexMetaData = state.metaData().getIndices().get(index);
+ if (indexMetaData == null) {
+ // Shouldn't happen
+ throw new IndexNotFoundException(index);
+ }
+ AliasMetaData aliasMetaData = indexMetaData.aliases().get(alias);
+ boolean filteringRequired = aliasMetaData != null && aliasMetaData.filteringRequired();
+ if (!filteringRequired) {
+ return null;
+ }
+ return new String[]{alias};
+ }
+ List filteringAliases = null;
+ for (String alias : resolvedExpressions) {
+ if (alias.equals(index)) {
+ return null;
+ }
+
+ IndexMetaData indexMetaData = state.metaData().getIndices().get(index);
+ if (indexMetaData == null) {
+ // Shouldn't happen
+ throw new IndexNotFoundException(index);
+ }
+
+ AliasMetaData aliasMetaData = indexMetaData.aliases().get(alias);
+ // Check that this is an alias for the current index
+ // Otherwise - skip it
+ if (aliasMetaData != null) {
+ boolean filteringRequired = aliasMetaData.filteringRequired();
+ if (filteringRequired) {
+ // If filtering required - add it to the list of filters
+ if (filteringAliases == null) {
+ filteringAliases = newArrayList();
+ }
+ filteringAliases.add(alias);
+ } else {
+ // If not, we have a non filtering alias for this index - no filtering needed
+ return null;
+ }
+ }
+ }
+ if (filteringAliases == null) {
+ return null;
+ }
+ return filteringAliases.toArray(new String[filteringAliases.size()]);
+ }
+
+ /**
+ * Resolves the search routing if in the expression aliases are used. If expressions point to concrete indices
+ * or aliases with no routing defined the specified routing is used.
+ *
+ * @return routing values grouped by concrete index
+ */
+ public Map> resolveSearchRouting(ClusterState state, @Nullable String routing, String... expressions) {
+ List resolvedExpressions = expressions != null ? Arrays.asList(expressions) : Collections.emptyList();
+ Context context = new Context(state, IndicesOptions.lenientExpandOpen());
+ for (ExpressionResolver expressionResolver : expressionResolvers) {
+ resolvedExpressions = expressionResolver.resolve(context, resolvedExpressions);
+ }
+
+ if (isAllIndices(resolvedExpressions)) {
+ return resolveSearchRoutingAllIndices(state.metaData(), routing);
+ }
+
+ if (resolvedExpressions.size() == 1) {
+ return resolveSearchRoutingSingleValue(state.metaData(), routing, resolvedExpressions.get(0));
+ }
+
+ Map> routings = null;
+ Set paramRouting = null;
+ // List of indices that don't require any routing
+ Set norouting = new HashSet<>();
+ if (routing != null) {
+ paramRouting = Strings.splitStringByCommaToSet(routing);
+ }
+
+ for (String expression : resolvedExpressions) {
+ ImmutableOpenMap indexToRoutingMap = state.metaData().getAliases().get(expression);
+ if (indexToRoutingMap != null && !indexToRoutingMap.isEmpty()) {
+ for (ObjectObjectCursor indexRouting : indexToRoutingMap) {
+ if (!norouting.contains(indexRouting.key)) {
+ if (!indexRouting.value.searchRoutingValues().isEmpty()) {
+ // Routing alias
+ if (routings == null) {
+ routings = newHashMap();
+ }
+ Set r = routings.get(indexRouting.key);
+ if (r == null) {
+ r = new HashSet<>();
+ routings.put(indexRouting.key, r);
+ }
+ r.addAll(indexRouting.value.searchRoutingValues());
+ if (paramRouting != null) {
+ r.retainAll(paramRouting);
+ }
+ if (r.isEmpty()) {
+ routings.remove(indexRouting.key);
+ }
+ } else {
+ // Non-routing alias
+ if (!norouting.contains(indexRouting.key)) {
+ norouting.add(indexRouting.key);
+ if (paramRouting != null) {
+ Set r = new HashSet<>(paramRouting);
+ if (routings == null) {
+ routings = newHashMap();
+ }
+ routings.put(indexRouting.key, r);
+ } else {
+ if (routings != null) {
+ routings.remove(indexRouting.key);
+ }
+ }
+ }
+ }
+ }
+ }
+ } else {
+ // Index
+ if (!norouting.contains(expression)) {
+ norouting.add(expression);
+ if (paramRouting != null) {
+ Set r = new HashSet<>(paramRouting);
+ if (routings == null) {
+ routings = newHashMap();
+ }
+ routings.put(expression, r);
+ } else {
+ if (routings != null) {
+ routings.remove(expression);
+ }
+ }
+ }
+ }
+
+ }
+ if (routings == null || routings.isEmpty()) {
+ return null;
+ }
+ return routings;
+ }
+
+ private Map> resolveSearchRoutingSingleValue(MetaData metaData, @Nullable String routing, String aliasOrIndex) {
+ Map> routings = null;
+ Set paramRouting = null;
+ if (routing != null) {
+ paramRouting = Strings.splitStringByCommaToSet(routing);
+ }
+
+ ImmutableOpenMap indexToRoutingMap = metaData.getAliases().get(aliasOrIndex);
+ if (indexToRoutingMap != null && !indexToRoutingMap.isEmpty()) {
+ // It's an alias
+ for (ObjectObjectCursor indexRouting : indexToRoutingMap) {
+ if (!indexRouting.value.searchRoutingValues().isEmpty()) {
+ // Routing alias
+ Set r = new HashSet<>(indexRouting.value.searchRoutingValues());
+ if (paramRouting != null) {
+ r.retainAll(paramRouting);
+ }
+ if (!r.isEmpty()) {
+ if (routings == null) {
+ routings = newHashMap();
+ }
+ routings.put(indexRouting.key, r);
+ }
+ } else {
+ // Non-routing alias
+ if (paramRouting != null) {
+ Set r = new HashSet<>(paramRouting);
+ if (routings == null) {
+ routings = newHashMap();
+ }
+ routings.put(indexRouting.key, r);
+ }
+ }
+ }
+ } else {
+ // It's an index
+ if (paramRouting != null) {
+ routings = ImmutableMap.of(aliasOrIndex, paramRouting);
+ }
+ }
+ return routings;
+ }
+
+ /**
+ * Sets the same routing for all indices
+ */
+ private Map> resolveSearchRoutingAllIndices(MetaData metaData, String routing) {
+ if (routing != null) {
+ Set r = Strings.splitStringByCommaToSet(routing);
+ Map> routings = newHashMap();
+ String[] concreteIndices = metaData.concreteAllIndices();
+ for (String index : concreteIndices) {
+ routings.put(index, r);
+ }
+ return routings;
+ }
+ return null;
+ }
+
+ /**
+ * Identifies whether the array containing index names given as argument refers to all indices
+ * The empty or null array identifies all indices
+ *
+ * @param aliasesOrIndices the array containing index names
+ * @return true if the provided array maps to all indices, false otherwise
+ */
+ public static boolean isAllIndices(List aliasesOrIndices) {
+ return aliasesOrIndices == null || aliasesOrIndices.isEmpty() || isExplicitAllPattern(aliasesOrIndices);
+ }
+
+ /**
+ * Identifies whether the array containing index names given as argument explicitly refers to all indices
+ * The empty or null array doesn't explicitly map to all indices
+ *
+ * @param aliasesOrIndices the array containing index names
+ * @return true if the provided array explicitly maps to all indices, false otherwise
+ */
+ static boolean isExplicitAllPattern(List aliasesOrIndices) {
+ return aliasesOrIndices != null && aliasesOrIndices.size() == 1 && MetaData.ALL.equals(aliasesOrIndices.get(0));
+ }
+
+ /**
+ * Identifies whether the first argument (an array containing index names) is a pattern that matches all indices
+ *
+ * @param indicesOrAliases the array containing index names
+ * @param concreteIndices array containing the concrete indices that the first argument refers to
+ * @return true if the first argument is a pattern that maps to all available indices, false otherwise
+ */
+ boolean isPatternMatchingAllIndices(MetaData metaData, String[] indicesOrAliases, String[] concreteIndices) {
+ // if we end up matching on all indices, check, if its a wildcard parameter, or a "-something" structure
+ if (concreteIndices.length == metaData.concreteAllIndices().length && indicesOrAliases.length > 0) {
+
+ //we might have something like /-test1,+test1 that would identify all indices
+ //or something like /-test1 with test1 index missing and IndicesOptions.lenient()
+ if (indicesOrAliases[0].charAt(0) == '-') {
+ return true;
+ }
+
+ //otherwise we check if there's any simple regex
+ for (String indexOrAlias : indicesOrAliases) {
+ if (Regex.isSimpleMatchPattern(indexOrAlias)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ final static class Context {
+
+ private final ClusterState state;
+ private final IndicesOptions options;
+
+ Context(ClusterState state, IndicesOptions options) {
+ this.state = state;
+ this.options = options;
+ }
+
+ public ClusterState getState() {
+ return state;
+ }
+
+ public IndicesOptions getOptions() {
+ return options;
+ }
+ }
+
+ private interface ExpressionResolver {
+
+ /**
+ * Resolves the list of expressions into other expressions if possible (possible concrete indices and aliases, but
+ * that isn't required). The provided implementations can also be left untouched.
+ *
+ * @return a new list with expressions based on the provided expressions
+ */
+ List resolve(Context context, List expressions);
+
+ }
+
+ /**
+ * Resolves alias/index name expressions with wildcards into the corresponding concrete indices/aliases
+ */
+ final static class WildcardExpressionResolver implements ExpressionResolver {
+
+ @Override
+ public List resolve(Context context, List expressions) {
+ IndicesOptions options = context.getOptions();
+ MetaData metaData = context.getState().metaData();
+ if (options.expandWildcardsClosed() == false && options.expandWildcardsOpen() == false) {
+ return expressions;
+ }
+
+ if (expressions.isEmpty() || (expressions.size() == 1 && MetaData.ALL.equals(expressions.get(0)))) {
+ if (options.expandWildcardsOpen() && options.expandWildcardsClosed()) {
+ return Arrays.asList(metaData.concreteAllIndices());
+ } else if (options.expandWildcardsOpen()) {
+ return Arrays.asList(metaData.concreteAllOpenIndices());
+ } else if (options.expandWildcardsClosed()) {
+ return Arrays.asList(metaData.concreteAllClosedIndices());
+ } else {
+ return Collections.emptyList();
+ }
+ }
+
+ Set result = null;
+ for (int i = 0; i < expressions.size(); i++) {
+ String aliasOrIndex = expressions.get(i);
+ if (metaData.getAliasAndIndexMap().containsKey(aliasOrIndex)) {
+ if (result != null) {
+ result.add(aliasOrIndex);
+ }
+ continue;
+ }
+ boolean add = true;
+ if (aliasOrIndex.charAt(0) == '+') {
+ // if its the first, add empty result set
+ if (i == 0) {
+ result = new HashSet<>();
+ }
+ add = true;
+ aliasOrIndex = aliasOrIndex.substring(1);
+ } else if (aliasOrIndex.charAt(0) == '-') {
+ // if its the first, fill it with all the indices...
+ if (i == 0) {
+ String[] concreteIndices;
+ if (options.expandWildcardsOpen() && options.expandWildcardsClosed()) {
+ concreteIndices = metaData.concreteAllIndices();
+ } else if (options.expandWildcardsOpen()) {
+ concreteIndices = metaData.concreteAllOpenIndices();
+ } else if (options.expandWildcardsClosed()) {
+ concreteIndices = metaData.concreteAllClosedIndices();
+ } else {
+ assert false : "Shouldn't end up here";
+ concreteIndices = Strings.EMPTY_ARRAY;
+ }
+ result = new HashSet<>(Arrays.asList(concreteIndices));
+ }
+ add = false;
+ aliasOrIndex = aliasOrIndex.substring(1);
+ }
+ if (!Regex.isSimpleMatchPattern(aliasOrIndex)) {
+ if (!options.ignoreUnavailable() && !metaData.getAliasAndIndexMap().containsKey(aliasOrIndex)) {
+ IndexNotFoundException infe = new IndexNotFoundException(aliasOrIndex);
+ infe.setResources("index_or_alias", aliasOrIndex);
+ throw infe;
+ }
+ if (result != null) {
+ if (add) {
+ result.add(aliasOrIndex);
+ } else {
+ result.remove(aliasOrIndex);
+ }
+ }
+ continue;
+ }
+ if (result == null) {
+ // add all the previous ones...
+ result = new HashSet<>();
+ result.addAll(expressions.subList(0, i));
+ }
+ String[] indices;
+ if (options.expandWildcardsOpen() && options.expandWildcardsClosed()) {
+ indices = metaData.concreteAllIndices();
+ } else if (options.expandWildcardsOpen()) {
+ indices = metaData.concreteAllOpenIndices();
+ } else if (options.expandWildcardsClosed()) {
+ indices = metaData.concreteAllClosedIndices();
+ } else {
+ assert false : "this shouldn't get called if wildcards expand to none";
+ indices = Strings.EMPTY_ARRAY;
+ }
+ boolean found = false;
+ // iterating over all concrete indices and see if there is a wildcard match
+ for (String index : indices) {
+ if (Regex.simpleMatch(aliasOrIndex, index)) {
+ found = true;
+ if (add) {
+ result.add(index);
+ } else {
+ result.remove(index);
+ }
+ }
+ }
+ // iterating over all aliases and see if there is a wildcard match
+ for (ObjectCursor cursor : metaData.getAliases().keys()) {
+ String alias = cursor.value;
+ if (Regex.simpleMatch(aliasOrIndex, alias)) {
+ found = true;
+ if (add) {
+ result.add(alias);
+ } else {
+ result.remove(alias);
+ }
+ }
+ }
+ if (!found && !options.allowNoIndices()) {
+ IndexNotFoundException infe = new IndexNotFoundException(aliasOrIndex);
+ infe.setResources("index_or_alias", aliasOrIndex);
+ throw infe;
+ }
+ }
+ if (result == null) {
+ return expressions;
+ }
+ if (result.isEmpty() && !options.allowNoIndices()) {
+ IndexNotFoundException infe = new IndexNotFoundException((String)null);
+ infe.setResources("index_or_alias", expressions.toArray(new String[0]));
+ throw infe;
+ }
+ return new ArrayList<>(result);
+ }
+ }
+
+}
diff --git a/core/src/main/java/org/elasticsearch/cluster/metadata/MappingMetaData.java b/core/src/main/java/org/elasticsearch/cluster/metadata/MappingMetaData.java
index 741d173d8f9..4e3c19430e9 100644
--- a/core/src/main/java/org/elasticsearch/cluster/metadata/MappingMetaData.java
+++ b/core/src/main/java/org/elasticsearch/cluster/metadata/MappingMetaData.java
@@ -167,10 +167,10 @@ public class MappingMetaData extends AbstractDiffable {
Version version) throws TimestampParsingException {
try {
// no need for unix timestamp parsing in 2.x
- FormatDateTimeFormatter formatter = version.onOrAfter(Version.V_2_0_0) ? dateTimeFormatter : EPOCH_MILLIS_PARSER;
+ FormatDateTimeFormatter formatter = version.onOrAfter(Version.V_2_0_0_beta1) ? dateTimeFormatter : EPOCH_MILLIS_PARSER;
return Long.toString(formatter.parser().parseMillis(timestampAsString));
} catch (RuntimeException e) {
- if (version.before(Version.V_2_0_0)) {
+ if (version.before(Version.V_2_0_0_beta1)) {
try {
return Long.toString(dateTimeFormatter.parser().parseMillis(timestampAsString));
} catch (RuntimeException e1) {
diff --git a/core/src/main/java/org/elasticsearch/cluster/metadata/MetaData.java b/core/src/main/java/org/elasticsearch/cluster/metadata/MetaData.java
index 341e659e142..3715e64f7b1 100644
--- a/core/src/main/java/org/elasticsearch/cluster/metadata/MetaData.java
+++ b/core/src/main/java/org/elasticsearch/cluster/metadata/MetaData.java
@@ -25,16 +25,18 @@ import com.carrotsearch.hppc.cursors.ObjectCursor;
import com.carrotsearch.hppc.cursors.ObjectObjectCursor;
import com.google.common.base.Predicate;
import com.google.common.collect.*;
-
import org.apache.lucene.util.CollectionUtil;
-import org.elasticsearch.action.support.IndicesOptions;
-import org.elasticsearch.cluster.*;
+import org.elasticsearch.cluster.Diff;
+import org.elasticsearch.cluster.Diffable;
+import org.elasticsearch.cluster.DiffableUtils;
import org.elasticsearch.cluster.DiffableUtils.KeyedReader;
+import org.elasticsearch.cluster.InternalClusterInfoService;
import org.elasticsearch.cluster.block.ClusterBlock;
import org.elasticsearch.cluster.block.ClusterBlockLevel;
import org.elasticsearch.cluster.routing.allocation.decider.DiskThresholdDecider;
import org.elasticsearch.cluster.service.InternalClusterService;
import org.elasticsearch.common.Nullable;
+import org.elasticsearch.common.ParseFieldMatcher;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.collect.HppcMaps;
import org.elasticsearch.common.collect.ImmutableOpenMap;
@@ -47,8 +49,7 @@ import org.elasticsearch.common.settings.loader.SettingsLoader;
import org.elasticsearch.common.xcontent.*;
import org.elasticsearch.discovery.DiscoverySettings;
import org.elasticsearch.index.Index;
-import org.elasticsearch.indices.IndexClosedException;
-import org.elasticsearch.indices.IndexMissingException;
+import org.elasticsearch.index.IndexNotFoundException;
import org.elasticsearch.indices.recovery.RecoverySettings;
import org.elasticsearch.indices.store.IndicesStore;
import org.elasticsearch.indices.ttl.IndicesTTLService;
@@ -58,11 +59,9 @@ import org.elasticsearch.search.warmer.IndexWarmersMetaData;
import java.io.IOException;
import java.util.*;
-import static com.google.common.collect.Lists.newArrayList;
-import static com.google.common.collect.Maps.newHashMap;
import static org.elasticsearch.common.settings.Settings.*;
-public class MetaData implements Iterable, Diffable {
+public class MetaData implements Iterable, Diffable, FromXContentBuilder, ToXContent {
public static final MetaData PROTO = builder().build();
@@ -134,7 +133,7 @@ public class MetaData implements Iterable, Diffable {
public static final String CONTEXT_MODE_GATEWAY = XContentContext.GATEWAY.toString();
- private final String uuid;
+ private final String clusterUUID;
private final long version;
private final Settings transientSettings;
@@ -156,8 +155,8 @@ public class MetaData implements Iterable, Diffable {
private final ImmutableOpenMap aliasAndIndexToIndexMap;
@SuppressWarnings("unchecked")
- MetaData(String uuid, long version, Settings transientSettings, Settings persistentSettings, ImmutableOpenMap indices, ImmutableOpenMap templates, ImmutableOpenMap customs) {
- this.uuid = uuid;
+ MetaData(String clusterUUID, long version, Settings transientSettings, Settings persistentSettings, ImmutableOpenMap indices, ImmutableOpenMap templates, ImmutableOpenMap customs) {
+ this.clusterUUID = clusterUUID;
this.version = version;
this.transientSettings = transientSettings;
this.persistentSettings = persistentSettings;
@@ -254,8 +253,8 @@ public class MetaData implements Iterable, Diffable {
return this.version;
}
- public String uuid() {
- return this.uuid;
+ public String clusterUUID() {
+ return this.clusterUUID;
}
/**
@@ -281,6 +280,10 @@ public class MetaData implements Iterable, Diffable {
return aliases();
}
+ public ImmutableOpenMap getAliasAndIndexMap() {
+ return aliasAndIndexToIndexMap;
+ }
+
/**
* Finds the specific index aliases that match with the specified aliases directly or partially via wildcards and
* that point to the specified concrete indices or match partially with the indices via wildcards.
@@ -471,6 +474,8 @@ public class MetaData implements Iterable, Diffable {
/**
* Returns indexing routing for the given index.
*/
+ // 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.
public String resolveIndexRouting(@Nullable String routing, String aliasOrIndex) {
// Check if index is specified by an alias
ImmutableOpenMap indexAliases = aliases.get(aliasOrIndex);
@@ -497,441 +502,6 @@ public class MetaData implements Iterable, Diffable {
return routing;
}
- public Map> resolveSearchRouting(@Nullable String routing, String aliasOrIndex) {
- return resolveSearchRouting(routing, convertFromWildcards(new String[]{aliasOrIndex}, IndicesOptions.lenientExpandOpen()));
- }
-
- public Map> resolveSearchRouting(@Nullable String routing, String[] aliasesOrIndices) {
- if (isAllIndices(aliasesOrIndices)) {
- return resolveSearchRoutingAllIndices(routing);
- }
-
- aliasesOrIndices = convertFromWildcards(aliasesOrIndices, IndicesOptions.lenientExpandOpen());
-
- if (aliasesOrIndices.length == 1) {
- return resolveSearchRoutingSingleValue(routing, aliasesOrIndices[0]);
- }
-
- Map> routings = null;
- Set paramRouting = null;
- // List of indices that don't require any routing
- Set norouting = new HashSet<>();
- if (routing != null) {
- paramRouting = Strings.splitStringByCommaToSet(routing);
- }
-
- for (String aliasOrIndex : aliasesOrIndices) {
- ImmutableOpenMap indexToRoutingMap = aliases.get(aliasOrIndex);
- if (indexToRoutingMap != null && !indexToRoutingMap.isEmpty()) {
- for (ObjectObjectCursor indexRouting : indexToRoutingMap) {
- if (!norouting.contains(indexRouting.key)) {
- if (!indexRouting.value.searchRoutingValues().isEmpty()) {
- // Routing alias
- if (routings == null) {
- routings = newHashMap();
- }
- Set r = routings.get(indexRouting.key);
- if (r == null) {
- r = new HashSet<>();
- routings.put(indexRouting.key, r);
- }
- r.addAll(indexRouting.value.searchRoutingValues());
- if (paramRouting != null) {
- r.retainAll(paramRouting);
- }
- if (r.isEmpty()) {
- routings.remove(indexRouting.key);
- }
- } else {
- // Non-routing alias
- if (!norouting.contains(indexRouting.key)) {
- norouting.add(indexRouting.key);
- if (paramRouting != null) {
- Set r = new HashSet<>(paramRouting);
- if (routings == null) {
- routings = newHashMap();
- }
- routings.put(indexRouting.key, r);
- } else {
- if (routings != null) {
- routings.remove(indexRouting.key);
- }
- }
- }
- }
- }
- }
- } else {
- // Index
- if (!norouting.contains(aliasOrIndex)) {
- norouting.add(aliasOrIndex);
- if (paramRouting != null) {
- Set r = new HashSet<>(paramRouting);
- if (routings == null) {
- routings = newHashMap();
- }
- routings.put(aliasOrIndex, r);
- } else {
- if (routings != null) {
- routings.remove(aliasOrIndex);
- }
- }
- }
- }
-
- }
- if (routings == null || routings.isEmpty()) {
- return null;
- }
- return routings;
- }
-
- private Map> resolveSearchRoutingSingleValue(@Nullable String routing, String aliasOrIndex) {
- Map