Internal: Add METADATA_READ and METADATA_WRITE blocks

This commit splits the current ClusterBlockLevel.METADATA into two disctins ClusterBlockLevel.METADATA_READ and ClusterBlockLevel.METADATA_WRITE blocks. It allows to make a distinction between
an operation that modifies the index or cluster metadata and an operation that does not change any metadata.

Before this commit, many operations where blocked when the cluster was read-only: Cluster Stats, Get Mappings, Get Snapshot, Get Index Settings, etc. Now those operations are allowed even when
the cluster or the index is read-only.

Related to #8102, #2833

Closes #3703
Closes #5855
Closes #10521
Closes #10522
This commit is contained in:
tlrx 2015-01-08 18:31:04 +01:00 committed by Tanguy Leroux
parent 2e2e345dcb
commit adc0807c68
81 changed files with 1912 additions and 252 deletions

View File

@ -0,0 +1,30 @@
---
"Test indices.exists on a read only index":
- do:
indices.create:
index: test_index_ro
- do:
indices.put_settings:
index: test_index_ro
body:
index.blocks.read_only: true
- do:
indices.exists:
index: test_index_ro
- is_true: ''
- do:
indices.put_settings:
index: test_index_ro
body:
index.blocks.read_only: false
- do:
indices.exists:
index: test_index_ro
- is_true: ''

View File

@ -75,7 +75,8 @@ public class TransportNodesShutdownAction extends TransportMasterNodeOperationAc
@Override
protected ClusterBlockException checkBlock(NodesShutdownRequest request, ClusterState state) {
return state.blocks().globalBlockedException(ClusterBlockLevel.METADATA);
// Stopping a node impacts the cluster state, so we check for the METADATA_WRITE block here
return state.blocks().globalBlockedException(ClusterBlockLevel.METADATA_WRITE);
}
@Override

View File

@ -65,7 +65,7 @@ public class TransportDeleteRepositoryAction extends TransportMasterNodeOperatio
@Override
protected ClusterBlockException checkBlock(DeleteRepositoryRequest request, ClusterState state) {
return state.blocks().indexBlockedException(ClusterBlockLevel.METADATA, "");
return state.blocks().indexBlockedException(ClusterBlockLevel.METADATA_WRITE, "");
}
@Override

View File

@ -65,7 +65,7 @@ public class TransportGetRepositoriesAction extends TransportMasterNodeReadOpera
@Override
protected ClusterBlockException checkBlock(GetRepositoriesRequest request, ClusterState state) {
return state.blocks().indexBlockedException(ClusterBlockLevel.METADATA, "");
return state.blocks().indexBlockedException(ClusterBlockLevel.METADATA_READ, "");
}
@Override

View File

@ -65,7 +65,7 @@ public class TransportPutRepositoryAction extends TransportMasterNodeOperationAc
@Override
protected ClusterBlockException checkBlock(PutRepositoryRequest request, ClusterState state) {
return state.blocks().indexBlockedException(ClusterBlockLevel.METADATA, "");
return state.blocks().indexBlockedException(ClusterBlockLevel.METADATA_WRITE, "");
}
@Override

View File

@ -69,7 +69,7 @@ public class TransportVerifyRepositoryAction extends TransportMasterNodeOperatio
@Override
protected ClusterBlockException checkBlock(VerifyRepositoryRequest request, ClusterState state) {
return state.blocks().indexBlockedException(ClusterBlockLevel.METADATA, "");
return state.blocks().indexBlockedException(ClusterBlockLevel.METADATA_READ, "");
}
@Override

View File

@ -58,7 +58,7 @@ public class TransportClusterRerouteAction extends TransportMasterNodeOperationA
@Override
protected ClusterBlockException checkBlock(ClusterRerouteRequest request, ClusterState state) {
return state.blocks().globalBlockedException(ClusterBlockLevel.METADATA);
return state.blocks().globalBlockedException(ClusterBlockLevel.METADATA_WRITE);
}
@Override

View File

@ -76,7 +76,7 @@ public class TransportClusterUpdateSettingsAction extends TransportMasterNodeOpe
request.persistentSettings().getAsMap().isEmpty() && request.transientSettings().getAsMap().size() == 1 && request.transientSettings().get(MetaData.SETTING_READ_ONLY) != null) {
return null;
}
return state.blocks().globalBlockedException(ClusterBlockLevel.METADATA);
return state.blocks().globalBlockedException(ClusterBlockLevel.METADATA_WRITE);
}

View File

@ -58,7 +58,7 @@ public class TransportClusterSearchShardsAction extends TransportMasterNodeReadO
@Override
protected ClusterBlockException checkBlock(ClusterSearchShardsRequest request, ClusterState state) {
return state.blocks().indicesBlockedException(ClusterBlockLevel.METADATA, state.metaData().concreteIndices(request.indicesOptions(), request.indices()));
return state.blocks().indicesBlockedException(ClusterBlockLevel.METADATA_READ, state.metaData().concreteIndices(request.indicesOptions(), request.indices()));
}
@Override

View File

@ -65,7 +65,7 @@ public class TransportCreateSnapshotAction extends TransportMasterNodeOperationA
@Override
protected ClusterBlockException checkBlock(CreateSnapshotRequest request, ClusterState state) {
return state.blocks().indexBlockedException(ClusterBlockLevel.METADATA, "");
return state.blocks().indexBlockedException(ClusterBlockLevel.METADATA_WRITE, "");
}
@Override

View File

@ -64,7 +64,7 @@ public class TransportDeleteSnapshotAction extends TransportMasterNodeOperationA
@Override
protected ClusterBlockException checkBlock(DeleteSnapshotRequest request, ClusterState state) {
return state.blocks().indexBlockedException(ClusterBlockLevel.METADATA, "");
return state.blocks().indexBlockedException(ClusterBlockLevel.METADATA_WRITE, "");
}
@Override

View File

@ -67,7 +67,7 @@ public class TransportGetSnapshotsAction extends TransportMasterNodeOperationAct
@Override
protected ClusterBlockException checkBlock(GetSnapshotsRequest request, ClusterState state) {
return state.blocks().indexBlockedException(ClusterBlockLevel.METADATA, "");
return state.blocks().indexBlockedException(ClusterBlockLevel.METADATA_READ, "");
}
@Override

View File

@ -65,7 +65,13 @@ public class TransportRestoreSnapshotAction extends TransportMasterNodeOperation
@Override
protected ClusterBlockException checkBlock(RestoreSnapshotRequest request, ClusterState state) {
return state.blocks().indexBlockedException(ClusterBlockLevel.METADATA, "");
// Restoring a snapshot might change the global state and create/change an index,
// so we need to check for METADATA_WRITE and WRITE blocks
ClusterBlockException blockException = state.blocks().indexBlockedException(ClusterBlockLevel.METADATA_WRITE, "");
if (blockException != null) {
return blockException;
}
return state.blocks().indexBlockedException(ClusterBlockLevel.WRITE, "");
}
@Override

View File

@ -70,7 +70,7 @@ public class TransportSnapshotsStatusAction extends TransportMasterNodeOperation
@Override
protected ClusterBlockException checkBlock(SnapshotsStatusRequest request, ClusterState state) {
return state.blocks().globalBlockedException(ClusterBlockLevel.METADATA);
return state.blocks().globalBlockedException(ClusterBlockLevel.METADATA_READ);
}
@Override

View File

@ -53,7 +53,7 @@ public class TransportPendingClusterTasksAction extends TransportMasterNodeReadO
@Override
protected ClusterBlockException checkBlock(PendingClusterTasksRequest request, ClusterState state) {
return state.blocks().globalBlockedException(ClusterBlockLevel.METADATA);
return state.blocks().globalBlockedException(ClusterBlockLevel.METADATA_READ);
}
@Override

View File

@ -78,7 +78,7 @@ public class TransportIndicesAliasesAction extends TransportMasterNodeOperationA
indices.add(index);
}
}
return state.blocks().indicesBlockedException(ClusterBlockLevel.METADATA, indices.toArray(new String[indices.size()]));
return state.blocks().indicesBlockedException(ClusterBlockLevel.METADATA_WRITE, indices.toArray(new String[indices.size()]));
}
@Override

View File

@ -49,7 +49,7 @@ public class TransportAliasesExistAction extends TransportMasterNodeReadOperatio
@Override
protected ClusterBlockException checkBlock(GetAliasesRequest request, ClusterState state) {
return state.blocks().indicesBlockedException(ClusterBlockLevel.METADATA, state.metaData().concreteIndices(request.indicesOptions(), request.indices()));
return state.blocks().indicesBlockedException(ClusterBlockLevel.METADATA_READ, state.metaData().concreteIndices(request.indicesOptions(), request.indices()));
}
@Override

View File

@ -52,7 +52,7 @@ public class TransportGetAliasesAction extends TransportMasterNodeReadOperationA
@Override
protected ClusterBlockException checkBlock(GetAliasesRequest request, ClusterState state) {
return state.blocks().indicesBlockedException(ClusterBlockLevel.METADATA, state.metaData().concreteIndices(request.indicesOptions(), request.indices()));
return state.blocks().indicesBlockedException(ClusterBlockLevel.METADATA_READ, state.metaData().concreteIndices(request.indicesOptions(), request.indices()));
}
@Override

View File

@ -175,12 +175,12 @@ public class TransportClearIndicesCacheAction extends TransportBroadcastOperatio
@Override
protected ClusterBlockException checkGlobalBlock(ClusterState state, ClearIndicesCacheRequest request) {
return state.blocks().globalBlockedException(ClusterBlockLevel.METADATA);
return state.blocks().globalBlockedException(ClusterBlockLevel.METADATA_WRITE);
}
@Override
protected ClusterBlockException checkRequestBlock(ClusterState state, ClearIndicesCacheRequest request, String[] concreteIndices) {
return state.blocks().indicesBlockedException(ClusterBlockLevel.METADATA, concreteIndices);
return state.blocks().indicesBlockedException(ClusterBlockLevel.METADATA_WRITE, concreteIndices);
}
}

View File

@ -76,7 +76,7 @@ public class TransportCloseIndexAction extends TransportMasterNodeOperationActio
@Override
protected ClusterBlockException checkBlock(CloseIndexRequest request, ClusterState state) {
return state.blocks().indicesBlockedException(ClusterBlockLevel.METADATA, state.metaData().concreteIndices(request.indicesOptions(), request.indices()));
return state.blocks().indicesBlockedException(ClusterBlockLevel.METADATA_WRITE, state.metaData().concreteIndices(request.indicesOptions(), request.indices()));
}
@Override

View File

@ -67,7 +67,7 @@ public class TransportCreateIndexAction extends TransportMasterNodeOperationActi
@Override
protected ClusterBlockException checkBlock(CreateIndexRequest request, ClusterState state) {
return state.blocks().indexBlockedException(ClusterBlockLevel.METADATA, request.index());
return state.blocks().indexBlockedException(ClusterBlockLevel.METADATA_WRITE, request.index());
}
@Override

View File

@ -76,7 +76,7 @@ public class TransportDeleteIndexAction extends TransportMasterNodeOperationActi
@Override
protected ClusterBlockException checkBlock(DeleteIndexRequest request, ClusterState state) {
return state.blocks().indicesBlockedException(ClusterBlockLevel.METADATA, state.metaData().concreteIndices(request.indicesOptions(), request.indices()));
return state.blocks().indicesBlockedException(ClusterBlockLevel.METADATA_WRITE, state.metaData().concreteIndices(request.indicesOptions(), request.indices()));
}
@Override

View File

@ -65,7 +65,7 @@ public class TransportIndicesExistsAction extends TransportMasterNodeReadOperati
protected ClusterBlockException checkBlock(IndicesExistsRequest request, ClusterState state) {
//make sure through indices options that the concrete indices call never throws IndexMissingException
IndicesOptions indicesOptions = IndicesOptions.fromOptions(true, true, request.indicesOptions().expandWildcardsOpen(), request.indicesOptions().expandWildcardsClosed());
return state.blocks().indicesBlockedException(ClusterBlockLevel.METADATA, clusterService.state().metaData().concreteIndices(indicesOptions, request.indices()));
return state.blocks().indicesBlockedException(ClusterBlockLevel.METADATA_READ, clusterService.state().metaData().concreteIndices(indicesOptions, request.indices()));
}
@Override

View File

@ -62,7 +62,7 @@ public class TransportTypesExistsAction extends TransportMasterNodeReadOperation
@Override
protected ClusterBlockException checkBlock(TypesExistsRequest request, ClusterState state) {
return state.blocks().indicesBlockedException(ClusterBlockLevel.METADATA, state.metaData().concreteIndices(request.indicesOptions(), request.indices()));
return state.blocks().indicesBlockedException(ClusterBlockLevel.METADATA_READ, state.metaData().concreteIndices(request.indicesOptions(), request.indices()));
}
@Override

View File

@ -120,11 +120,11 @@ public class TransportFlushAction extends TransportBroadcastOperationAction<Flus
@Override
protected ClusterBlockException checkGlobalBlock(ClusterState state, FlushRequest request) {
return state.blocks().globalBlockedException(ClusterBlockLevel.METADATA);
return state.blocks().globalBlockedException(ClusterBlockLevel.METADATA_WRITE);
}
@Override
protected ClusterBlockException checkRequestBlock(ClusterState state, FlushRequest countRequest, String[] concreteIndices) {
return state.blocks().indicesBlockedException(ClusterBlockLevel.METADATA, concreteIndices);
return state.blocks().indicesBlockedException(ClusterBlockLevel.METADATA_WRITE, concreteIndices);
}
}

View File

@ -60,7 +60,7 @@ public class TransportGetIndexAction extends TransportClusterInfoAction<GetIndex
@Override
protected ClusterBlockException checkBlock(GetIndexRequest request, ClusterState state) {
return state.blocks().indicesBlockedException(ClusterBlockLevel.METADATA, state.metaData().concreteIndices(request.indicesOptions(), request.indices()));
return state.blocks().indicesBlockedException(ClusterBlockLevel.METADATA_READ, state.metaData().concreteIndices(request.indicesOptions(), request.indices()));
}
@Override

View File

@ -29,6 +29,8 @@ import org.elasticsearch.action.support.ActionFilters;
import org.elasticsearch.action.support.single.custom.TransportSingleCustomOperationAction;
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.routing.ShardsIterator;
import org.elasticsearch.common.collect.MapBuilder;
import org.elasticsearch.common.inject.Inject;
@ -38,10 +40,10 @@ import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.IndexService;
import org.elasticsearch.index.mapper.DocumentFieldMappers;
import org.elasticsearch.index.mapper.DocumentMapper;
import org.elasticsearch.index.mapper.FieldMapper;
import org.elasticsearch.index.IndexService;
import org.elasticsearch.index.shard.ShardId;
import org.elasticsearch.indices.IndicesService;
import org.elasticsearch.indices.TypeMissingException;
@ -134,6 +136,11 @@ public class TransportGetFieldMappingsIndexAction extends TransportSingleCustomO
return new GetFieldMappingsResponse();
}
@Override
protected ClusterBlockException checkRequestBlock(ClusterState state, InternalRequest request) {
return state.blocks().indexBlockedException(ClusterBlockLevel.METADATA_READ, request.concreteIndex());
}
private static final ToXContent.Params includeDefaultsParams = new ToXContent.Params() {
final static String INCLUDE_DEFAULTS = "include_defaults";

View File

@ -51,7 +51,7 @@ public class TransportGetMappingsAction extends TransportClusterInfoAction<GetMa
@Override
protected ClusterBlockException checkBlock(GetMappingsRequest request, ClusterState state) {
return state.blocks().indicesBlockedException(ClusterBlockLevel.METADATA, state.metaData().concreteIndices(request.indicesOptions(), request.indices()));
return state.blocks().indicesBlockedException(ClusterBlockLevel.METADATA_READ, state.metaData().concreteIndices(request.indicesOptions(), request.indices()));
}
@Override

View File

@ -66,7 +66,7 @@ public class TransportPutMappingAction extends TransportMasterNodeOperationActio
@Override
protected ClusterBlockException checkBlock(PutMappingRequest request, ClusterState state) {
return state.blocks().indicesBlockedException(ClusterBlockLevel.METADATA, clusterService.state().metaData().concreteIndices(request.indicesOptions(), request.indices()));
return state.blocks().indicesBlockedException(ClusterBlockLevel.METADATA_WRITE, clusterService.state().metaData().concreteIndices(request.indicesOptions(), request.indices()));
}
@Override

View File

@ -76,7 +76,7 @@ public class TransportOpenIndexAction extends TransportMasterNodeOperationAction
@Override
protected ClusterBlockException checkBlock(OpenIndexRequest request, ClusterState state) {
return state.blocks().indicesBlockedException(ClusterBlockLevel.METADATA, state.metaData().concreteIndices(request.indicesOptions(), request.indices()));
return state.blocks().indicesBlockedException(ClusterBlockLevel.METADATA_WRITE, state.metaData().concreteIndices(request.indicesOptions(), request.indices()));
}
@Override

View File

@ -121,11 +121,11 @@ public class TransportOptimizeAction extends TransportBroadcastOperationAction<O
@Override
protected ClusterBlockException checkGlobalBlock(ClusterState state, OptimizeRequest request) {
return state.blocks().globalBlockedException(ClusterBlockLevel.METADATA);
return state.blocks().globalBlockedException(ClusterBlockLevel.METADATA_WRITE);
}
@Override
protected ClusterBlockException checkRequestBlock(ClusterState state, OptimizeRequest request, String[] concreteIndices) {
return state.blocks().indicesBlockedException(ClusterBlockLevel.METADATA, concreteIndices);
return state.blocks().indicesBlockedException(ClusterBlockLevel.METADATA_WRITE, concreteIndices);
}
}

View File

@ -122,11 +122,11 @@ public class TransportRefreshAction extends TransportBroadcastOperationAction<Re
@Override
protected ClusterBlockException checkGlobalBlock(ClusterState state, RefreshRequest request) {
return state.blocks().globalBlockedException(ClusterBlockLevel.METADATA);
return state.blocks().globalBlockedException(ClusterBlockLevel.METADATA_WRITE);
}
@Override
protected ClusterBlockException checkRequestBlock(ClusterState state, RefreshRequest countRequest, String[] concreteIndices) {
return state.blocks().indicesBlockedException(ClusterBlockLevel.METADATA, concreteIndices);
return state.blocks().indicesBlockedException(ClusterBlockLevel.METADATA_WRITE, concreteIndices);
}
}

View File

@ -83,12 +83,12 @@ public class TransportIndicesSegmentsAction extends TransportBroadcastOperationA
@Override
protected ClusterBlockException checkGlobalBlock(ClusterState state, IndicesSegmentsRequest request) {
return state.blocks().globalBlockedException(ClusterBlockLevel.METADATA);
return state.blocks().globalBlockedException(ClusterBlockLevel.METADATA_READ);
}
@Override
protected ClusterBlockException checkRequestBlock(ClusterState state, IndicesSegmentsRequest countRequest, String[] concreteIndices) {
return state.blocks().indicesBlockedException(ClusterBlockLevel.METADATA, concreteIndices);
return state.blocks().indicesBlockedException(ClusterBlockLevel.METADATA_READ, concreteIndices);
}
@Override

View File

@ -62,7 +62,7 @@ public class TransportGetSettingsAction extends TransportMasterNodeReadOperation
@Override
protected ClusterBlockException checkBlock(GetSettingsRequest request, ClusterState state) {
return state.blocks().indicesBlockedException(ClusterBlockLevel.METADATA, state.metaData().concreteIndices(request.indicesOptions(), request.indices()));
return state.blocks().indicesBlockedException(ClusterBlockLevel.METADATA_READ, state.metaData().concreteIndices(request.indicesOptions(), request.indices()));
}

View File

@ -58,14 +58,14 @@ public class TransportUpdateSettingsAction extends TransportMasterNodeOperationA
@Override
protected ClusterBlockException checkBlock(UpdateSettingsRequest request, ClusterState state) {
// allow for dedicated changes to the metadata blocks, so we don't block those to allow to "re-enable" it
ClusterBlockException globalBlock = state.blocks().globalBlockedException(ClusterBlockLevel.METADATA);
ClusterBlockException globalBlock = state.blocks().globalBlockedException(ClusterBlockLevel.METADATA_WRITE);
if (globalBlock != null) {
return globalBlock;
}
if (request.settings().getAsMap().size() == 1 && (request.settings().get(IndexMetaData.SETTING_BLOCKS_METADATA) != null || request.settings().get(IndexMetaData.SETTING_READ_ONLY) != null )) {
return null;
}
return state.blocks().indicesBlockedException(ClusterBlockLevel.METADATA, state.metaData().concreteIndices(request.indicesOptions(), request.indices()));
return state.blocks().indicesBlockedException(ClusterBlockLevel.METADATA_WRITE, state.metaData().concreteIndices(request.indicesOptions(), request.indices()));
}
@Override

View File

@ -84,12 +84,12 @@ public class TransportIndicesStatsAction extends TransportBroadcastOperationActi
@Override
protected ClusterBlockException checkGlobalBlock(ClusterState state, IndicesStatsRequest request) {
return state.blocks().globalBlockedException(ClusterBlockLevel.METADATA);
return state.blocks().globalBlockedException(ClusterBlockLevel.METADATA_READ);
}
@Override
protected ClusterBlockException checkRequestBlock(ClusterState state, IndicesStatsRequest request, String[] concreteIndices) {
return state.blocks().indicesBlockedException(ClusterBlockLevel.METADATA, concreteIndices);
return state.blocks().indicesBlockedException(ClusterBlockLevel.METADATA_READ, concreteIndices);
}

View File

@ -64,7 +64,7 @@ public class TransportDeleteIndexTemplateAction extends TransportMasterNodeOpera
@Override
protected ClusterBlockException checkBlock(DeleteIndexTemplateRequest request, ClusterState state) {
return state.blocks().indexBlockedException(ClusterBlockLevel.METADATA, "");
return state.blocks().indexBlockedException(ClusterBlockLevel.METADATA_WRITE, "");
}
@Override

View File

@ -54,7 +54,7 @@ public class TransportGetIndexTemplatesAction extends TransportMasterNodeReadOpe
@Override
protected ClusterBlockException checkBlock(GetIndexTemplatesRequest request, ClusterState state) {
return state.blocks().globalBlockedException(ClusterBlockLevel.METADATA);
return state.blocks().globalBlockedException(ClusterBlockLevel.METADATA_READ);
}
@Override

View File

@ -64,7 +64,7 @@ public class TransportPutIndexTemplateAction extends TransportMasterNodeOperatio
@Override
protected ClusterBlockException checkBlock(PutIndexTemplateRequest request, ClusterState state) {
return state.blocks().indexBlockedException(ClusterBlockLevel.METADATA, "");
return state.blocks().indexBlockedException(ClusterBlockLevel.METADATA_WRITE, "");
}
@Override

View File

@ -73,7 +73,7 @@ public class TransportDeleteWarmerAction extends TransportMasterNodeOperationAct
@Override
protected ClusterBlockException checkBlock(DeleteWarmerRequest request, ClusterState state) {
return state.blocks().indicesBlockedException(ClusterBlockLevel.METADATA, clusterService.state().metaData().concreteIndices(request.indicesOptions(), request.indices()));
return state.blocks().indicesBlockedException(ClusterBlockLevel.METADATA_WRITE, clusterService.state().metaData().concreteIndices(request.indicesOptions(), request.indices()));
}
@Override

View File

@ -22,7 +22,6 @@ package org.elasticsearch.action.admin.indices.warmer.get;
import com.google.common.collect.ImmutableList;
import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.action.ActionListener;
import org.elasticsearch.action.admin.indices.alias.get.GetAliasesRequest;
import org.elasticsearch.action.support.ActionFilters;
import org.elasticsearch.action.support.master.info.TransportClusterInfoAction;
import org.elasticsearch.cluster.ClusterService;
@ -56,7 +55,7 @@ public class TransportGetWarmersAction extends TransportClusterInfoAction<GetWar
@Override
protected ClusterBlockException checkBlock(GetWarmersRequest request, ClusterState state) {
return state.blocks().indicesBlockedException(ClusterBlockLevel.METADATA, state.metaData().concreteIndices(request.indicesOptions(), request.indices()));
return state.blocks().indicesBlockedException(ClusterBlockLevel.METADATA_READ, state.metaData().concreteIndices(request.indicesOptions(), request.indices()));
}
@Override

View File

@ -80,7 +80,13 @@ public class TransportPutWarmerAction extends TransportMasterNodeOperationAction
@Override
protected ClusterBlockException checkBlock(PutWarmerRequest request, ClusterState state) {
String[] concreteIndices = clusterService.state().metaData().concreteIndices(request.searchRequest().indicesOptions(), request.searchRequest().indices());
return state.blocks().indicesBlockedException(ClusterBlockLevel.METADATA, concreteIndices);
ClusterBlockException status = state.blocks().indicesBlockedException(ClusterBlockLevel.METADATA_WRITE, concreteIndices);
if (status != null) {
return status;
}
// PutWarmer executes a SearchQuery before adding the new warmer to the cluster state,
// so we need to check the same block as TransportSearchTypeAction here
return state.blocks().indicesBlockedException(ClusterBlockLevel.READ, concreteIndices);
}
@Override

View File

@ -131,7 +131,7 @@ public class ClusterBlock implements Serializable, Streamable, ToXContent {
final int len = in.readVInt();
ArrayList<ClusterBlockLevel> levels = new ArrayList<>();
for (int i = 0; i < len; i++) {
levels.add(ClusterBlockLevel.fromId(in.readVInt()));
levels.addAll(ClusterBlockLevel.fromId(in.readVInt()));
}
this.levels = EnumSet.copyOf(levels);
retryable = in.readBoolean();
@ -145,7 +145,7 @@ public class ClusterBlock implements Serializable, Streamable, ToXContent {
out.writeString(description);
out.writeVInt(levels.size());
for (ClusterBlockLevel level : levels) {
out.writeVInt(level.id());
out.writeVInt(level.toId(out.getVersion()));
}
out.writeBoolean(retryable);
out.writeBoolean(disableStatePersistence);

View File

@ -20,6 +20,7 @@
package org.elasticsearch.cluster.block;
import org.elasticsearch.ElasticsearchIllegalArgumentException;
import org.elasticsearch.Version;
import java.util.EnumSet;
@ -29,9 +30,18 @@ import java.util.EnumSet;
public enum ClusterBlockLevel {
READ(0),
WRITE(1),
METADATA(2);
public static final EnumSet<ClusterBlockLevel> ALL = EnumSet.of(READ, WRITE, METADATA);
/**
* Since 1.6.0, METADATA has been split into two distincts cluster block levels
* @deprecated Use METADATA_READ or METADATA_WRITE instead.
*/
@Deprecated
METADATA(2),
METADATA_READ(3),
METADATA_WRITE(4);
public static final EnumSet<ClusterBlockLevel> ALL = EnumSet.of(READ, WRITE, METADATA_READ, METADATA_WRITE);
public static final EnumSet<ClusterBlockLevel> READ_WRITE = EnumSet.of(READ, WRITE);
private final int id;
@ -44,13 +54,35 @@ public enum ClusterBlockLevel {
return this.id;
}
public static ClusterBlockLevel fromId(int id) {
/**
* Returns the ClusterBlockLevel's id according to a given version, this to ensure backward compatibility.
*
* @param version the version
* @return the ClusterBlockLevel's id
*/
public int toId(Version version) {
assert version != null : "Version shouldn't be null";
// Since 1.6.0, METADATA has been split into two distincts cluster block levels
if (version.before(Version.V_1_6_0)) {
if (this == ClusterBlockLevel.METADATA_READ || this == ClusterBlockLevel.METADATA_WRITE) {
return ClusterBlockLevel.METADATA.id();
}
}
return id();
}
static EnumSet<ClusterBlockLevel> fromId(int id) {
if (id == 0) {
return READ;
return EnumSet.of(READ);
} else if (id == 1) {
return WRITE;
return EnumSet.of(WRITE);
} else if (id == 2) {
return METADATA;
// Since 1.6.0, METADATA has been split into two distincts cluster block levels
return EnumSet.of(METADATA_READ, METADATA_WRITE);
} else if (id == 3) {
return EnumSet.of(METADATA_READ);
} else if (id == 4) {
return EnumSet.of(METADATA_WRITE);
}
throw new ElasticsearchIllegalArgumentException("No cluster block level matching [" + id + "]");
}

View File

@ -117,10 +117,10 @@ public class IndexMetaData {
return factory;
}
public static final ClusterBlock INDEX_READ_ONLY_BLOCK = new ClusterBlock(5, "index read-only (api)", false, false, RestStatus.FORBIDDEN, EnumSet.of(ClusterBlockLevel.WRITE, ClusterBlockLevel.METADATA));
public static final ClusterBlock INDEX_READ_ONLY_BLOCK = new ClusterBlock(5, "index read-only (api)", false, false, RestStatus.FORBIDDEN, EnumSet.of(ClusterBlockLevel.WRITE, ClusterBlockLevel.METADATA_WRITE));
public static final ClusterBlock INDEX_READ_BLOCK = new ClusterBlock(7, "index read (api)", false, false, RestStatus.FORBIDDEN, EnumSet.of(ClusterBlockLevel.READ));
public static final ClusterBlock INDEX_WRITE_BLOCK = new ClusterBlock(8, "index write (api)", false, false, RestStatus.FORBIDDEN, EnumSet.of(ClusterBlockLevel.WRITE));
public static final ClusterBlock INDEX_METADATA_BLOCK = new ClusterBlock(9, "index metadata (api)", false, false, RestStatus.FORBIDDEN, EnumSet.of(ClusterBlockLevel.METADATA));
public static final ClusterBlock INDEX_METADATA_BLOCK = new ClusterBlock(9, "index metadata (api)", false, false, RestStatus.FORBIDDEN, EnumSet.of(ClusterBlockLevel.METADATA_WRITE, ClusterBlockLevel.METADATA_READ));
public static enum State {
OPEN((byte) 0),

View File

@ -127,7 +127,7 @@ public class MetaData implements Iterable<IndexMetaData> {
public static final String SETTING_READ_ONLY = "cluster.blocks.read_only";
public static final ClusterBlock CLUSTER_READ_ONLY_BLOCK = new ClusterBlock(6, "cluster read-only (api)", false, false, RestStatus.FORBIDDEN, EnumSet.of(ClusterBlockLevel.WRITE, ClusterBlockLevel.METADATA));
public static final ClusterBlock CLUSTER_READ_ONLY_BLOCK = new ClusterBlock(6, "cluster read-only (api)", false, false, RestStatus.FORBIDDEN, EnumSet.of(ClusterBlockLevel.WRITE, ClusterBlockLevel.METADATA_WRITE));
public static final MetaData EMPTY_META_DATA = builder().build();

View File

@ -44,7 +44,7 @@ public class DiscoverySettings extends AbstractComponent {
public final static int NO_MASTER_BLOCK_ID = 2;
public final static ClusterBlock NO_MASTER_BLOCK_ALL = new ClusterBlock(NO_MASTER_BLOCK_ID, "no master", true, true, RestStatus.SERVICE_UNAVAILABLE, ClusterBlockLevel.ALL);
public final static ClusterBlock NO_MASTER_BLOCK_WRITES = new ClusterBlock(NO_MASTER_BLOCK_ID, "no master", true, false, RestStatus.SERVICE_UNAVAILABLE, EnumSet.of(ClusterBlockLevel.WRITE, ClusterBlockLevel.METADATA));
public final static ClusterBlock NO_MASTER_BLOCK_WRITES = new ClusterBlock(NO_MASTER_BLOCK_ID, "no master", true, false, RestStatus.SERVICE_UNAVAILABLE, EnumSet.of(ClusterBlockLevel.WRITE, ClusterBlockLevel.METADATA_WRITE));
private volatile ClusterBlock noMasterBlock;
private volatile TimeValue publishTimeout = DEFAULT_PUBLISH_TIMEOUT;

View File

@ -73,7 +73,7 @@ import java.util.Set;
*/
public class TribeService extends AbstractLifecycleComponent<TribeService> {
public static final ClusterBlock TRIBE_METADATA_BLOCK = new ClusterBlock(10, "tribe node, metadata not allowed", false, false, RestStatus.BAD_REQUEST, EnumSet.of(ClusterBlockLevel.METADATA));
public static final ClusterBlock TRIBE_METADATA_BLOCK = new ClusterBlock(10, "tribe node, metadata not allowed", false, false, RestStatus.BAD_REQUEST, EnumSet.of(ClusterBlockLevel.METADATA_READ, ClusterBlockLevel.METADATA_WRITE));
public static final ClusterBlock TRIBE_WRITE_BLOCK = new ClusterBlock(11, "tribe node, write not allowed", false, false, RestStatus.BAD_REQUEST, EnumSet.of(ClusterBlockLevel.WRITE));
public static Settings processSettings(Settings settings) {

View File

@ -0,0 +1,115 @@
/*
* 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.action.admin.cluster.repositories;
import org.elasticsearch.action.admin.cluster.repositories.get.GetRepositoriesResponse;
import org.elasticsearch.action.admin.cluster.repositories.verify.VerifyRepositoryResponse;
import org.elasticsearch.cluster.metadata.MetaData;
import org.elasticsearch.common.settings.ImmutableSettings;
import org.elasticsearch.test.ElasticsearchIntegrationTest;
import org.elasticsearch.test.ElasticsearchIntegrationTest.ClusterScope;
import org.junit.Test;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertBlocked;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasSize;
/**
* This class tests that repository operations (Put, Delete, Verify) are blocked when the cluster is read-only.
*
* The @ClusterScope TEST is needed because this class updates the cluster setting "cluster.blocks.read_only".
*/
@ClusterScope(scope = ElasticsearchIntegrationTest.Scope.TEST)
public class RepositoryBlocksTests extends ElasticsearchIntegrationTest {
@Test
public void testPutRepositoryWithBlocks() {
logger.info("--> registering a repository is blocked when the cluster is read only");
try {
setClusterReadOnly(true);
assertBlocked(client().admin().cluster().preparePutRepository("test-repo-blocks")
.setType("fs")
.setVerify(false)
.setSettings(ImmutableSettings.settingsBuilder().put("location", createTempDir())), MetaData.CLUSTER_READ_ONLY_BLOCK);
} finally {
setClusterReadOnly(false);
}
logger.info("--> registering a repository is allowed when the cluster is not read only");
assertAcked(client().admin().cluster().preparePutRepository("test-repo-blocks")
.setType("fs")
.setVerify(false)
.setSettings(ImmutableSettings.settingsBuilder().put("location", createTempDir())));
}
@Test
public void testVerifyRepositoryWithBlocks() {
assertAcked(client().admin().cluster().preparePutRepository("test-repo-blocks")
.setType("fs")
.setVerify(false)
.setSettings(ImmutableSettings.settingsBuilder().put("location", createTempDir())));
// This test checks that the Get Repository operation is never blocked, even if the cluster is read only.
try {
setClusterReadOnly(true);
VerifyRepositoryResponse response = client().admin().cluster().prepareVerifyRepository("test-repo-blocks").execute().actionGet();
assertThat(response.getNodes().length, equalTo(cluster().numDataAndMasterNodes()));
} finally {
setClusterReadOnly(false);
}
}
@Test
public void testDeleteRepositoryWithBlocks() {
assertAcked(client().admin().cluster().preparePutRepository("test-repo-blocks")
.setType("fs")
.setVerify(false)
.setSettings(ImmutableSettings.settingsBuilder().put("location", createTempDir())));
logger.info("--> deleting a repository is blocked when the cluster is read only");
try {
setClusterReadOnly(true);
assertBlocked(client().admin().cluster().prepareDeleteRepository("test-repo-blocks"), MetaData.CLUSTER_READ_ONLY_BLOCK);
} finally {
setClusterReadOnly(false);
}
logger.info("--> deleting a repository is allowed when the cluster is not read only");
assertAcked(client().admin().cluster().prepareDeleteRepository("test-repo-blocks"));
}
@Test
public void testGetRepositoryWithBlocks() {
assertAcked(client().admin().cluster().preparePutRepository("test-repo-blocks")
.setType("fs")
.setVerify(false)
.setSettings(ImmutableSettings.settingsBuilder().put("location", createTempDir())));
// This test checks that the Get Repository operation is never blocked, even if the cluster is read only.
try {
setClusterReadOnly(true);
GetRepositoriesResponse response = client().admin().cluster().prepareGetRepositories("test-repo-blocks").execute().actionGet();
assertThat(response.repositories(), hasSize(1));
} finally {
setClusterReadOnly(false);
}
}
}

View File

@ -0,0 +1,159 @@
/*
* 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.action.admin.cluster.snapshots;
import org.elasticsearch.action.admin.cluster.repositories.verify.VerifyRepositoryResponse;
import org.elasticsearch.action.admin.cluster.snapshots.create.CreateSnapshotResponse;
import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotResponse;
import org.elasticsearch.action.admin.cluster.snapshots.get.GetSnapshotsResponse;
import org.elasticsearch.action.admin.cluster.snapshots.restore.RestoreSnapshotResponse;
import org.elasticsearch.action.admin.cluster.snapshots.status.SnapshotsStatusResponse;
import org.elasticsearch.cluster.metadata.MetaData;
import org.elasticsearch.common.settings.ImmutableSettings;
import org.elasticsearch.rest.RestStatus;
import org.elasticsearch.test.ElasticsearchIntegrationTest;
import org.elasticsearch.test.ElasticsearchIntegrationTest.ClusterScope;
import org.junit.Before;
import org.junit.Test;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertBlocked;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasSize;
/**
* This class tests that snapshot operations (Create, Delete, Restore) are blocked when the cluster is read-only.
*
* The @ClusterScope TEST is needed because this class updates the cluster setting "cluster.blocks.read_only".
*/
@ClusterScope(scope = ElasticsearchIntegrationTest.Scope.TEST)
public class SnapshotBlocksTests extends ElasticsearchIntegrationTest {
protected static final String INDEX_NAME = "test-blocks";
protected static final String REPOSITORY_NAME = "repo-" + INDEX_NAME;
protected static final String SNAPSHOT_NAME = "snapshot-0";
@Before
protected void setUpRepository() throws Exception {
createIndex(INDEX_NAME);
int docs = between(10, 100);
for (int i = 0; i < docs; i++) {
client().prepareIndex(INDEX_NAME, "type").setSource("test", "init").execute().actionGet();
}
logger.info("--> register a repository");
assertAcked(client().admin().cluster().preparePutRepository(REPOSITORY_NAME)
.setType("fs")
.setSettings(ImmutableSettings.settingsBuilder().put("location", createTempDir())));
logger.info("--> verify the repository");
VerifyRepositoryResponse verifyResponse = client().admin().cluster().prepareVerifyRepository(REPOSITORY_NAME).get();
assertThat(verifyResponse.getNodes().length, equalTo(cluster().numDataAndMasterNodes()));
logger.info("--> create a snapshot");
CreateSnapshotResponse snapshotResponse = client().admin().cluster().prepareCreateSnapshot(REPOSITORY_NAME, SNAPSHOT_NAME)
.setIncludeGlobalState(true)
.setWaitForCompletion(true)
.execute().actionGet();
assertThat(snapshotResponse.status(), equalTo(RestStatus.OK));
ensureSearchable();
}
@Test
public void testCreateSnapshotWithBlocks() {
logger.info("--> creating a snapshot is blocked when the cluster is read only");
try {
setClusterReadOnly(true);
assertBlocked(client().admin().cluster().prepareCreateSnapshot(REPOSITORY_NAME, "snapshot-1"), MetaData.CLUSTER_READ_ONLY_BLOCK);
} finally {
setClusterReadOnly(false);
}
logger.info("--> creating a snapshot is allowed when the cluster is not read only");
CreateSnapshotResponse response = client().admin().cluster().prepareCreateSnapshot(REPOSITORY_NAME, "snapshot-1")
.setWaitForCompletion(true)
.execute().actionGet();
assertThat(response.status(), equalTo(RestStatus.OK));
}
@Test
public void testDeleteSnapshotWithBlocks() {
logger.info("--> deleting a snapshot is blocked when the cluster is read only");
try {
setClusterReadOnly(true);
assertBlocked(client().admin().cluster().prepareDeleteSnapshot(REPOSITORY_NAME, SNAPSHOT_NAME), MetaData.CLUSTER_READ_ONLY_BLOCK);
} finally {
setClusterReadOnly(false);
}
logger.info("--> deleting a snapshot is allowed when the cluster is not read only");
DeleteSnapshotResponse response = client().admin().cluster().prepareDeleteSnapshot(REPOSITORY_NAME, SNAPSHOT_NAME).execute().actionGet();
assertThat(response.isAcknowledged(), equalTo(true));
}
@Test
public void testRestoreSnapshotWithBlocks() {
assertAcked(client().admin().indices().prepareDelete(INDEX_NAME));
assertFalse(client().admin().indices().prepareExists(INDEX_NAME).get().isExists());
logger.info("--> restoring a snapshot is blocked when the cluster is read only");
try {
setClusterReadOnly(true);
assertBlocked(client().admin().cluster().prepareRestoreSnapshot(REPOSITORY_NAME, SNAPSHOT_NAME), MetaData.CLUSTER_READ_ONLY_BLOCK);
} finally {
setClusterReadOnly(false);
}
logger.info("--> creating a snapshot is allowed when the cluster is not read only");
RestoreSnapshotResponse response = client().admin().cluster().prepareRestoreSnapshot(REPOSITORY_NAME, SNAPSHOT_NAME)
.setWaitForCompletion(true)
.execute().actionGet();
assertThat(response.status(), equalTo(RestStatus.OK));
assertTrue(client().admin().indices().prepareExists(INDEX_NAME).get().isExists());
}
@Test
public void testGetSnapshotWithBlocks() {
// This test checks that the Get Snapshot operation is never blocked, even if the cluster is read only.
try {
setClusterReadOnly(true);
GetSnapshotsResponse response = client().admin().cluster().prepareGetSnapshots(REPOSITORY_NAME).execute().actionGet();
assertThat(response.getSnapshots(), hasSize(1));
assertThat(response.getSnapshots().get(0).name(), equalTo(SNAPSHOT_NAME));
} finally {
setClusterReadOnly(false);
}
}
@Test
public void testSnapshotStatusWithBlocks() {
// This test checks that the Snapshot Status operation is never blocked, even if the cluster is read only.
try {
setClusterReadOnly(true);
SnapshotsStatusResponse response = client().admin().cluster().prepareSnapshotStatus(REPOSITORY_NAME)
.setSnapshots(SNAPSHOT_NAME)
.execute().actionGet();
assertThat(response.getSnapshots(), hasSize(1));
assertThat(response.getSnapshots().get(0).getState().completed(), equalTo(true));
} finally {
setClusterReadOnly(false);
}
}
}

View File

@ -0,0 +1,57 @@
/*
* 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.action.admin.cluster.tasks;
import org.elasticsearch.test.ElasticsearchIntegrationTest;
import org.elasticsearch.test.ElasticsearchIntegrationTest.ClusterScope;
import org.junit.Test;
import java.util.Arrays;
import static org.elasticsearch.cluster.metadata.IndexMetaData.*;
@ClusterScope(scope = ElasticsearchIntegrationTest.Scope.TEST)
public class PendingTasksBlocksTests extends ElasticsearchIntegrationTest {
@Test
public void testPendingTasksWithBlocks() {
createIndex("test");
ensureGreen("test");
// This test checks that the Pending Cluster Tasks operation is never blocked, even if an index is read only or whatever.
for (String blockSetting : Arrays.asList(SETTING_BLOCKS_READ, SETTING_BLOCKS_WRITE, SETTING_READ_ONLY, SETTING_BLOCKS_METADATA)) {
try {
enableIndexBlock("test", blockSetting);
PendingClusterTasksResponse response = client().admin().cluster().preparePendingClusterTasks().execute().actionGet();
assertNotNull(response.getPendingTasks());
} finally {
disableIndexBlock("test", blockSetting);
}
}
try {
setClusterReadOnly(true);
PendingClusterTasksResponse response = client().admin().cluster().preparePendingClusterTasks().execute().actionGet();
assertNotNull(response.getPendingTasks());
} finally {
setClusterReadOnly(false);
}
}
}

View File

@ -0,0 +1,64 @@
/*
* 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.action.admin.indices.cache.clear;
import org.elasticsearch.test.ElasticsearchIntegrationTest;
import org.elasticsearch.test.ElasticsearchIntegrationTest.ClusterScope;
import org.junit.Test;
import java.util.Arrays;
import static org.elasticsearch.cluster.metadata.IndexMetaData.*;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertBlocked;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertNoFailures;
import static org.hamcrest.Matchers.equalTo;
@ClusterScope(scope = ElasticsearchIntegrationTest.Scope.TEST)
public class ClearIndicesCacheBlocksTests extends ElasticsearchIntegrationTest {
@Test
public void testClearIndicesCacheWithBlocks() {
createIndex("test");
ensureGreen("test");
NumShards numShards = getNumShards("test");
// Request is not blocked
for (String blockSetting : Arrays.asList(SETTING_BLOCKS_READ, SETTING_BLOCKS_WRITE)) {
try {
enableIndexBlock("test", blockSetting);
ClearIndicesCacheResponse clearIndicesCacheResponse = client().admin().indices().prepareClearCache("test").setFieldDataCache(true).setFilterCache(true).setIdCache(true).execute().actionGet();
assertNoFailures(clearIndicesCacheResponse);
assertThat(clearIndicesCacheResponse.getSuccessfulShards(), equalTo(numShards.totalNumShards));
} finally {
disableIndexBlock("test", blockSetting);
}
}
// Request is blocked
for (String blockSetting : Arrays.asList(SETTING_READ_ONLY, SETTING_BLOCKS_METADATA)) {
try {
enableIndexBlock("test", blockSetting);
assertBlocked(client().admin().indices().prepareClearCache("test").setFieldDataCache(true).setFilterCache(true).setIdCache(true));
} finally {
disableIndexBlock("test", blockSetting);
}
}
}
}

View File

@ -34,6 +34,7 @@ import org.junit.Test;
import java.util.HashMap;
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertBlocked;
import static org.hamcrest.Matchers.*;
import static org.hamcrest.core.IsNull.notNullValue;
@ -140,4 +141,14 @@ public class CreateIndexTests extends ElasticsearchIntegrationTest{
e.getMessage().contains("index must have 0 or more replica shards"), equalTo(true));
}
}
@Test
public void testCreateIndexWithBlocks() {
try {
setClusterReadOnly(true);
assertBlocked(prepareCreate("test"));
} finally {
setClusterReadOnly(false);
}
}
}

View File

@ -0,0 +1,43 @@
/*
* 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.action.admin.indices.delete;
import org.elasticsearch.test.ElasticsearchIntegrationTest;
import org.elasticsearch.test.ElasticsearchIntegrationTest.ClusterScope;
import org.junit.Test;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertBlocked;
@ClusterScope(scope = ElasticsearchIntegrationTest.Scope.TEST)
public class DeleteIndexBlocksTests extends ElasticsearchIntegrationTest{
@Test
public void testDeleteIndexWithBlocks() {
createIndex("test");
ensureGreen("test");
try {
setClusterReadOnly(true);
assertBlocked(client().admin().indices().prepareDelete("test"));
} finally {
setClusterReadOnly(false);
}
}
}

View File

@ -0,0 +1,82 @@
/*
* 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.action.admin.indices.flush;
import org.elasticsearch.test.ElasticsearchIntegrationTest;
import org.elasticsearch.test.ElasticsearchIntegrationTest.ClusterScope;
import org.junit.Test;
import java.util.Arrays;
import static org.elasticsearch.cluster.metadata.IndexMetaData.*;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertBlocked;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertNoFailures;
import static org.hamcrest.Matchers.equalTo;
@ClusterScope(scope = ElasticsearchIntegrationTest.Scope.TEST)
public class FlushBlocksTests extends ElasticsearchIntegrationTest {
@Test
public void testFlushWithBlocks() {
createIndex("test");
ensureGreen("test");
NumShards numShards = getNumShards("test");
int docs = between(10, 100);
for (int i = 0; i < docs; i++) {
client().prepareIndex("test", "type", "" + i).setSource("test", "init").execute().actionGet();
}
// Request is not blocked
for (String blockSetting : Arrays.asList(SETTING_BLOCKS_READ, SETTING_BLOCKS_WRITE)) {
try {
enableIndexBlock("test", blockSetting);
FlushResponse response = client().admin().indices().prepareFlush("test").execute().actionGet();
assertNoFailures(response);
assertThat(response.getSuccessfulShards(), equalTo(numShards.totalNumShards));
} finally {
disableIndexBlock("test", blockSetting);
}
}
// Request is blocked
for (String blockSetting : Arrays.asList(SETTING_READ_ONLY, SETTING_BLOCKS_METADATA)) {
try {
enableIndexBlock("test", blockSetting);
assertBlocked(client().admin().indices().prepareFlush("test"));
} finally {
disableIndexBlock("test", blockSetting);
}
}
// Flushing all indices is blocked when the cluster is read-only
try {
FlushResponse response = client().admin().indices().prepareFlush().execute().actionGet();
assertNoFailures(response);
assertThat(response.getSuccessfulShards(), equalTo(numShards.totalNumShards));
setClusterReadOnly(true);
assertBlocked(client().admin().indices().prepareFlush());
} finally {
setClusterReadOnly(false);
}
}
}

View File

@ -20,7 +20,6 @@
package org.elasticsearch.action.admin.indices.get;
import com.google.common.collect.ImmutableList;
import org.elasticsearch.action.admin.indices.alias.Alias;
import org.elasticsearch.action.admin.indices.get.GetIndexRequest.Feature;
import org.elasticsearch.cluster.metadata.AliasMetaData;
@ -34,12 +33,13 @@ import org.elasticsearch.test.ElasticsearchIntegrationTest;
import org.junit.Test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import static org.elasticsearch.cluster.metadata.IndexMetaData.*;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
import static org.hamcrest.Matchers.anyOf;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.notNullValue;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertBlocked;
import static org.hamcrest.Matchers.*;
@ElasticsearchIntegrationTest.SuiteScopeTest
public class GetIndexTests extends ElasticsearchIntegrationTest {
@ -205,6 +205,32 @@ public class GetIndexTests extends ElasticsearchIntegrationTest {
assertEmptyWarmers(response);
}
@Test
public void testGetIndexWithBlocks() {
for (String block : Arrays.asList(SETTING_BLOCKS_READ, SETTING_BLOCKS_WRITE, SETTING_READ_ONLY)) {
try {
enableIndexBlock("idx", block);
GetIndexResponse response = client().admin().indices().prepareGetIndex().addIndices("idx")
.addFeatures(Feature.MAPPINGS, Feature.ALIASES).get();
String[] indices = response.indices();
assertThat(indices, notNullValue());
assertThat(indices.length, equalTo(1));
assertThat(indices[0], equalTo("idx"));
assertMappings(response, "idx");
assertAliases(response, "idx");
} finally {
disableIndexBlock("idx", block);
}
}
try {
enableIndexBlock("idx", SETTING_BLOCKS_METADATA);
assertBlocked(client().admin().indices().prepareGetIndex().addIndices("idx").addFeatures(Feature.MAPPINGS, Feature.ALIASES), INDEX_METADATA_BLOCK);
} finally {
disableIndexBlock("idx", SETTING_BLOCKS_METADATA);
}
}
private GetIndexResponse runWithRandomFeatureMethod(GetIndexRequestBuilder requestBuilder, Feature... features) {
if (randomBoolean()) {
return requestBuilder.addFeatures(features).get();

View File

@ -0,0 +1,82 @@
/*
* 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.action.admin.indices.optimize;
import org.elasticsearch.test.ElasticsearchIntegrationTest;
import org.elasticsearch.test.ElasticsearchIntegrationTest.ClusterScope;
import org.junit.Test;
import java.util.Arrays;
import static org.elasticsearch.cluster.metadata.IndexMetaData.*;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertBlocked;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertNoFailures;
import static org.hamcrest.Matchers.equalTo;
@ClusterScope(scope = ElasticsearchIntegrationTest.Scope.TEST)
public class OptimizeBlocksTests extends ElasticsearchIntegrationTest {
@Test
public void testOptimizeWithBlocks() {
createIndex("test");
ensureGreen("test");
NumShards numShards = getNumShards("test");
int docs = between(10, 100);
for (int i = 0; i < docs; i++) {
client().prepareIndex("test", "type", "" + i).setSource("test", "init").execute().actionGet();
}
// Request is not blocked
for (String blockSetting : Arrays.asList(SETTING_BLOCKS_READ, SETTING_BLOCKS_WRITE)) {
try {
enableIndexBlock("test", blockSetting);
OptimizeResponse response = client().admin().indices().prepareOptimize("test").execute().actionGet();
assertNoFailures(response);
assertThat(response.getSuccessfulShards(), equalTo(numShards.totalNumShards));
} finally {
disableIndexBlock("test", blockSetting);
}
}
// Request is blocked
for (String blockSetting : Arrays.asList(SETTING_READ_ONLY, SETTING_BLOCKS_METADATA)) {
try {
enableIndexBlock("test", blockSetting);
assertBlocked(client().admin().indices().prepareOptimize("test"));
} finally {
disableIndexBlock("test", blockSetting);
}
}
// Optimizing all indices is blocked when the cluster is read-only
try {
OptimizeResponse response = client().admin().indices().prepareOptimize().execute().actionGet();
assertNoFailures(response);
assertThat(response.getSuccessfulShards(), equalTo(numShards.totalNumShards));
setClusterReadOnly(true);
assertBlocked(client().admin().indices().prepareFlush());
} finally {
setClusterReadOnly(false);
}
}
}

View File

@ -0,0 +1,78 @@
/*
* 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.action.admin.indices.refresh;
import org.elasticsearch.test.ElasticsearchIntegrationTest;
import org.elasticsearch.test.ElasticsearchIntegrationTest.ClusterScope;
import org.junit.Test;
import java.util.Arrays;
import static org.elasticsearch.cluster.metadata.IndexMetaData.*;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertBlocked;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertNoFailures;
import static org.hamcrest.Matchers.equalTo;
@ClusterScope(scope = ElasticsearchIntegrationTest.Scope.TEST)
public class RefreshBlocksTests extends ElasticsearchIntegrationTest {
@Test
public void testRefreshWithBlocks() {
createIndex("test");
ensureGreen("test");
NumShards numShards = getNumShards("test");
// Request is not blocked
for (String blockSetting : Arrays.asList(SETTING_BLOCKS_READ, SETTING_BLOCKS_WRITE)) {
try {
enableIndexBlock("test", blockSetting);
RefreshResponse response = client().admin().indices().prepareRefresh("test").execute().actionGet();
assertNoFailures(response);
assertThat(response.getSuccessfulShards(), equalTo(numShards.totalNumShards));
} finally {
disableIndexBlock("test", blockSetting);
}
}
// Request is blocked
for (String blockSetting : Arrays.asList(SETTING_READ_ONLY, SETTING_BLOCKS_METADATA)) {
try {
enableIndexBlock("test", blockSetting);
assertBlocked(client().admin().indices().prepareRefresh("test"));
} finally {
disableIndexBlock("test", blockSetting);
}
}
// Refreshing all indices is blocked when the cluster is read-only
try {
RefreshResponse response = client().admin().indices().prepareRefresh().execute().actionGet();
assertNoFailures(response);
assertThat(response.getSuccessfulShards(), equalTo(numShards.totalNumShards));
setClusterReadOnly(true);
assertBlocked(client().admin().indices().prepareRefresh());
} finally {
setClusterReadOnly(false);
}
}
}

View File

@ -0,0 +1,65 @@
/*
* 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.action.admin.indices.segments;
import org.elasticsearch.test.ElasticsearchIntegrationTest;
import org.elasticsearch.test.ElasticsearchIntegrationTest.ClusterScope;
import org.junit.Test;
import java.util.Arrays;
import static org.elasticsearch.cluster.metadata.IndexMetaData.*;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertBlocked;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertNoFailures;
@ClusterScope(scope = ElasticsearchIntegrationTest.Scope.TEST)
public class IndicesSegmentsBlocksTests extends ElasticsearchIntegrationTest {
@Test
public void testIndicesSegmentsWithBlocks() {
createIndex("test-blocks");
ensureGreen("test-blocks");
int docs = between(10, 100);
for (int i = 0; i < docs; i++) {
client().prepareIndex("test-blocks", "type", "" + i).setSource("test", "init").execute().actionGet();
}
client().admin().indices().prepareFlush("test-blocks").get();
// Request is not blocked
for (String blockSetting : Arrays.asList(SETTING_BLOCKS_READ, SETTING_BLOCKS_WRITE, SETTING_READ_ONLY)) {
try {
enableIndexBlock("test-blocks", blockSetting);
IndicesSegmentResponse response = client().admin().indices().prepareSegments("test-blocks").execute().actionGet();
assertNoFailures(response);
} finally {
disableIndexBlock("test-blocks", blockSetting);
}
}
// Request is blocked
try {
enableIndexBlock("test-blocks", SETTING_BLOCKS_METADATA);
assertBlocked(client().admin().indices().prepareSegments("test-blocks"));
} finally {
disableIndexBlock("test-blocks", SETTING_BLOCKS_METADATA);
}
}
}

View File

@ -0,0 +1,62 @@
/*
* 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.action.admin.indices.stats;
import org.elasticsearch.cluster.block.ClusterBlockException;
import org.elasticsearch.cluster.metadata.IndexMetaData;
import org.elasticsearch.test.ElasticsearchIntegrationTest;
import org.elasticsearch.test.ElasticsearchIntegrationTest.ClusterScope;
import org.junit.Test;
import java.util.Arrays;
import static org.elasticsearch.cluster.metadata.IndexMetaData.*;
@ClusterScope(scope = ElasticsearchIntegrationTest.Scope.TEST)
public class IndicesStatsBlocksTests extends ElasticsearchIntegrationTest {
@Test
public void testIndicesStatsWithBlocks() {
createIndex("ro");
ensureGreen("ro");
// Request is not blocked
for (String blockSetting : Arrays.asList(SETTING_BLOCKS_READ, SETTING_BLOCKS_WRITE, SETTING_READ_ONLY)) {
try {
enableIndexBlock("ro", blockSetting);
IndicesStatsResponse indicesStatsResponse = client().admin().indices().prepareStats("ro").execute().actionGet();
assertNotNull(indicesStatsResponse.getIndex("ro"));
} finally {
disableIndexBlock("ro", blockSetting);
}
}
// Request is blocked
try {
enableIndexBlock("ro", IndexMetaData.SETTING_BLOCKS_METADATA);
client().admin().indices().prepareStats("ro").execute().actionGet();
fail("Exists should fail when " + IndexMetaData.SETTING_BLOCKS_METADATA + " is true");
} catch (ClusterBlockException e) {
// Ok, a ClusterBlockException is expected
} finally {
disableIndexBlock("ro", IndexMetaData.SETTING_BLOCKS_METADATA);
}
}
}

View File

@ -49,6 +49,7 @@ import org.elasticsearch.search.sort.SortOrder;
import org.elasticsearch.test.ElasticsearchIntegrationTest;
import org.junit.Test;
import java.util.Arrays;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@ -57,14 +58,13 @@ import java.util.concurrent.TimeUnit;
import static com.google.common.collect.Sets.newHashSet;
import static org.elasticsearch.client.Requests.createIndexRequest;
import static org.elasticsearch.client.Requests.indexRequest;
import static org.elasticsearch.cluster.metadata.IndexMetaData.*;
import static org.elasticsearch.common.settings.ImmutableSettings.settingsBuilder;
import static org.elasticsearch.index.query.FilterBuilders.*;
import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery;
import static org.elasticsearch.index.query.QueryBuilders.rangeQuery;
import static org.elasticsearch.test.hamcrest.CollectionAssertions.hasKey;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertSearchResponse;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertHitCount;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.*;
import static org.hamcrest.Matchers.*;
/**
@ -908,10 +908,10 @@ public class IndexAliasesTests extends ElasticsearchIntegrationTest {
assertAcked(prepareCreate("test")
.addMapping("type", "field", "type=string")
.setAliases("{\n" +
" \"alias1\" : {},\n" +
" \"alias2\" : {\"filter\" : {\"term\": {\"field\":\"value\"}}},\n" +
" \"alias3\" : { \"index_routing\" : \"index\", \"search_routing\" : \"search\"}\n" +
"}"));
" \"alias1\" : {},\n" +
" \"alias2\" : {\"filter\" : {\"term\": {\"field\":\"value\"}}},\n" +
" \"alias3\" : { \"index_routing\" : \"index\", \"search_routing\" : \"search\"}\n" +
"}"));
checkAliases();
}
@ -989,13 +989,56 @@ public class IndexAliasesTests extends ElasticsearchIntegrationTest {
@Test
public void testAliasesFilterWithHasChildQuery() throws Exception {
assertAcked(prepareCreate("my-index")
.addMapping("parent")
.addMapping("child", "_parent", "type=parent")
.addMapping("parent")
.addMapping("child", "_parent", "type=parent")
);
assertAcked(admin().indices().prepareAliases().addAlias("my-index", "filter1", hasChildFilter("child", matchAllQuery())));
assertAcked(admin().indices().prepareAliases().addAlias("my-index", "filter2", hasParentFilter("child", matchAllQuery())));
}
@Test
public void testAliasesWithBlocks() {
createIndex("test");
ensureGreen();
for (String block : Arrays.asList(SETTING_BLOCKS_READ, SETTING_BLOCKS_WRITE)) {
try {
enableIndexBlock("test", block);
assertAcked(admin().indices().prepareAliases().addAlias("test", "alias1").addAlias("test", "alias2"));
assertAcked(admin().indices().prepareAliases().removeAlias("test", "alias1"));
assertThat(admin().indices().prepareGetAliases("alias2").execute().actionGet().getAliases().get("test").size(), equalTo(1));
assertThat(admin().indices().prepareAliasesExist("alias2").get().exists(), equalTo(true));
} finally {
disableIndexBlock("test", block);
}
}
try {
enableIndexBlock("test", SETTING_READ_ONLY);
assertBlocked(admin().indices().prepareAliases().addAlias("test", "alias3"), INDEX_READ_ONLY_BLOCK);
assertBlocked(admin().indices().prepareAliases().removeAlias("test", "alias2"), INDEX_READ_ONLY_BLOCK);
assertThat(admin().indices().prepareGetAliases("alias2").execute().actionGet().getAliases().get("test").size(), equalTo(1));
assertThat(admin().indices().prepareAliasesExist("alias2").get().exists(), equalTo(true));
} finally {
disableIndexBlock("test", SETTING_READ_ONLY);
}
try {
enableIndexBlock("test", SETTING_BLOCKS_METADATA);
assertBlocked(admin().indices().prepareAliases().addAlias("test", "alias3"), INDEX_METADATA_BLOCK);
assertBlocked(admin().indices().prepareAliases().removeAlias("test", "alias2"), INDEX_METADATA_BLOCK);
assertBlocked(admin().indices().prepareGetAliases("alias2"), INDEX_METADATA_BLOCK);
assertBlocked(admin().indices().prepareAliasesExist("alias2"), INDEX_METADATA_BLOCK);
} finally {
disableIndexBlock("test", SETTING_BLOCKS_METADATA);
}
}
private void checkAliases() {
GetAliasesResponse getAliasesResponse = admin().indices().prepareGetAliases("alias1").get();
assertThat(getAliasesResponse.getAliases().get("test").size(), equalTo(1));

View File

@ -49,14 +49,14 @@ public class SimpleBlocksTests extends ElasticsearchIntegrationTest {
canIndexExists("test1");
// cluster.read_only = true: block write and metadata
setClusterReadOnly("true");
setClusterReadOnly(true);
canNotCreateIndex("test2");
// even if index has index.read_only = false
canNotIndexDocument("test1");
canNotIndexExists("test1");
canIndexExists("test1");
// cluster.read_only = false: removes the block
setClusterReadOnly("false");
setClusterReadOnly(false);
canCreateIndex("test2");
canIndexDocument("test2");
canIndexDocument("test1");
@ -71,7 +71,7 @@ public class SimpleBlocksTests extends ElasticsearchIntegrationTest {
// adds index write and metadata block
setIndexReadOnly( "ro", "true");
canNotIndexDocument("ro");
canNotIndexExists("ro");
canIndexExists("ro");
// other indices not blocked
canCreateIndex("rw");
@ -156,11 +156,6 @@ public class SimpleBlocksTests extends ElasticsearchIntegrationTest {
}
}
private void setClusterReadOnly(String value) {
Settings settings = settingsBuilder().put(MetaData.SETTING_READ_ONLY, value).build();
client().admin().cluster().prepareUpdateSettings().setTransientSettings(settings).execute().actionGet();
}
private void setIndexReadOnly(String index, Object value) {
HashMap<String, Object> newSettings = new HashMap<>();
newSettings.put(IndexMetaData.SETTING_READ_ONLY, value);

View File

@ -1,117 +0,0 @@
/*
* 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;
import org.elasticsearch.action.admin.cluster.settings.ClusterUpdateSettingsResponse;
import org.elasticsearch.action.admin.cluster.state.ClusterStateResponse;
import org.elasticsearch.action.admin.indices.alias.Alias;
import org.elasticsearch.client.Requests;
import org.elasticsearch.cluster.block.ClusterBlock;
import org.elasticsearch.cluster.block.ClusterBlockException;
import org.elasticsearch.common.settings.ImmutableSettings;
import org.elasticsearch.rest.RestStatus;
import org.elasticsearch.test.ElasticsearchIntegrationTest;
import org.junit.Test;
import static org.elasticsearch.test.ElasticsearchIntegrationTest.*;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
import static org.hamcrest.Matchers.*;
/**
* Scoped as test, because the if the test with cluster read only block fails, all other tests fail as well, as this is not cleaned up properly
*/
@ClusterScope(scope= Scope.TEST)
public class BlockClusterStatsTests extends ElasticsearchIntegrationTest {
@Test
public void testBlocks() throws Exception {
assertAcked(prepareCreate("foo").addAlias(new Alias("foo-alias")));
try {
assertAcked(client().admin().indices().prepareUpdateSettings("foo").setSettings(
ImmutableSettings.settingsBuilder().put("index.blocks.read_only", true)));
ClusterUpdateSettingsResponse updateSettingsResponse = client().admin().cluster().prepareUpdateSettings().setTransientSettings(
ImmutableSettings.settingsBuilder().put("cluster.blocks.read_only", true).build()).get();
assertThat(updateSettingsResponse.isAcknowledged(), is(true));
ClusterStateResponse clusterStateResponseUnfiltered = client().admin().cluster().prepareState().setLocal(true).clear().setBlocks(true).get();
assertThat(clusterStateResponseUnfiltered.getState().blocks().global(), hasSize(1));
assertThat(clusterStateResponseUnfiltered.getState().blocks().indices().size(), is(1));
ClusterStateResponse clusterStateResponse = client().admin().cluster().prepareState().clear().get();
assertThat(clusterStateResponse.getState().blocks().global(), hasSize(0));
assertThat(clusterStateResponse.getState().blocks().indices().size(), is(0));
try {
client().admin().indices().prepareClose("foo-alias").get();
fail("close index should have failed");
} catch(ClusterBlockException e) {
assertClusterAndIndexBlocks(e);
}
try {
client().admin().indices().preparePutMapping("foo-alias").setType("type1").setSource("field1", "type=string").get();
fail("put mapping should have failed");
} catch(ClusterBlockException e) {
assertClusterAndIndexBlocks(e);
}
try {
client().admin().indices().preparePutWarmer("foo-alias").setSearchRequest(Requests.searchRequest("foo-alias")).get();
fail("put warmer should have failed");
} catch(ClusterBlockException e) {
assertClusterAndIndexBlocks(e);
}
try {
client().admin().indices().prepareDeleteWarmer().setIndices("foo-alias").setNames("warmer1").get();
fail("delete warmer should have failed");
} catch(ClusterBlockException e) {
assertClusterAndIndexBlocks(e);
}
try {
client().admin().indices().prepareTypesExists("foo-alias").setTypes("test").get();
fail("types exists should have failed");
} catch(ClusterBlockException e) {
assertClusterAndIndexBlocks(e);
}
try {
client().admin().indices().prepareExists("foo-alias").get();
fail("indices exists should have failed");
} catch(ClusterBlockException e) {
assertClusterAndIndexBlocks(e);
}
} finally {
assertAcked(client().admin().cluster().prepareUpdateSettings().setTransientSettings(
ImmutableSettings.settingsBuilder().put("cluster.blocks.read_only", false).build()).get());
assertAcked(client().admin().indices().prepareUpdateSettings("foo").setSettings(
ImmutableSettings.settingsBuilder().put("index.blocks.read_only", false)));
}
}
private void assertClusterAndIndexBlocks(ClusterBlockException e) {
assertThat(e.blocks().size(), equalTo(2));
for (ClusterBlock clusterBlock : e.blocks()) {
assertThat(clusterBlock.status(), equalTo(RestStatus.FORBIDDEN));
assertThat(clusterBlock.id(), either(equalTo(5)).or(equalTo(6)));
assertThat(clusterBlock.description(), either(containsString("cluster read-only (api)")).or(containsString("index read-only (api)")));
}
}
}

View File

@ -24,6 +24,8 @@ import org.elasticsearch.action.admin.cluster.health.ClusterHealthResponse;
import org.elasticsearch.action.admin.cluster.health.ClusterHealthStatus;
import org.elasticsearch.action.admin.cluster.reroute.ClusterRerouteResponse;
import org.elasticsearch.cluster.ClusterState;
import org.elasticsearch.cluster.node.DiscoveryNode;
import org.elasticsearch.cluster.routing.ShardRouting;
import org.elasticsearch.cluster.routing.ShardRoutingState;
import org.elasticsearch.cluster.routing.allocation.RerouteExplanation;
import org.elasticsearch.cluster.routing.allocation.RoutingExplanations;
@ -31,7 +33,7 @@ import org.elasticsearch.cluster.routing.allocation.command.AllocateAllocationCo
import org.elasticsearch.cluster.routing.allocation.command.MoveAllocationCommand;
import org.elasticsearch.cluster.routing.allocation.decider.Decision;
import org.elasticsearch.cluster.routing.allocation.decider.DisableAllocationDecider;
import org.elasticsearch.cluster.routing.allocation.decider.EnableAllocationDecider;
import org.elasticsearch.cluster.routing.allocation.decider.EnableAllocationDecider.Allocation;
import org.elasticsearch.common.Priority;
import org.elasticsearch.common.io.FileSystemUtils;
import org.elasticsearch.common.logging.ESLogger;
@ -47,9 +49,14 @@ import java.nio.file.Path;
import java.util.Arrays;
import java.util.List;
import static org.elasticsearch.cluster.metadata.IndexMetaData.*;
import static org.elasticsearch.cluster.routing.allocation.decider.EnableAllocationDecider.CLUSTER_ROUTING_ALLOCATION_ENABLE;
import static org.elasticsearch.common.settings.ImmutableSettings.settingsBuilder;
import static org.elasticsearch.test.ElasticsearchIntegrationTest.Scope;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertBlocked;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasSize;
/**
*/
@ -70,7 +77,7 @@ public class ClusterRerouteTests extends ElasticsearchIntegrationTest {
@Test
public void rerouteWithCommands_enableAllocationSettings() throws Exception {
Settings commonSettings = settingsBuilder()
.put(EnableAllocationDecider.CLUSTER_ROUTING_ALLOCATION_ENABLE, EnableAllocationDecider.Allocation.NONE.name())
.put(CLUSTER_ROUTING_ALLOCATION_ENABLE, Allocation.NONE.name())
.build();
rerouteWithCommands(commonSettings);
}
@ -148,7 +155,7 @@ public class ClusterRerouteTests extends ElasticsearchIntegrationTest {
@Test
public void rerouteWithAllocateLocalGateway_enableAllocationSettings() throws Exception {
Settings commonSettings = settingsBuilder()
.put(EnableAllocationDecider.CLUSTER_ROUTING_ALLOCATION_ENABLE, EnableAllocationDecider.Allocation.NONE.name())
.put(CLUSTER_ROUTING_ALLOCATION_ENABLE, Allocation.NONE.name())
.build();
rerouteWithAllocateLocalGateway(commonSettings);
}
@ -241,7 +248,7 @@ public class ClusterRerouteTests extends ElasticsearchIntegrationTest {
logger.info("--> disable allocation");
Settings newSettings = settingsBuilder()
.put(EnableAllocationDecider.CLUSTER_ROUTING_ALLOCATION_ENABLE, EnableAllocationDecider.Allocation.NONE.name())
.put(CLUSTER_ROUTING_ALLOCATION_ENABLE, Allocation.NONE.name())
.build();
client().admin().cluster().prepareUpdateSettings().setTransientSettings(newSettings).execute().actionGet();
@ -264,4 +271,51 @@ public class ClusterRerouteTests extends ElasticsearchIntegrationTest {
assertThat(explanation.decisions().type(), equalTo(Decision.Type.YES));
}
@Test
public void testClusterRerouteWithBlocks() throws Exception {
List<String> nodesIds = internalCluster().startNodesAsync(2).get();
logger.info("--> create an index with 1 shard and 0 replicas");
assertAcked(prepareCreate("test-blocks").setSettings(settingsBuilder().put("index.number_of_shards", 1).put("index.number_of_replicas", 0)));
ensureGreen("test-blocks");
logger.info("--> check that the index has 1 shard");
ClusterState state = client().admin().cluster().prepareState().execute().actionGet().getState();
List<ShardRouting> shards = state.routingTable().allShards("test-blocks");
assertThat(shards, hasSize(1));
logger.info("--> check that the shard is allocated");
ShardRouting shard = shards.get(0);
assertThat(shard.assignedToNode(), equalTo(true));
logger.info("--> retrieve the node where the shard is allocated");
DiscoveryNode node = state.nodes().resolveNode(shard.currentNodeId());
assertNotNull(node);
// toggle is used to mve the shard from one node to another
int toggle = nodesIds.indexOf(node.getName());
// Rerouting shards is not blocked
for (String blockSetting : Arrays.asList(SETTING_BLOCKS_READ, SETTING_BLOCKS_WRITE, SETTING_READ_ONLY, SETTING_BLOCKS_METADATA)) {
try {
enableIndexBlock("test-blocks", blockSetting);
assertAcked(client().admin().cluster().prepareReroute()
.add(new MoveAllocationCommand(new ShardId("test-blocks", 0), nodesIds.get(toggle % 2), nodesIds.get(++toggle % 2))));
ClusterHealthResponse healthResponse = client().admin().cluster().prepareHealth().setWaitForYellowStatus().setWaitForRelocatingShards(0).execute().actionGet();
assertThat(healthResponse.isTimedOut(), equalTo(false));
} finally {
disableIndexBlock("test-blocks", blockSetting);
}
}
// Rerouting shards is blocked when the cluster is read only
try {
setClusterReadOnly(true);
assertBlocked(client().admin().cluster().prepareReroute()
.add(new MoveAllocationCommand(new ShardId("test-blocks", 1), nodesIds.get(toggle % 2), nodesIds.get(++toggle % 2))));
} finally {
setClusterReadOnly(false);
}
}
}

View File

@ -0,0 +1,84 @@
/*
* 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.block;
import org.elasticsearch.Version;
import org.elasticsearch.common.io.stream.BytesStreamInput;
import org.elasticsearch.common.io.stream.BytesStreamOutput;
import org.elasticsearch.rest.RestStatus;
import org.elasticsearch.test.ElasticsearchTestCase;
import org.junit.Test;
import java.util.EnumSet;
import static org.elasticsearch.cluster.block.ClusterBlockLevel.*;
import static org.elasticsearch.test.VersionUtils.randomVersion;
import static org.hamcrest.CoreMatchers.equalTo;
public class ClusterBlockTests extends ElasticsearchTestCase {
@Test
public void testSerialization() throws Exception {
int iterations = randomIntBetween(10, 100);
for (int i = 0; i < iterations; i++) {
// Get a random version
Version version = randomVersion(random());
// Get a random list of ClusterBlockLevels
EnumSet<ClusterBlockLevel> levels = EnumSet.noneOf(ClusterBlockLevel.class);
int nbLevels = randomIntBetween(1, ClusterBlockLevel.values().length);
for (int j = 0; j < nbLevels; j++) {
levels.add(randomFrom(ClusterBlockLevel.values()));
}
ClusterBlock clusterBlock = new ClusterBlock(randomInt(), "cluster block #" + randomInt(), randomBoolean(),
randomBoolean(), randomFrom(RestStatus.values()), levels);
BytesStreamOutput out = new BytesStreamOutput();
out.setVersion(version);
clusterBlock.writeTo(out);
BytesStreamInput in = new BytesStreamInput(out.bytes());
in.setVersion(version);
ClusterBlock result = ClusterBlock.readClusterBlock(in);
assertThat(result.id(), equalTo(clusterBlock.id()));
assertThat(result.status(), equalTo(clusterBlock.status()));
assertThat(result.description(), equalTo(clusterBlock.description()));
assertThat(result.retryable(), equalTo(clusterBlock.retryable()));
assertThat(result.disableStatePersistence(), equalTo(clusterBlock.disableStatePersistence()));
// This enum set is used to count the expected serialized/deserialized number of blocks
EnumSet<ClusterBlockLevel> expected = EnumSet.noneOf(ClusterBlockLevel.class);
for (ClusterBlockLevel level : clusterBlock.levels()) {
if (level == METADATA) {
assertTrue(result.levels().contains(METADATA_READ));
assertTrue(result.levels().contains(METADATA_WRITE));
} else {
assertTrue(result.levels().contains(level));
}
expected.addAll(ClusterBlockLevel.fromId(level.toId(version)));
}
assertThat(result.levels().size(), equalTo(expected.size()));
}
}
}

View File

@ -19,7 +19,9 @@
package org.elasticsearch.cluster.settings;
import org.elasticsearch.action.admin.cluster.settings.ClusterUpdateSettingsRequestBuilder;
import org.elasticsearch.action.admin.cluster.settings.ClusterUpdateSettingsResponse;
import org.elasticsearch.cluster.metadata.MetaData;
import org.elasticsearch.cluster.routing.allocation.decider.DisableAllocationDecider;
import org.elasticsearch.common.settings.ImmutableSettings;
import org.elasticsearch.common.settings.Settings;
@ -28,9 +30,11 @@ import org.elasticsearch.test.ElasticsearchIntegrationTest;
import org.hamcrest.Matchers;
import org.junit.Test;
import static org.elasticsearch.common.settings.ImmutableSettings.settingsBuilder;
import static org.elasticsearch.test.ElasticsearchIntegrationTest.ClusterScope;
import static org.elasticsearch.test.ElasticsearchIntegrationTest.Scope.TEST;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertBlocked;
import static org.hamcrest.Matchers.*;
@ClusterScope(scope = TEST)
@ -141,4 +145,39 @@ public class ClusterSettingsTests extends ElasticsearchIntegrationTest {
assertThat(response.getTransientSettings().getAsMap().entrySet(), Matchers.emptyIterable());
assertThat(discoverySettings.getPublishTimeout().seconds(), equalTo(1l));
}
@Test
public void testClusterUpdateSettingsWithBlocks() {
String key1 = "cluster.routing.allocation.enable";
Settings transientSettings = ImmutableSettings.builder().put(key1, false).build();
String key2 = "cluster.routing.allocation.node_concurrent_recoveries";
Settings persistentSettings = ImmutableSettings.builder().put(key2, "5").build();
ClusterUpdateSettingsRequestBuilder request = client().admin().cluster().prepareUpdateSettings()
.setTransientSettings(transientSettings)
.setPersistentSettings(persistentSettings);
// Cluster settings updates are blocked when the cluster is read only
try {
setClusterReadOnly(true);
assertBlocked(request, MetaData.CLUSTER_READ_ONLY_BLOCK);
// But it's possible to update the settings to update the "cluster.blocks.read_only" setting
Settings settings = settingsBuilder().put(MetaData.SETTING_READ_ONLY, false).build();
assertAcked(client().admin().cluster().prepareUpdateSettings().setTransientSettings(settings).get());
} finally {
setClusterReadOnly(false);
}
// It should work now
ClusterUpdateSettingsResponse response = request.execute().actionGet();
assertAcked(response);
assertThat(response.getTransientSettings().get(key1), notNullValue());
assertThat(response.getTransientSettings().get(key2), nullValue());
assertThat(response.getPersistentSettings().get(key1), nullValue());
assertThat(response.getPersistentSettings().get(key2), notNullValue());
}
}

View File

@ -27,8 +27,12 @@ import org.elasticsearch.test.ElasticsearchIntegrationTest;
import org.elasticsearch.test.ElasticsearchIntegrationTest.ClusterScope;
import org.junit.Test;
import java.util.Arrays;
import static org.elasticsearch.cluster.metadata.IndexMetaData.*;
import static org.elasticsearch.common.settings.ImmutableSettings.settingsBuilder;
import static org.elasticsearch.test.ElasticsearchIntegrationTest.*;
import static org.elasticsearch.test.ElasticsearchIntegrationTest.Scope;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertBlocked;
import static org.hamcrest.Matchers.equalTo;
/**
@ -123,4 +127,36 @@ public class ClusterSearchShardsTests extends ElasticsearchIntegrationTest {
assertThat(seenTest2, equalTo(true));
assertThat(response.getNodes().length, equalTo(2));
}
@Test
public void testClusterSearchShardsWithBlocks() {
createIndex("test-blocks");
NumShards numShards = getNumShards("test-blocks");
int docs = between(10, 100);
for (int i = 0; i < docs; i++) {
client().prepareIndex("test-blocks", "type", "" + i).setSource("test", "init").execute().actionGet();
}
ensureGreen("test-blocks");
// Request is not blocked
for (String blockSetting : Arrays.asList(SETTING_BLOCKS_READ, SETTING_BLOCKS_WRITE, SETTING_READ_ONLY)) {
try {
enableIndexBlock("test-blocks", blockSetting);
ClusterSearchShardsResponse response = client().admin().cluster().prepareSearchShards("test-blocks").execute().actionGet();
assertThat(response.getGroups().length, equalTo(numShards.numPrimaries));
} finally {
disableIndexBlock("test-blocks", blockSetting);
}
}
// Request is blocked
try {
enableIndexBlock("test-blocks", SETTING_BLOCKS_METADATA);
assertBlocked(client().admin().cluster().prepareSearchShards("test-blocks"));
} finally {
disableIndexBlock("test-blocks", SETTING_BLOCKS_METADATA);
}
}
}

View File

@ -51,7 +51,7 @@ public class RecoverAfterNodesTests extends ElasticsearchIntegrationTest {
ImmutableSet<ClusterBlock> blocks;
do {
blocks = nodeClient.admin().cluster().prepareState().setLocal(true).execute().actionGet()
.getState().blocks().global(ClusterBlockLevel.METADATA);
.getState().blocks().global(ClusterBlockLevel.METADATA_WRITE);
}
while (!blocks.isEmpty() && (System.currentTimeMillis() - start) < timeout.millis());
return blocks;
@ -67,17 +67,17 @@ public class RecoverAfterNodesTests extends ElasticsearchIntegrationTest {
logger.info("--> start node (1)");
Client clientNode1 = startNode(settingsBuilder().put("gateway.recover_after_nodes", 3));
assertThat(clientNode1.admin().cluster().prepareState().setLocal(true).execute().actionGet()
.getState().blocks().global(ClusterBlockLevel.METADATA),
.getState().blocks().global(ClusterBlockLevel.METADATA_WRITE),
hasItem(GatewayService.STATE_NOT_RECOVERED_BLOCK));
logger.info("--> start node (2)");
Client clientNode2 = startNode(settingsBuilder().put("gateway.recover_after_nodes", 3));
Thread.sleep(BLOCK_WAIT_TIMEOUT.millis());
assertThat(clientNode1.admin().cluster().prepareState().setLocal(true).execute().actionGet()
.getState().blocks().global(ClusterBlockLevel.METADATA),
.getState().blocks().global(ClusterBlockLevel.METADATA_WRITE),
hasItem(GatewayService.STATE_NOT_RECOVERED_BLOCK));
assertThat(clientNode2.admin().cluster().prepareState().setLocal(true).execute().actionGet()
.getState().blocks().global(ClusterBlockLevel.METADATA),
.getState().blocks().global(ClusterBlockLevel.METADATA_WRITE),
hasItem(GatewayService.STATE_NOT_RECOVERED_BLOCK));
logger.info("--> start node (3)");
@ -93,28 +93,28 @@ public class RecoverAfterNodesTests extends ElasticsearchIntegrationTest {
logger.info("--> start master_node (1)");
Client master1 = startNode(settingsBuilder().put("gateway.recover_after_master_nodes", 2).put("node.data", false).put("node.master", true));
assertThat(master1.admin().cluster().prepareState().setLocal(true).execute().actionGet()
.getState().blocks().global(ClusterBlockLevel.METADATA),
.getState().blocks().global(ClusterBlockLevel.METADATA_WRITE),
hasItem(GatewayService.STATE_NOT_RECOVERED_BLOCK));
logger.info("--> start data_node (1)");
Client data1 = startNode(settingsBuilder().put("gateway.recover_after_master_nodes", 2).put("node.data", true).put("node.master", false));
assertThat(master1.admin().cluster().prepareState().setLocal(true).execute().actionGet()
.getState().blocks().global(ClusterBlockLevel.METADATA),
.getState().blocks().global(ClusterBlockLevel.METADATA_WRITE),
hasItem(GatewayService.STATE_NOT_RECOVERED_BLOCK));
assertThat(data1.admin().cluster().prepareState().setLocal(true).execute().actionGet()
.getState().blocks().global(ClusterBlockLevel.METADATA),
.getState().blocks().global(ClusterBlockLevel.METADATA_WRITE),
hasItem(GatewayService.STATE_NOT_RECOVERED_BLOCK));
logger.info("--> start data_node (2)");
Client data2 = startNode(settingsBuilder().put("gateway.recover_after_master_nodes", 2).put("node.data", true).put("node.master", false));
assertThat(master1.admin().cluster().prepareState().setLocal(true).execute().actionGet()
.getState().blocks().global(ClusterBlockLevel.METADATA),
.getState().blocks().global(ClusterBlockLevel.METADATA_WRITE),
hasItem(GatewayService.STATE_NOT_RECOVERED_BLOCK));
assertThat(data1.admin().cluster().prepareState().setLocal(true).execute().actionGet()
.getState().blocks().global(ClusterBlockLevel.METADATA),
.getState().blocks().global(ClusterBlockLevel.METADATA_WRITE),
hasItem(GatewayService.STATE_NOT_RECOVERED_BLOCK));
assertThat(data2.admin().cluster().prepareState().setLocal(true).execute().actionGet()
.getState().blocks().global(ClusterBlockLevel.METADATA),
.getState().blocks().global(ClusterBlockLevel.METADATA_WRITE),
hasItem(GatewayService.STATE_NOT_RECOVERED_BLOCK));
logger.info("--> start master_node (2)");
@ -130,28 +130,28 @@ public class RecoverAfterNodesTests extends ElasticsearchIntegrationTest {
logger.info("--> start master_node (1)");
Client master1 = startNode(settingsBuilder().put("gateway.recover_after_data_nodes", 2).put("node.data", false).put("node.master", true));
assertThat(master1.admin().cluster().prepareState().setLocal(true).execute().actionGet()
.getState().blocks().global(ClusterBlockLevel.METADATA),
.getState().blocks().global(ClusterBlockLevel.METADATA_WRITE),
hasItem(GatewayService.STATE_NOT_RECOVERED_BLOCK));
logger.info("--> start data_node (1)");
Client data1 = startNode(settingsBuilder().put("gateway.recover_after_data_nodes", 2).put("node.data", true).put("node.master", false));
assertThat(master1.admin().cluster().prepareState().setLocal(true).execute().actionGet()
.getState().blocks().global(ClusterBlockLevel.METADATA),
.getState().blocks().global(ClusterBlockLevel.METADATA_WRITE),
hasItem(GatewayService.STATE_NOT_RECOVERED_BLOCK));
assertThat(data1.admin().cluster().prepareState().setLocal(true).execute().actionGet()
.getState().blocks().global(ClusterBlockLevel.METADATA),
.getState().blocks().global(ClusterBlockLevel.METADATA_WRITE),
hasItem(GatewayService.STATE_NOT_RECOVERED_BLOCK));
logger.info("--> start master_node (2)");
Client master2 = startNode(settingsBuilder().put("gateway.recover_after_data_nodes", 2).put("node.data", false).put("node.master", true));
assertThat(master2.admin().cluster().prepareState().setLocal(true).execute().actionGet()
.getState().blocks().global(ClusterBlockLevel.METADATA),
.getState().blocks().global(ClusterBlockLevel.METADATA_WRITE),
hasItem(GatewayService.STATE_NOT_RECOVERED_BLOCK));
assertThat(data1.admin().cluster().prepareState().setLocal(true).execute().actionGet()
.getState().blocks().global(ClusterBlockLevel.METADATA),
.getState().blocks().global(ClusterBlockLevel.METADATA_WRITE),
hasItem(GatewayService.STATE_NOT_RECOVERED_BLOCK));
assertThat(master2.admin().cluster().prepareState().setLocal(true).execute().actionGet()
.getState().blocks().global(ClusterBlockLevel.METADATA),
.getState().blocks().global(ClusterBlockLevel.METADATA_WRITE),
hasItem(GatewayService.STATE_NOT_RECOVERED_BLOCK));
logger.info("--> start data_node (2)");

View File

@ -731,25 +731,6 @@ public class IndicesOptionsIntegrationTests extends ElasticsearchIntegrationTest
assertThat(client().admin().indices().prepareGetWarmers("barbaz").setWarmers("test1").get().getWarmers().size(), equalTo(0));
}
@Test
// Indices exists never throws IndexMissingException, the indices options control its behaviour (return true or false)
public void testIndicesExists() throws Exception {
assertThat(client().admin().indices().prepareExists("foo").get().isExists(), equalTo(false));
assertThat(client().admin().indices().prepareExists("foo").setIndicesOptions(IndicesOptions.lenientExpandOpen()).get().isExists(), equalTo(true));
assertThat(client().admin().indices().prepareExists("foo*").get().isExists(), equalTo(false));
assertThat(client().admin().indices().prepareExists("foo*").setIndicesOptions(IndicesOptions.fromOptions(false, true, true, false)).get().isExists(), equalTo(true));
assertThat(client().admin().indices().prepareExists("_all").get().isExists(), equalTo(false));
createIndex("foo", "foobar", "bar", "barbaz");
ensureYellow();
assertThat(client().admin().indices().prepareExists("foo*").get().isExists(), equalTo(true));
assertThat(client().admin().indices().prepareExists("foobar").get().isExists(), equalTo(true));
assertThat(client().admin().indices().prepareExists("bar*").get().isExists(), equalTo(true));
assertThat(client().admin().indices().prepareExists("bar").get().isExists(), equalTo(true));
assertThat(client().admin().indices().prepareExists("_all").get().isExists(), equalTo(true));
}
@Test
public void testPutMapping() throws Exception {
verify(client().admin().indices().preparePutMapping("foo").setType("type1").setSource("field", "type=string"), true);

View File

@ -0,0 +1,80 @@
/*
* 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.indices.exists.indices;
import org.elasticsearch.action.support.IndicesOptions;
import org.elasticsearch.cluster.block.ClusterBlockException;
import org.elasticsearch.cluster.metadata.IndexMetaData;
import org.elasticsearch.test.ElasticsearchIntegrationTest;
import org.junit.Test;
import java.util.Arrays;
import static org.elasticsearch.cluster.metadata.IndexMetaData.*;
import static org.hamcrest.Matchers.equalTo;
public class IndicesExistsTests extends ElasticsearchIntegrationTest {
@Test
// Indices exists never throws IndexMissingException, the indices options control its behaviour (return true or false)
public void testIndicesExists() throws Exception {
assertThat(client().admin().indices().prepareExists("foo").get().isExists(), equalTo(false));
assertThat(client().admin().indices().prepareExists("foo").setIndicesOptions(IndicesOptions.lenientExpandOpen()).get().isExists(), equalTo(true));
assertThat(client().admin().indices().prepareExists("foo*").get().isExists(), equalTo(false));
assertThat(client().admin().indices().prepareExists("foo*").setIndicesOptions(IndicesOptions.fromOptions(false, true, true, false)).get().isExists(), equalTo(true));
assertThat(client().admin().indices().prepareExists("_all").get().isExists(), equalTo(false));
createIndex("foo", "foobar", "bar", "barbaz");
ensureYellow();
assertThat(client().admin().indices().prepareExists("foo*").get().isExists(), equalTo(true));
assertThat(client().admin().indices().prepareExists("foobar").get().isExists(), equalTo(true));
assertThat(client().admin().indices().prepareExists("bar*").get().isExists(), equalTo(true));
assertThat(client().admin().indices().prepareExists("bar").get().isExists(), equalTo(true));
assertThat(client().admin().indices().prepareExists("_all").get().isExists(), equalTo(true));
}
@Test
public void testIndicesExistsWithBlocks() {
createIndex("ro");
ensureYellow();
// Request is not blocked
for (String blockSetting : Arrays.asList(SETTING_BLOCKS_READ, SETTING_BLOCKS_WRITE, SETTING_READ_ONLY)) {
try {
enableIndexBlock("ro", blockSetting);
assertThat(client().admin().indices().prepareExists("ro").execute().actionGet().isExists(), equalTo(true));
} finally {
disableIndexBlock("ro", blockSetting);
}
}
// Request is blocked
try {
enableIndexBlock("ro", IndexMetaData.SETTING_BLOCKS_METADATA);
assertThat(client().admin().indices().prepareExists("ro").execute().actionGet().isExists(), equalTo(true));
fail("Exists should fail when " + IndexMetaData.SETTING_BLOCKS_METADATA + " is true");
} catch (ClusterBlockException e) {
// Ok, a ClusterBlockException is expected
} finally {
disableIndexBlock("ro", IndexMetaData.SETTING_BLOCKS_METADATA);
}
}
}

View File

@ -21,11 +21,18 @@ package org.elasticsearch.indices.exists.types;
import org.elasticsearch.action.admin.cluster.health.ClusterHealthResponse;
import org.elasticsearch.action.admin.indices.exists.types.TypesExistsResponse;
import org.elasticsearch.client.Client;
import org.elasticsearch.cluster.metadata.IndexMetaData;
import org.elasticsearch.indices.IndexMissingException;
import org.elasticsearch.test.ElasticsearchIntegrationTest;
import org.junit.Test;
import java.io.IOException;
import java.util.Arrays;
import static org.elasticsearch.cluster.metadata.IndexMetaData.*;
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertBlocked;
import static org.hamcrest.Matchers.equalTo;
public class TypesExistsTests extends ElasticsearchIntegrationTest {
@ -69,4 +76,27 @@ public class TypesExistsTests extends ElasticsearchIntegrationTest {
assertThat(response.isExists(), equalTo(false));
}
@Test
public void testTypesExistsWithBlocks() throws IOException {
assertAcked(prepareCreate("ro").addMapping("type1", jsonBuilder().startObject().startObject("type1").endObject().endObject()));
ensureGreen("ro");
// Request is not blocked
for (String block : Arrays.asList(SETTING_BLOCKS_READ, SETTING_BLOCKS_WRITE, SETTING_READ_ONLY)) {
try {
enableIndexBlock("ro", block);
assertThat(client().admin().indices().prepareTypesExists("ro").setTypes("type1").execute().actionGet().isExists(), equalTo(true));
} finally {
disableIndexBlock("ro", block);
}
}
// Request is blocked
try {
enableIndexBlock("ro", IndexMetaData.SETTING_BLOCKS_METADATA);
assertBlocked(client().admin().indices().prepareTypesExists("ro").setTypes("type1"));
} finally {
disableIndexBlock("ro", IndexMetaData.SETTING_BLOCKS_METADATA);
}
}
}

View File

@ -21,16 +21,21 @@ package org.elasticsearch.indices.mapping;
import com.google.common.collect.Maps;
import org.elasticsearch.action.admin.indices.mapping.get.GetFieldMappingsResponse;
import org.elasticsearch.common.xcontent.*;
import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.test.ElasticsearchIntegrationTest;
import org.hamcrest.Matchers;
import org.junit.Test;
import java.io.IOException;
import java.util.Arrays;
import java.util.Map;
import static org.elasticsearch.cluster.metadata.IndexMetaData.*;
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertBlocked;
import static org.hamcrest.Matchers.*;
public class SimpleGetFieldMappingsTests extends ElasticsearchIntegrationTest {
@ -174,4 +179,29 @@ public class SimpleGetFieldMappingsTests extends ElasticsearchIntegrationTest {
assertThat(responseStrings, not(equalTo(prettyJsonBuilder.string())));
}
@Test
public void testGetFieldMappingsWithBlocks() throws Exception {
assertAcked(prepareCreate("test")
.addMapping("typeA", getMappingForType("typeA"))
.addMapping("typeB", getMappingForType("typeB")));
ensureYellow();
for (String block : Arrays.asList(SETTING_BLOCKS_READ, SETTING_BLOCKS_WRITE, SETTING_READ_ONLY)) {
try {
enableIndexBlock("test", block);
GetFieldMappingsResponse response = client().admin().indices().prepareGetFieldMappings("test").setTypes("typeA").setFields("field1", "obj.subfield").get();
assertThat(response.fieldMappings("test", "typeA", "field1").fullName(), equalTo("field1"));
} finally {
disableIndexBlock("test", block);
}
}
try {
enableIndexBlock("test", SETTING_BLOCKS_METADATA);
assertBlocked(client().admin().indices().prepareGetMappings(), INDEX_METADATA_BLOCK);
} finally {
disableIndexBlock("test", SETTING_BLOCKS_METADATA);
}
}
}

View File

@ -28,8 +28,11 @@ import org.elasticsearch.test.ElasticsearchIntegrationTest.ClusterScope;
import org.junit.Test;
import java.io.IOException;
import java.util.Arrays;
import static org.elasticsearch.cluster.metadata.IndexMetaData.*;
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertBlocked;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.notNullValue;
@ -143,4 +146,30 @@ public class SimpleGetMappingsTests extends ElasticsearchIntegrationTest {
assertThat(response.mappings().get("indexb").get("Btype"), notNullValue());
}
@Test
public void testGetMappingsWithBlocks() throws IOException {
client().admin().indices().prepareCreate("test")
.addMapping("typeA", getMappingForType("typeA"))
.addMapping("typeB", getMappingForType("typeB"))
.execute().actionGet();
ensureGreen();
for (String block : Arrays.asList(SETTING_BLOCKS_READ, SETTING_BLOCKS_WRITE, SETTING_READ_ONLY)) {
try {
enableIndexBlock("test", block);
GetMappingsResponse response = client().admin().indices().prepareGetMappings().execute().actionGet();
assertThat(response.mappings().size(), equalTo(1));
assertThat(response.mappings().get("test").size(), equalTo(2));
} finally {
disableIndexBlock("test", block);
}
}
try {
enableIndexBlock("test", SETTING_BLOCKS_METADATA);
assertBlocked(client().admin().indices().prepareGetMappings(), INDEX_METADATA_BLOCK);
} finally {
disableIndexBlock("test", SETTING_BLOCKS_METADATA);
}
}
}

View File

@ -41,15 +41,16 @@ import org.hamcrest.Matchers;
import org.junit.Test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.atomic.AtomicBoolean;
import static org.elasticsearch.cluster.metadata.IndexMetaData.*;
import static org.elasticsearch.common.settings.ImmutableSettings.settingsBuilder;
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertThrows;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.*;
import static org.hamcrest.Matchers.*;
@ClusterScope(randomDynamicTemplates = false)
@ -440,4 +441,28 @@ public class UpdateMappingTests extends ElasticsearchIntegrationTest {
}
}
@Test
public void testPutMappingsWithBlocks() throws Exception {
createIndex("test");
ensureGreen();
for (String block : Arrays.asList(SETTING_BLOCKS_READ, SETTING_BLOCKS_WRITE)) {
try {
enableIndexBlock("test", block);
assertAcked(client().admin().indices().preparePutMapping("test").setType("doc").setSource("{\"properties\":{\"date\":{\"type\":\"integer\"}}}"));
} finally {
disableIndexBlock("test", block);
}
}
for (String block : Arrays.asList(SETTING_READ_ONLY, SETTING_BLOCKS_METADATA)) {
try {
enableIndexBlock("test", block);
assertBlocked(client().admin().indices().preparePutMapping("test").setType("doc").setSource("{\"properties\":{\"date\":{\"type\":\"integer\"}}}"));
} finally {
disableIndexBlock("test", block);
}
}
}
}

View File

@ -0,0 +1,65 @@
/*
* 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.indices.settings;
import org.elasticsearch.action.admin.indices.settings.get.GetSettingsResponse;
import org.elasticsearch.common.settings.ImmutableSettings;
import org.elasticsearch.test.ElasticsearchIntegrationTest;
import org.junit.Test;
import java.util.Arrays;
import static org.elasticsearch.cluster.metadata.IndexMetaData.*;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertBlocked;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
public class GetSettingsBlocksTests extends ElasticsearchIntegrationTest {
@Test
public void testGetSettingsWithBlocks() throws Exception {
assertAcked(prepareCreate("test")
.setSettings(ImmutableSettings.settingsBuilder()
.put("index.refresh_interval", -1)
.put("index.merge.policy.expunge_deletes_allowed", "30")
.put("index.mapper.dynamic", false)));
for (String block : Arrays.asList(SETTING_BLOCKS_READ, SETTING_BLOCKS_WRITE, SETTING_READ_ONLY)) {
try {
enableIndexBlock("test", block);
GetSettingsResponse response = client().admin().indices().prepareGetSettings("test").get();
assertThat(response.getIndexToSettings().size(), greaterThanOrEqualTo(1));
assertThat(response.getSetting("test", "index.refresh_interval"), equalTo("-1"));
assertThat(response.getSetting("test", "index.merge.policy.expunge_deletes_allowed"), equalTo("30"));
assertThat(response.getSetting("test", "index.mapper.dynamic"), equalTo("false"));
} finally {
disableIndexBlock("test", block);
}
}
try {
enableIndexBlock("test", SETTING_BLOCKS_METADATA);
assertBlocked(client().admin().indices().prepareGetSettings("test"));
} finally {
disableIndexBlock("test", SETTING_BLOCKS_METADATA);
}
}
}

View File

@ -32,6 +32,7 @@ import org.elasticsearch.action.admin.indices.settings.get.GetSettingsResponse;
import org.elasticsearch.cluster.metadata.IndexMetaData;
import org.elasticsearch.common.Priority;
import org.elasticsearch.common.settings.ImmutableSettings;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.index.engine.VersionConflictEngineException;
import org.elasticsearch.index.merge.policy.TieredMergePolicyProvider;
import org.elasticsearch.index.merge.scheduler.ConcurrentMergeSchedulerProvider;
@ -41,8 +42,10 @@ import org.elasticsearch.index.store.support.AbstractIndexStore;
import org.elasticsearch.test.ElasticsearchIntegrationTest;
import org.junit.Test;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertThrows;
import java.util.Arrays;
import static org.elasticsearch.cluster.metadata.IndexMetaData.*;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.*;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.nullValue;
@ -384,4 +387,31 @@ public class UpdateSettingsTests extends ElasticsearchIntegrationTest {
rootLogger.setLevel(savedLevel);
}
}
@Test
public void testUpdateSettingsWithBlocks() {
createIndex("test");
ensureGreen("test");
Settings.Builder builder = ImmutableSettings.builder().put("index.refresh_interval", -1);
for (String blockSetting : Arrays.asList(SETTING_BLOCKS_READ, SETTING_BLOCKS_WRITE)) {
try {
enableIndexBlock("test", blockSetting);
assertAcked(client().admin().indices().prepareUpdateSettings("test").setSettings(builder));
} finally {
disableIndexBlock("test", blockSetting);
}
}
// Closing an index is blocked
for (String blockSetting : Arrays.asList(SETTING_READ_ONLY, SETTING_BLOCKS_METADATA)) {
try {
enableIndexBlock("test", blockSetting);
assertBlocked(client().admin().indices().prepareUpdateSettings("test").setSettings(builder));
} finally {
disableIndexBlock("test", blockSetting);
}
}
}
}

View File

@ -30,21 +30,18 @@ import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.support.IndicesOptions;
import org.elasticsearch.client.Client;
import org.elasticsearch.cluster.metadata.IndexMetaData;
import org.elasticsearch.common.settings.ImmutableSettings;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.indices.IndexMissingException;
import org.elasticsearch.test.ElasticsearchIntegrationTest;
import org.elasticsearch.test.store.MockFSDirectoryService;
import org.junit.Test;
import java.io.IOException;
import java.util.Arrays;
import java.util.concurrent.ExecutionException;
import static org.elasticsearch.common.settings.ImmutableSettings.settingsBuilder;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertHitCount;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertNoFailures;
import static org.elasticsearch.cluster.metadata.IndexMetaData.*;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.*;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.notNullValue;
@ -338,5 +335,58 @@ public class OpenCloseIndexTests extends ElasticsearchIntegrationTest {
assertHitCount(searchResponse, docs);
}
@Test
public void testOpenCloseIndexWithBlocks() {
createIndex("test");
ensureGreen("test");
int docs = between(10, 100);
for (int i = 0; i < docs ; i++) {
client().prepareIndex("test", "type", "" + i).setSource("test", "init").execute().actionGet();
}
for (String blockSetting : Arrays.asList(SETTING_BLOCKS_READ, SETTING_BLOCKS_WRITE)) {
try {
enableIndexBlock("test", blockSetting);
// Closing an index is not blocked
CloseIndexResponse closeIndexResponse = client().admin().indices().prepareClose("test").execute().actionGet();
assertAcked(closeIndexResponse);
assertIndexIsClosed("test");
// Opening an index is not blocked
OpenIndexResponse openIndexResponse = client().admin().indices().prepareOpen("test").execute().actionGet();
assertAcked(openIndexResponse);
assertIndexIsOpened("test");
} finally {
disableIndexBlock("test", blockSetting);
}
}
// Closing an index is blocked
for (String blockSetting : Arrays.asList(SETTING_READ_ONLY, SETTING_BLOCKS_METADATA)) {
try {
enableIndexBlock("test", blockSetting);
assertBlocked(client().admin().indices().prepareClose("test"));
assertIndexIsOpened("test");
} finally {
disableIndexBlock("test", blockSetting);
}
}
CloseIndexResponse closeIndexResponse = client().admin().indices().prepareClose("test").execute().actionGet();
assertAcked(closeIndexResponse);
assertIndexIsClosed("test");
// Opening an index is blocked
for (String blockSetting : Arrays.asList(SETTING_READ_ONLY, SETTING_BLOCKS_METADATA)) {
try {
enableIndexBlock("test", blockSetting);
assertBlocked(client().admin().indices().prepareOpen("test"));
assertIndexIsClosed("test");
} finally {
disableIndexBlock("test", blockSetting);
}
}
}
}

View File

@ -0,0 +1,66 @@
/*
* 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.indices.template;
import org.elasticsearch.action.admin.indices.alias.Alias;
import org.elasticsearch.action.admin.indices.template.get.GetIndexTemplatesResponse;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.test.ElasticsearchIntegrationTest;
import org.elasticsearch.test.ElasticsearchIntegrationTest.ClusterScope;
import org.junit.Test;
import java.io.IOException;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertBlocked;
import static org.hamcrest.Matchers.hasSize;
@ClusterScope(scope = ElasticsearchIntegrationTest.Scope.TEST)
public class IndexTemplateBlocksTests extends ElasticsearchIntegrationTest {
@Test
public void testIndexTemplatesWithBlocks() throws IOException {
// creates a simple index template
client().admin().indices().preparePutTemplate("template_blocks")
.setTemplate("te*")
.setOrder(0)
.addMapping("type1", XContentFactory.jsonBuilder().startObject().startObject("type1").startObject("properties")
.startObject("field1").field("type", "string").field("store", "yes").endObject()
.startObject("field2").field("type", "string").field("store", "yes").field("index", "not_analyzed").endObject()
.endObject().endObject().endObject())
.execute().actionGet();
try {
setClusterReadOnly(true);
GetIndexTemplatesResponse response = client().admin().indices().prepareGetTemplates("template_blocks").execute().actionGet();
assertThat(response.getIndexTemplates(), hasSize(1));
assertBlocked(client().admin().indices().preparePutTemplate("template_blocks_2")
.setTemplate("block*")
.setOrder(0)
.addAlias(new Alias("alias_1")));
assertBlocked(client().admin().indices().prepareDeleteTemplate("template_blocks"));
} finally {
setClusterReadOnly(false);
}
}
}

View File

@ -0,0 +1,158 @@
/*
* 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.indices.warmer;
import com.carrotsearch.hppc.cursors.ObjectObjectCursor;
import com.google.common.collect.ImmutableList;
import org.elasticsearch.action.admin.indices.warmer.get.GetWarmersResponse;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.warmer.IndexWarmersMetaData;
import org.elasticsearch.test.ElasticsearchIntegrationTest;
import org.elasticsearch.test.ElasticsearchIntegrationTest.ClusterScope;
import org.junit.Test;
import java.util.Arrays;
import static org.elasticsearch.cluster.metadata.IndexMetaData.*;
import static org.elasticsearch.cluster.metadata.MetaData.CLUSTER_READ_ONLY_BLOCK;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertBlocked;
import static org.hamcrest.Matchers.equalTo;
@ClusterScope(scope = ElasticsearchIntegrationTest.Scope.TEST)
public class IndicesWarmerBlocksTests extends ElasticsearchIntegrationTest {
@Test
public void testPutWarmerWithBlocks() {
createIndex("test-blocks");
ensureGreen("test-blocks");
// Index reads are blocked, the warmer can't be registered
try {
enableIndexBlock("test-blocks", SETTING_BLOCKS_READ);
assertBlocked(client().admin().indices().preparePutWarmer("warmer_blocked")
.setSearchRequest(client().prepareSearch("test-*").setTypes("a1").setQuery(QueryBuilders.matchAllQuery())), INDEX_READ_BLOCK);
} finally {
disableIndexBlock("test-blocks", SETTING_BLOCKS_READ);
}
// Index writes are blocked, the warmer can be registered
try {
enableIndexBlock("test-blocks", SETTING_BLOCKS_WRITE);
assertAcked(client().admin().indices().preparePutWarmer("warmer_acked")
.setSearchRequest(client().prepareSearch("test-blocks").setTypes("a1").setQuery(QueryBuilders.matchAllQuery())));
} finally {
disableIndexBlock("test-blocks", SETTING_BLOCKS_WRITE);
}
// Index metadata changes are blocked, the warmer can't be registered
try {
enableIndexBlock("test-blocks", SETTING_BLOCKS_METADATA);
assertBlocked(client().admin().indices().preparePutWarmer("warmer_blocked")
.setSearchRequest(client().prepareSearch("test-*").setTypes("a1").setQuery(QueryBuilders.matchAllQuery())), INDEX_METADATA_BLOCK);
} finally {
disableIndexBlock("test-blocks", SETTING_BLOCKS_METADATA);
}
// Index metadata changes are blocked, the warmer can't be registered
try {
enableIndexBlock("test-blocks", SETTING_READ_ONLY);
assertBlocked(client().admin().indices().preparePutWarmer("warmer_blocked")
.setSearchRequest(client().prepareSearch("test-*").setTypes("a1").setQuery(QueryBuilders.matchAllQuery())), INDEX_READ_ONLY_BLOCK);
} finally {
disableIndexBlock("test-blocks", SETTING_READ_ONLY);
}
// Adding a new warmer is not possible when the cluster is read-only
try {
setClusterReadOnly(true);
assertBlocked(client().admin().indices().preparePutWarmer("warmer_blocked")
.setSearchRequest(client().prepareSearch("test-blocks").setTypes("a1").setQuery(QueryBuilders.matchAllQuery())), CLUSTER_READ_ONLY_BLOCK);
} finally {
setClusterReadOnly(false);
}
}
@Test
public void testGetWarmerWithBlocks() {
createIndex("test-blocks");
ensureGreen("test-blocks");
assertAcked(client().admin().indices().preparePutWarmer("warmer_block")
.setSearchRequest(client().prepareSearch("test-blocks").setTypes("a1").setQuery(QueryBuilders.matchAllQuery())));
// Request is not blocked
for (String blockSetting : Arrays.asList(SETTING_BLOCKS_READ, SETTING_BLOCKS_WRITE, SETTING_READ_ONLY)) {
try {
enableIndexBlock("test-blocks", blockSetting);
GetWarmersResponse response = client().admin().indices().prepareGetWarmers("test-blocks").get();
assertThat(response.warmers().size(), equalTo(1));
ObjectObjectCursor<String, ImmutableList<IndexWarmersMetaData.Entry>> entry = response.warmers().iterator().next();
assertThat(entry.key, equalTo("test-blocks"));
assertThat(entry.value.size(), equalTo(1));
assertThat(entry.value.iterator().next().name(), equalTo("warmer_block"));
} finally {
disableIndexBlock("test-blocks", blockSetting);
}
}
// Request is blocked
try {
enableIndexBlock("test-blocks", SETTING_BLOCKS_METADATA);
assertBlocked(client().admin().indices().prepareGetWarmers("test-blocks"), INDEX_METADATA_BLOCK);
} finally {
disableIndexBlock("test-blocks", SETTING_BLOCKS_METADATA);
}
}
@Test
public void testDeleteWarmerWithBlocks() {
createIndex("test-blocks");
ensureGreen("test-blocks");
// Request is not blocked
for (String blockSetting : Arrays.asList(SETTING_BLOCKS_READ, SETTING_BLOCKS_WRITE)) {
try {
assertAcked(client().admin().indices().preparePutWarmer("warmer_block")
.setSearchRequest(client().prepareSearch("test-blocks").setTypes("a1").setQuery(QueryBuilders.matchAllQuery())));
enableIndexBlock("test-blocks", blockSetting);
assertAcked(client().admin().indices().prepareDeleteWarmer().setIndices("test-blocks").setNames("warmer_block"));
} finally {
disableIndexBlock("test-blocks", blockSetting);
}
}
// Request is blocked
for (String blockSetting : Arrays.asList(SETTING_READ_ONLY, SETTING_BLOCKS_METADATA)) {
try {
assertAcked(client().admin().indices().preparePutWarmer("warmer_block")
.setSearchRequest(client().prepareSearch("test-blocks").setTypes("a1").setQuery(QueryBuilders.matchAllQuery())));
enableIndexBlock("test-blocks", blockSetting);
assertBlocked(client().admin().indices().prepareDeleteWarmer().setIndices("test-blocks").setNames("warmer_block"));
} finally {
disableIndexBlock("test-blocks", blockSetting);
}
}
}
}

View File

@ -1421,6 +1421,24 @@ public abstract class ElasticsearchIntegrationTest extends ElasticsearchTestCase
client().admin().indices().prepareUpdateSettings(index).setSettings(settings).get();
}
/** Disables an index block for the specified index */
public static void disableIndexBlock(String index, String block) {
Settings settings = ImmutableSettings.builder().put(block, false).build();
client().admin().indices().prepareUpdateSettings(index).setSettings(settings).get();
}
/** Enables an index block for the specified index */
public static void enableIndexBlock(String index, String block) {
Settings settings = ImmutableSettings.builder().put(block, true).build();
client().admin().indices().prepareUpdateSettings(index).setSettings(settings).get();
}
/** Sets or unsets the cluster read_only mode **/
public static void setClusterReadOnly(boolean value) {
Settings settings = settingsBuilder().put(MetaData.SETTING_READ_ONLY, value).build();
assertAcked(client().admin().cluster().prepareUpdateSettings().setTransientSettings(settings).get());
}
private static CountDownLatch newLatch(List<CountDownLatch> latches) {
CountDownLatch l = new CountDownLatch(1);
latches.add(l);

View File

@ -54,6 +54,8 @@ import org.elasticsearch.action.search.ShardSearchFailure;
import org.elasticsearch.action.support.broadcast.BroadcastOperationResponse;
import org.elasticsearch.action.support.master.AcknowledgedRequestBuilder;
import org.elasticsearch.action.support.master.AcknowledgedResponse;
import org.elasticsearch.cluster.block.ClusterBlock;
import org.elasticsearch.cluster.block.ClusterBlockException;
import org.elasticsearch.cluster.metadata.IndexTemplateMetaData;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.bytes.BytesReference;
@ -83,6 +85,7 @@ import java.util.concurrent.TimeUnit;
import static com.google.common.base.Predicates.isNull;
import static org.elasticsearch.test.ElasticsearchTestCase.*;
import static org.elasticsearch.test.VersionUtils.randomVersion;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;
@ -118,6 +121,42 @@ public class ElasticsearchAssertions {
assertVersionSerializable(response);
}
/**
* Executes the request and fails if the request has not been blocked.
*
* @param builder the request builder
*/
public static void assertBlocked(ActionRequestBuilder builder) {
assertBlocked(builder, null);
}
/**
* Executes the request and fails if the request has not been blocked by a specific {@link ClusterBlock}.
*
* @param builder the request builder
* @param expectedBlock the expected block
*/
public static void assertBlocked(ActionRequestBuilder builder, ClusterBlock expectedBlock) {
try {
builder.get();
fail("Request executed with success but a ClusterBlockException was expected");
} catch (ClusterBlockException e) {
assertThat(e.blocks().size(), greaterThan(0));
assertThat(e.status(), equalTo(RestStatus.FORBIDDEN));
if (expectedBlock != null) {
boolean found = false;
for (ClusterBlock clusterBlock : e.blocks()) {
if (clusterBlock.id() == expectedBlock.id()) {
found = true;
break;
}
}
assertThat("Request should have been blocked by [" + expectedBlock + "] instead of " + e.blocks(), found, equalTo(true));
}
}
}
public static String formatShardStatus(BroadcastOperationResponse response) {
String msg = " Total shards: " + response.getTotalShards() + " Successful shards: " + response.getSuccessfulShards() + " & "
+ response.getFailedShards() + " shard failures:";