Core: don't replace indices within the ActionRequest with the concrete ones, and make sure check blocks is executed on concrete indices

Concrete indices is now called multiple times when needed instead of changing what's inside the incoming request with the concrete indices. Ideally we want to keep the original aliases or indices or wildcard expressions in the request.

Also made sure that the check blocks is done against the concrete indices, which wasn't the case for delete index, delete mapping, open index, close index, types exists and indices exists.

Closes #6694
Closes #6777
This commit is contained in:
javanna 2014-07-01 15:19:04 +02:00 committed by Luca Cavanna
parent caf11ff2fb
commit 8dedbd01df
20 changed files with 196 additions and 147 deletions

View File

@ -24,8 +24,6 @@ setup:
---
"Filtering the cluster state by blocks should return the blocks":
# read only index
# TODO: can this cause issues leaving it read only when deleting it in teardown
- do:
indices.put_settings:
index: testidx
@ -42,6 +40,12 @@ setup:
- is_false: routing_nodes
- length: { blocks: 1 }
- do:
indices.put_settings:
index: testidx
body:
index.blocks.read_only: false
---
"Filtering the cluster state by nodes only should work":
- do:

View File

@ -62,9 +62,7 @@ public class TransportAliasesExistAction extends TransportMasterNodeReadOperatio
@Override
protected void masterOperation(GetAliasesRequest request, ClusterState state, ActionListener<AliasesExistResponse> listener) throws ElasticsearchException {
String[] concreteIndices = state.metaData().concreteIndices(request.indicesOptions(), request.indices());
request.indices(concreteIndices);
boolean result = state.metaData().hasAliases(request.aliases(), request.indices());
boolean result = state.metaData().hasAliases(request.aliases(), concreteIndices);
listener.onResponse(new AliasesExistResponse(result));
}

View File

@ -65,10 +65,8 @@ public class TransportGetAliasesAction extends TransportMasterNodeReadOperationA
@Override
protected void masterOperation(GetAliasesRequest request, ClusterState state, ActionListener<GetAliasesResponse> listener) throws ElasticsearchException {
String[] concreteIndices = state.metaData().concreteIndices(request.indicesOptions(), request.indices());
request.indices(concreteIndices);
@SuppressWarnings("unchecked") // ImmutableList to List results incompatible type
ImmutableOpenMap<String, List<AliasMetaData>> result = (ImmutableOpenMap) state.metaData().findAliases(request.aliases(), request.indices());
ImmutableOpenMap<String, List<AliasMetaData>> result = (ImmutableOpenMap) state.metaData().findAliases(request.aliases(), concreteIndices);
listener.onResponse(new GetAliasesResponse(result));
}

View File

@ -80,15 +80,15 @@ public class TransportCloseIndexAction extends TransportMasterNodeOperationActio
@Override
protected ClusterBlockException checkBlock(CloseIndexRequest request, ClusterState state) {
return state.blocks().indicesBlockedException(ClusterBlockLevel.METADATA, request.indices());
return state.blocks().indicesBlockedException(ClusterBlockLevel.METADATA, state.metaData().concreteIndices(request.indicesOptions(), request.indices()));
}
@Override
protected void masterOperation(final CloseIndexRequest request, final ClusterState state, final ActionListener<CloseIndexResponse> listener) throws ElasticsearchException {
request.indices(state.metaData().concreteIndices(request.indicesOptions(), request.indices()));
final String[] concreteIndices = state.metaData().concreteIndices(request.indicesOptions(), request.indices());
CloseIndexClusterStateUpdateRequest updateRequest = new CloseIndexClusterStateUpdateRequest()
.ackTimeout(request.timeout()).masterNodeTimeout(request.masterNodeTimeout())
.indices(request.indices());
.indices(concreteIndices);
indexStateService.closeIndex(updateRequest, new ActionListener<ClusterStateUpdateResponse>() {
@ -99,7 +99,7 @@ public class TransportCloseIndexAction extends TransportMasterNodeOperationActio
@Override
public void onFailure(Throwable t) {
logger.debug("failed to close indices [{}]", t, request.indices());
logger.debug("failed to close indices [{}]", t, concreteIndices);
listener.onFailure(t);
}
});

View File

@ -80,19 +80,19 @@ public class TransportDeleteIndexAction extends TransportMasterNodeOperationActi
@Override
protected ClusterBlockException checkBlock(DeleteIndexRequest request, ClusterState state) {
return state.blocks().indicesBlockedException(ClusterBlockLevel.METADATA, request.indices());
return state.blocks().indicesBlockedException(ClusterBlockLevel.METADATA, state.metaData().concreteIndices(request.indicesOptions(), request.indices()));
}
@Override
protected void masterOperation(final DeleteIndexRequest request, final ClusterState state, final ActionListener<DeleteIndexResponse> listener) throws ElasticsearchException {
request.indices(state.metaData().concreteIndices(request.indicesOptions(), request.indices()));
if (request.indices().length == 0) {
String[] concreteIndices = state.metaData().concreteIndices(request.indicesOptions(), request.indices());
if (concreteIndices.length == 0) {
listener.onResponse(new DeleteIndexResponse(true));
return;
}
// TODO: this API should be improved, currently, if one delete index failed, we send a failure, we should send a response array that includes all the indices that were deleted
final CountDown count = new CountDown(request.indices().length);
for (final String index : request.indices()) {
final CountDown count = new CountDown(concreteIndices.length);
for (final String index : concreteIndices) {
deleteIndexService.deleteIndex(new MetaDataDeleteIndexService.Request(index).timeout(request.timeout()).masterTimeout(request.masterNodeTimeout()), new MetaDataDeleteIndexService.Listener() {
private volatile Throwable lastFailure;

View File

@ -21,6 +21,7 @@ package org.elasticsearch.action.admin.indices.exists.indices;
import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.action.ActionListener;
import org.elasticsearch.action.support.IndicesOptions;
import org.elasticsearch.action.support.master.TransportMasterNodeReadOperationAction;
import org.elasticsearch.cluster.ClusterService;
import org.elasticsearch.cluster.ClusterState;
@ -64,16 +65,11 @@ public class TransportIndicesExistsAction extends TransportMasterNodeReadOperati
return new IndicesExistsResponse();
}
@Override
protected void doExecute(IndicesExistsRequest request, ActionListener<IndicesExistsResponse> listener) {
// don't call this since it will throw IndexMissingException
//request.indices(clusterService.state().metaData().concreteIndices(request.indices()));
super.doExecute(request, listener);
}
@Override
protected ClusterBlockException checkBlock(IndicesExistsRequest request, ClusterState state) {
return state.blocks().indicesBlockedException(ClusterBlockLevel.METADATA, request.indices());
//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()));
}
@Override

View File

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

View File

@ -110,13 +110,13 @@ public class TransportDeleteMappingAction extends TransportMasterNodeOperationAc
@Override
protected ClusterBlockException checkBlock(DeleteMappingRequest request, ClusterState state) {
return state.blocks().indicesBlockedException(ClusterBlockLevel.METADATA, request.indices());
return state.blocks().indicesBlockedException(ClusterBlockLevel.METADATA, state.metaData().concreteIndices(request.indicesOptions(), request.indices()));
}
@Override
protected void masterOperation(final DeleteMappingRequest request, final ClusterState state, final ActionListener<DeleteMappingResponse> listener) throws ElasticsearchException {
request.indices(state.metaData().concreteIndices(request.indicesOptions(), request.indices()));
flushAction.execute(Requests.flushRequest(request.indices()), new ActionListener<FlushResponse>() {
final String[] concreteIndices = state.metaData().concreteIndices(request.indicesOptions(), request.indices());
flushAction.execute(Requests.flushRequest(concreteIndices), new ActionListener<FlushResponse>() {
@Override
public void onResponse(FlushResponse flushResponse) {
if (logger.isTraceEnabled()) {
@ -125,7 +125,7 @@ public class TransportDeleteMappingAction extends TransportMasterNodeOperationAc
// get all types that need to be deleted.
ImmutableOpenMap<String, ImmutableOpenMap<String, MappingMetaData>> result = clusterService.state().metaData().findMappings(
request.indices(), request.types()
concreteIndices, request.types()
);
// create OrFilter with type filters within to account for different types
BoolFilterBuilder filterBuilder = new BoolFilterBuilder();
@ -142,7 +142,7 @@ public class TransportDeleteMappingAction extends TransportMasterNodeOperationAc
request.types(types.toArray(new String[types.size()]));
QuerySourceBuilder querySourceBuilder = new QuerySourceBuilder()
.setQuery(QueryBuilders.filteredQuery(QueryBuilders.matchAllQuery(), filterBuilder));
deleteByQueryAction.execute(Requests.deleteByQueryRequest(request.indices()).source(querySourceBuilder), new ActionListener<DeleteByQueryResponse>() {
deleteByQueryAction.execute(Requests.deleteByQueryRequest(concreteIndices).source(querySourceBuilder), new ActionListener<DeleteByQueryResponse>() {
@Override
public void onResponse(DeleteByQueryResponse deleteByQueryResponse) {
if (logger.isTraceEnabled()) {
@ -155,7 +155,7 @@ public class TransportDeleteMappingAction extends TransportMasterNodeOperationAc
}
}
}
refreshAction.execute(Requests.refreshRequest(request.indices()), new ActionListener<RefreshResponse>() {
refreshAction.execute(Requests.refreshRequest(concreteIndices), new ActionListener<RefreshResponse>() {
@Override
public void onResponse(RefreshResponse refreshResponse) {
if (logger.isTraceEnabled()) {
@ -174,7 +174,7 @@ public class TransportDeleteMappingAction extends TransportMasterNodeOperationAc
protected void removeMapping() {
DeleteMappingClusterStateUpdateRequest clusterStateUpdateRequest = new DeleteMappingClusterStateUpdateRequest()
.indices(request.indices()).types(request.types())
.indices(concreteIndices).types(request.types())
.ackTimeout(request.timeout())
.masterNodeTimeout(request.masterNodeTimeout());

View File

@ -60,7 +60,7 @@ public class TransportGetFieldMappingsAction extends TransportAction<GetFieldMap
final AtomicInteger completionCounter = new AtomicInteger(concreteIndices.length);
final AtomicReferenceArray<Object> indexResponses = new AtomicReferenceArray<>(concreteIndices.length);
if (concreteIndices == null || concreteIndices.length == 0) {
if (concreteIndices.length == 0) {
listener.onResponse(new GetFieldMappingsResponse());
} else {
boolean probablySingleFieldRequest = concreteIndices.length == 1 && request.types().length == 1 && request.fields().length == 1;

View File

@ -56,10 +56,10 @@ public class TransportGetMappingsAction extends TransportClusterInfoAction<GetMa
}
@Override
protected void doMasterOperation(final GetMappingsRequest request, final ClusterState state, final ActionListener<GetMappingsResponse> listener) throws ElasticsearchException {
protected void doMasterOperation(final GetMappingsRequest request, String[] concreteIndices, final ClusterState state, final ActionListener<GetMappingsResponse> listener) throws ElasticsearchException {
logger.trace("serving getMapping request based on version {}", state.version());
ImmutableOpenMap<String, ImmutableOpenMap<String, MappingMetaData>> result = state.metaData().findMappings(
request.indices(), request.types()
concreteIndices, request.types()
);
listener.onResponse(new GetMappingsResponse(result));
}

View File

@ -68,22 +68,17 @@ public class TransportPutMappingAction extends TransportMasterNodeOperationActio
return new PutMappingResponse();
}
@Override
protected void doExecute(PutMappingRequest request, ActionListener<PutMappingResponse> listener) {
request.indices(clusterService.state().metaData().concreteIndices(request.indicesOptions(), request.indices()));
super.doExecute(request, listener);
}
@Override
protected ClusterBlockException checkBlock(PutMappingRequest request, ClusterState state) {
return state.blocks().indicesBlockedException(ClusterBlockLevel.METADATA, request.indices());
return state.blocks().indicesBlockedException(ClusterBlockLevel.METADATA, clusterService.state().metaData().concreteIndices(request.indicesOptions(), request.indices()));
}
@Override
protected void masterOperation(final PutMappingRequest request, final ClusterState state, final ActionListener<PutMappingResponse> listener) throws ElasticsearchException {
final String[] concreteIndices = clusterService.state().metaData().concreteIndices(request.indicesOptions(), request.indices());
PutMappingClusterStateUpdateRequest updateRequest = new PutMappingClusterStateUpdateRequest()
.ackTimeout(request.timeout()).masterNodeTimeout(request.masterNodeTimeout())
.indices(request.indices()).type(request.type())
.indices(concreteIndices).type(request.type())
.source(request.source()).ignoreConflicts(request.ignoreConflicts());
metaDataMappingService.putMapping(updateRequest, new ActionListener<ClusterStateUpdateResponse>() {
@ -95,7 +90,7 @@ public class TransportPutMappingAction extends TransportMasterNodeOperationActio
@Override
public void onFailure(Throwable t) {
logger.debug("failed to put mappings on indices [{}], type [{}]", t, request.indices(), request.type());
logger.debug("failed to put mappings on indices [{}], type [{}]", t, concreteIndices, request.type());
listener.onFailure(t);
}
});

View File

@ -80,15 +80,15 @@ public class TransportOpenIndexAction extends TransportMasterNodeOperationAction
@Override
protected ClusterBlockException checkBlock(OpenIndexRequest request, ClusterState state) {
return state.blocks().indicesBlockedException(ClusterBlockLevel.METADATA, request.indices());
return state.blocks().indicesBlockedException(ClusterBlockLevel.METADATA, state.metaData().concreteIndices(request.indicesOptions(), request.indices()));
}
@Override
protected void masterOperation(final OpenIndexRequest request, final ClusterState state, final ActionListener<OpenIndexResponse> listener) throws ElasticsearchException {
request.indices(state.metaData().concreteIndices(request.indicesOptions(), request.indices()));
final String[] concreteIndices = state.metaData().concreteIndices(request.indicesOptions(), request.indices());
OpenIndexClusterStateUpdateRequest updateRequest = new OpenIndexClusterStateUpdateRequest()
.ackTimeout(request.timeout()).masterNodeTimeout(request.masterNodeTimeout())
.indices(request.indices());
.indices(concreteIndices);
indexStateService.openIndex(updateRequest, new ActionListener<ClusterStateUpdateResponse>() {
@ -99,7 +99,7 @@ public class TransportOpenIndexAction extends TransportMasterNodeOperationAction
@Override
public void onFailure(Throwable t) {
logger.debug("failed to open indices [{}]", t, request.indices());
logger.debug("failed to open indices [{}]", t, concreteIndices);
listener.onFailure(t);
}
});

View File

@ -73,9 +73,9 @@ public class TransportGetSettingsAction extends TransportMasterNodeReadOperation
@Override
protected void masterOperation(GetSettingsRequest request, ClusterState state, ActionListener<GetSettingsResponse> listener) throws ElasticsearchException {
request.indices(state.metaData().concreteIndices(request.indicesOptions(), request.indices()));
String[] concreteIndices = state.metaData().concreteIndices(request.indicesOptions(), request.indices());
ImmutableOpenMap.Builder<String, Settings> indexToSettingsBuilder = ImmutableOpenMap.builder();
for (String concreteIndex : request.indices()) {
for (String concreteIndex : concreteIndices) {
IndexMetaData indexMetaData = state.getMetaData().index(concreteIndex);
if (indexMetaData == null) {
continue;

View File

@ -66,16 +66,11 @@ public class TransportUpdateSettingsAction extends TransportMasterNodeOperationA
return new UpdateSettingsResponse();
}
@Override
protected void doExecute(UpdateSettingsRequest request, ActionListener<UpdateSettingsResponse> listener) {
request.indices(clusterService.state().metaData().concreteIndices(request.indicesOptions(), request.indices()));
super.doExecute(request, listener);
}
@Override
protected void masterOperation(final UpdateSettingsRequest request, final ClusterState state, final ActionListener<UpdateSettingsResponse> listener) throws ElasticsearchException {
final String[] concreteIndices = clusterService.state().metaData().concreteIndices(request.indicesOptions(), request.indices());
UpdateSettingsClusterStateUpdateRequest clusterStateUpdateRequest = new UpdateSettingsClusterStateUpdateRequest()
.indices(request.indices())
.indices(concreteIndices)
.settings(request.settings())
.ackTimeout(request.timeout())
.masterNodeTimeout(request.masterNodeTimeout());
@ -88,7 +83,7 @@ public class TransportUpdateSettingsAction extends TransportMasterNodeOperationA
@Override
public void onFailure(Throwable t) {
logger.debug("failed to update settings on indices [{}]", t, request.indices());
logger.debug("failed to update settings on indices [{}]", t, concreteIndices);
listener.onFailure(t);
}
});

View File

@ -73,20 +73,14 @@ public class TransportDeleteWarmerAction extends TransportMasterNodeOperationAct
return new DeleteWarmerResponse();
}
@Override
protected void doExecute(DeleteWarmerRequest request, ActionListener<DeleteWarmerResponse> listener) {
// update to concrete indices
request.indices(clusterService.state().metaData().concreteIndices(request.indicesOptions(), request.indices()));
super.doExecute(request, listener);
}
@Override
protected ClusterBlockException checkBlock(DeleteWarmerRequest request, ClusterState state) {
return state.blocks().indicesBlockedException(ClusterBlockLevel.METADATA, request.indices());
return state.blocks().indicesBlockedException(ClusterBlockLevel.METADATA, clusterService.state().metaData().concreteIndices(request.indicesOptions(), request.indices()));
}
@Override
protected void masterOperation(final DeleteWarmerRequest request, final ClusterState state, final ActionListener<DeleteWarmerResponse> listener) throws ElasticsearchException {
final String[] concreteIndices = clusterService.state().metaData().concreteIndices(request.indicesOptions(), request.indices());
clusterService.submitStateUpdateTask("delete_warmer [" + Arrays.toString(request.names()) + "]", new AckedClusterStateUpdateTask<DeleteWarmerResponse>(request, listener) {
@Override
@ -96,7 +90,7 @@ public class TransportDeleteWarmerAction extends TransportMasterNodeOperationAct
@Override
public void onFailure(String source, Throwable t) {
logger.debug("failed to delete warmer [{}] on indices [{}]", t, Arrays.toString(request.names()), request.indices());
logger.debug("failed to delete warmer [{}] on indices [{}]", t, Arrays.toString(request.names()), concreteIndices);
super.onFailure(source, t);
}
@ -105,7 +99,7 @@ public class TransportDeleteWarmerAction extends TransportMasterNodeOperationAct
MetaData.Builder mdBuilder = MetaData.builder(currentState.metaData());
boolean globalFoundAtLeastOne = false;
for (String index : request.indices()) {
for (String index : concreteIndices) {
IndexMetaData indexMetaData = currentState.metaData().index(index);
if (indexMetaData == null) {
throw new IndexMissingException(new Index(index));
@ -141,7 +135,7 @@ public class TransportDeleteWarmerAction extends TransportMasterNodeOperationAct
}
if (logger.isInfoEnabled()) {
for (String index : request.indices()) {
for (String index : concreteIndices) {
IndexMetaData indexMetaData = currentState.metaData().index(index);
if (indexMetaData == null) {
throw new IndexMissingException(new Index(index));

View File

@ -57,9 +57,9 @@ public class TransportGetWarmersAction extends TransportClusterInfoAction<GetWar
}
@Override
protected void doMasterOperation(final GetWarmersRequest request, final ClusterState state, final ActionListener<GetWarmersResponse> listener) throws ElasticsearchException {
protected void doMasterOperation(final GetWarmersRequest request, String[] concreteIndices, final ClusterState state, final ActionListener<GetWarmersResponse> listener) throws ElasticsearchException {
ImmutableOpenMap<String, ImmutableList<IndexWarmersMetaData.Entry>> result = state.metaData().findWarmers(
request.indices(), request.types(), request.warmers()
concreteIndices, request.types(), request.warmers()
);
listener.onResponse(new GetWarmersResponse(result));
}

View File

@ -45,9 +45,8 @@ public abstract class TransportClusterInfoAction<Request extends ClusterInfoRequ
@Override
protected final void masterOperation(final Request request, final ClusterState state, final ActionListener<Response> listener) throws ElasticsearchException {
String[] concreteIndices = state.metaData().concreteIndices(request.indicesOptions(), request.indices());
request.indices(concreteIndices);
doMasterOperation(request, state, listener);
doMasterOperation(request, concreteIndices, state, listener);
}
protected abstract void doMasterOperation(Request request, ClusterState state, final ActionListener<Response> listener) throws ElasticsearchException;
protected abstract void doMasterOperation(Request request, String[] concreteIndices, ClusterState state, final ActionListener<Response> listener) throws ElasticsearchException;
}

View File

@ -86,7 +86,7 @@ public abstract class TransportIndicesReplicationOperationAction<Request extends
final long startTimeInMillis = System.currentTimeMillis();
Map<String, Set<String>> routingMap = resolveRouting(clusterState, request);
if (concreteIndices == null || concreteIndices.length == 0) {
if (concreteIndices.length == 0) {
listener.onResponse(newResponseInstance(request, indexResponses));
} else {
for (final String index : concreteIndices) {

View File

@ -192,70 +192,75 @@ public class BulkProcessorTests extends ElasticsearchIntegrationTest {
@Test
public void testBulkProcessorConcurrentRequestsReadOnlyIndex() throws Exception {
createIndex("test-ro");
assertAcked(client().admin().indices().prepareUpdateSettings("test-ro")
.setSettings(ImmutableSettings.builder().put("index.blocks.read_only", true)));
ensureGreen();
try {
assertAcked(client().admin().indices().prepareUpdateSettings("test-ro")
.setSettings(ImmutableSettings.builder().put("index.blocks.read_only", true)));
ensureGreen();
int bulkActions = randomIntBetween(10, 100);
int numDocs = randomIntBetween(bulkActions, bulkActions + 100);
int concurrentRequests = randomIntBetween(0, 10);
int bulkActions = randomIntBetween(10, 100);
int numDocs = randomIntBetween(bulkActions, bulkActions + 100);
int concurrentRequests = randomIntBetween(0, 10);
int expectedBulkActions = numDocs / bulkActions;
int expectedBulkActions = numDocs / bulkActions;
final CountDownLatch latch = new CountDownLatch(expectedBulkActions);
int totalExpectedBulkActions = numDocs % bulkActions == 0 ? expectedBulkActions : expectedBulkActions + 1;
final CountDownLatch closeLatch = new CountDownLatch(totalExpectedBulkActions);
final CountDownLatch latch = new CountDownLatch(expectedBulkActions);
int totalExpectedBulkActions = numDocs % bulkActions == 0 ? expectedBulkActions : expectedBulkActions + 1;
final CountDownLatch closeLatch = new CountDownLatch(totalExpectedBulkActions);
int testDocs = 0;
int testReadOnlyDocs = 0;
MultiGetRequestBuilder multiGetRequestBuilder = client().prepareMultiGet();
BulkProcessorTestListener listener = new BulkProcessorTestListener(latch, closeLatch);
int testDocs = 0;
int testReadOnlyDocs = 0;
MultiGetRequestBuilder multiGetRequestBuilder = client().prepareMultiGet();
BulkProcessorTestListener listener = new BulkProcessorTestListener(latch, closeLatch);
try (BulkProcessor processor = BulkProcessor.builder(client(), listener)
.setConcurrentRequests(concurrentRequests).setBulkActions(bulkActions)
//set interval and size to high values
.setFlushInterval(TimeValue.timeValueHours(24)).setBulkSize(new ByteSizeValue(1, ByteSizeUnit.GB)).build()) {
try (BulkProcessor processor = BulkProcessor.builder(client(), listener)
.setConcurrentRequests(concurrentRequests).setBulkActions(bulkActions)
//set interval and size to high values
.setFlushInterval(TimeValue.timeValueHours(24)).setBulkSize(new ByteSizeValue(1, ByteSizeUnit.GB)).build()) {
for (int i = 1; i <= numDocs; i++) {
if (randomBoolean()) {
testDocs++;
processor.add(new IndexRequest("test", "test", Integer.toString(testDocs)).source("field", "value"));
multiGetRequestBuilder.add("test", "test", Integer.toString(testDocs));
} else {
testReadOnlyDocs++;
processor.add(new IndexRequest("test-ro", "test", Integer.toString(testReadOnlyDocs)).source("field", "value"));
for (int i = 1; i <= numDocs; i++) {
if (randomBoolean()) {
testDocs++;
processor.add(new IndexRequest("test", "test", Integer.toString(testDocs)).source("field", "value"));
multiGetRequestBuilder.add("test", "test", Integer.toString(testDocs));
} else {
testReadOnlyDocs++;
processor.add(new IndexRequest("test-ro", "test", Integer.toString(testReadOnlyDocs)).source("field", "value"));
}
}
}
}
closeLatch.await();
closeLatch.await();
assertThat(listener.beforeCounts.get(), equalTo(totalExpectedBulkActions));
assertThat(listener.afterCounts.get(), equalTo(totalExpectedBulkActions));
assertThat(listener.bulkFailures.size(), equalTo(0));
assertThat(listener.bulkItems.size(), equalTo(testDocs + testReadOnlyDocs));
assertThat(listener.beforeCounts.get(), equalTo(totalExpectedBulkActions));
assertThat(listener.afterCounts.get(), equalTo(totalExpectedBulkActions));
assertThat(listener.bulkFailures.size(), equalTo(0));
assertThat(listener.bulkItems.size(), equalTo(testDocs + testReadOnlyDocs));
Set<String> ids = new HashSet<>();
Set<String> readOnlyIds = new HashSet<>();
for (BulkItemResponse bulkItemResponse : listener.bulkItems) {
assertThat(bulkItemResponse.getIndex(), either(equalTo("test")).or(equalTo("test-ro")));
assertThat(bulkItemResponse.getType(), equalTo("test"));
if (bulkItemResponse.getIndex().equals("test")) {
assertThat(bulkItemResponse.isFailed(), equalTo(false));
//with concurrent requests > 1 we can't rely on the order of the bulk requests
assertThat(Integer.valueOf(bulkItemResponse.getId()), both(greaterThan(0)).and(lessThanOrEqualTo(testDocs)));
//we do want to check that we don't get duplicate ids back
assertThat(ids.add(bulkItemResponse.getId()), equalTo(true));
} else {
assertThat(bulkItemResponse.isFailed(), equalTo(true));
//with concurrent requests > 1 we can't rely on the order of the bulk requests
assertThat(Integer.valueOf(bulkItemResponse.getId()), both(greaterThan(0)).and(lessThanOrEqualTo(testReadOnlyDocs)));
//we do want to check that we don't get duplicate ids back
assertThat(readOnlyIds.add(bulkItemResponse.getId()), equalTo(true));
Set<String> ids = new HashSet<>();
Set<String> readOnlyIds = new HashSet<>();
for (BulkItemResponse bulkItemResponse : listener.bulkItems) {
assertThat(bulkItemResponse.getIndex(), either(equalTo("test")).or(equalTo("test-ro")));
assertThat(bulkItemResponse.getType(), equalTo("test"));
if (bulkItemResponse.getIndex().equals("test")) {
assertThat(bulkItemResponse.isFailed(), equalTo(false));
//with concurrent requests > 1 we can't rely on the order of the bulk requests
assertThat(Integer.valueOf(bulkItemResponse.getId()), both(greaterThan(0)).and(lessThanOrEqualTo(testDocs)));
//we do want to check that we don't get duplicate ids back
assertThat(ids.add(bulkItemResponse.getId()), equalTo(true));
} else {
assertThat(bulkItemResponse.isFailed(), equalTo(true));
//with concurrent requests > 1 we can't rely on the order of the bulk requests
assertThat(Integer.valueOf(bulkItemResponse.getId()), both(greaterThan(0)).and(lessThanOrEqualTo(testReadOnlyDocs)));
//we do want to check that we don't get duplicate ids back
assertThat(readOnlyIds.add(bulkItemResponse.getId()), equalTo(true));
}
}
}
assertMultiGetResponse(multiGetRequestBuilder.get(), testDocs);
assertMultiGetResponse(multiGetRequestBuilder.get(), testDocs);
} finally {
assertAcked(client().admin().indices().prepareUpdateSettings("test-ro")
.setSettings(ImmutableSettings.builder().put("index.blocks.read_only", false)));
}
}
private static MultiGetRequestBuilder indexDocs(Client client, BulkProcessor processor, int numDocs) {

View File

@ -20,40 +20,105 @@ 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.settings.put.UpdateSettingsResponse;
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.elasticsearch.test.ElasticsearchIntegrationTest.ClusterScope;
import org.junit.Test;
import static org.elasticsearch.test.ElasticsearchIntegrationTest.*;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.is;
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= ElasticsearchIntegrationTest.Scope.TEST)
@ClusterScope(scope= Scope.TEST)
public class BlockClusterStatsTests extends ElasticsearchIntegrationTest {
@Test
public void testBlocks() throws Exception {
createIndex("foo");
ClusterUpdateSettingsResponse updateSettingsResponse = client().admin().cluster().prepareUpdateSettings().setTransientSettings(
ImmutableSettings.settingsBuilder().put("cluster.blocks.read_only", true).build()).get();
assertThat(updateSettingsResponse.isAcknowledged(), is(true));
UpdateSettingsResponse indexSettingsResponse = client().admin().indices().prepareUpdateSettings("foo").setSettings(
ImmutableSettings.settingsBuilder().put("index.blocks.read_only", true)).get();
assertThat(indexSettingsResponse.isAcknowledged(), is(true));
assertAcked(prepareCreate("foo").addAlias(new Alias("foo-alias")));
try {
ClusterUpdateSettingsResponse updateSettingsResponse = client().admin().cluster().prepareUpdateSettings().setTransientSettings(
ImmutableSettings.settingsBuilder().put("cluster.blocks.read_only", true).build()).get();
assertThat(updateSettingsResponse.isAcknowledged(), is(true));
assertAcked(client().admin().indices().prepareUpdateSettings("foo").setSettings(
ImmutableSettings.settingsBuilder().put("index.blocks.read_only", true)));
ClusterStateResponse clusterStateResponseUnfiltered = client().admin().cluster().prepareState().clear().setBlocks(true).get();
assertThat(clusterStateResponseUnfiltered.getState().blocks().global(), hasSize(1));
assertThat(clusterStateResponseUnfiltered.getState().blocks().indices().size(), is(1));
ClusterStateResponse clusterStateResponseUnfiltered = client().admin().cluster().prepareState().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));
ClusterStateResponse clusterStateResponse = client().admin().cluster().prepareState().clear().get();
assertThat(clusterStateResponse.getState().blocks().global(), hasSize(0));
assertThat(clusterStateResponse.getState().blocks().indices().size(), is(0));
assertAcked(client().admin().cluster().prepareUpdateSettings().setTransientSettings(
ImmutableSettings.settingsBuilder().put("cluster.blocks.read_only", false).build()).get());
try {
client().admin().indices().prepareClose("foo-alias").get();
fail("close index should have failed");
} catch(ClusterBlockException e) {
assertClusterAndIndexBlocks(e);
}
try {
client().admin().indices().prepareDeleteMapping("foo-alias").setType("test").get();
fail("delete mapping 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)")));
}
}
}