Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import org.elasticsearch.action.support.SubscribableListener;
import org.elasticsearch.cluster.ProjectState;
import org.elasticsearch.cluster.block.ClusterBlockLevel;
import org.elasticsearch.cluster.metadata.IndexMetadata;
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
import org.elasticsearch.cluster.project.ProjectResolver;
import org.elasticsearch.cluster.service.ClusterService;
Expand Down Expand Up @@ -171,7 +172,7 @@ private void doExecuteForked(
final Map<String, OriginalIndices> remoteClusterIndices = transportService.getRemoteClusterService()
.groupIndices(request.indicesOptions(), request.indices());
final OriginalIndices localIndices = remoteClusterIndices.remove(RemoteClusterAware.LOCAL_CLUSTER_GROUP_KEY);
final String[] concreteIndices;
String[] concreteIndices;
if (localIndices == null) {
// in the case we have one or more remote indices but no local we don't expand to all local indices and just do remote indices
concreteIndices = Strings.EMPTY_ARRAY;
Expand All @@ -184,7 +185,7 @@ private void doExecuteForked(
return;
}

checkIndexBlocks(projectState, concreteIndices);
concreteIndices = checkBlocksAndFilterIndices(projectState, concreteIndices);
final FailureCollector indexFailures = new FailureCollector();
final Map<String, FieldCapabilitiesIndexResponse> indexResponses = new HashMap<>();
// This map is used to share the index response for indices which have the same index mapping hash to reduce the memory usage.
Expand Down Expand Up @@ -371,17 +372,22 @@ void executeRemoteRequest(
);
}

private static void checkIndexBlocks(ProjectState projectState, String[] concreteIndices) {
static String[] checkBlocksAndFilterIndices(ProjectState projectState, String[] concreteIndices) {
var blocks = projectState.blocks();
var projectId = projectState.projectId();
if (blocks.global(projectId).isEmpty() && blocks.indices(projectId).isEmpty()) {
// short circuit optimization because block check below is relatively expensive for many indices
return;
return concreteIndices;
}
blocks.globalBlockedRaiseException(projectId, ClusterBlockLevel.READ);
List<String> filteredIndices = new ArrayList<>(concreteIndices.length);
for (String index : concreteIndices) {
blocks.indexBlockedRaiseException(projectState.projectId(), ClusterBlockLevel.READ, index);
blocks.indexBlockedRaiseException(projectId, ClusterBlockLevel.READ, index);
if (blocks.hasIndexBlock(projectId, index, IndexMetadata.INDEX_REFRESH_BLOCK) == false) {
filteredIndices.add(index);
}
}
return filteredIndices.toArray(new String[0]);
}

private static void mergeIndexResponses(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,23 @@
import org.elasticsearch.TransportVersions;
import org.elasticsearch.action.support.ActionFilter;
import org.elasticsearch.action.support.ActionFilters;
import org.elasticsearch.cluster.ClusterName;
import org.elasticsearch.cluster.ClusterState;
import org.elasticsearch.cluster.ProjectState;
import org.elasticsearch.cluster.block.ClusterBlock;
import org.elasticsearch.cluster.block.ClusterBlockException;
import org.elasticsearch.cluster.block.ClusterBlockLevel;
import org.elasticsearch.cluster.block.ClusterBlocks;
import org.elasticsearch.cluster.metadata.IndexMetadata;
import org.elasticsearch.cluster.metadata.ProjectId;
import org.elasticsearch.cluster.metadata.ProjectMetadata;
import org.elasticsearch.cluster.node.VersionInformation;
import org.elasticsearch.cluster.service.ClusterService;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.settings.ClusterSettings;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.indices.IndicesService;
import org.elasticsearch.rest.RestStatus;
import org.elasticsearch.search.DummyQueryBuilder;
import org.elasticsearch.search.SearchService;
import org.elasticsearch.test.ESTestCase;
Expand All @@ -29,8 +40,10 @@
import org.elasticsearch.transport.TransportService;

import java.io.IOException;
import java.util.EnumSet;
import java.util.concurrent.TimeUnit;

import static org.elasticsearch.action.fieldcaps.TransportFieldCapabilitiesAction.checkBlocksAndFilterIndices;
import static org.hamcrest.Matchers.containsString;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
Expand Down Expand Up @@ -104,4 +117,63 @@ protected void doWriteTo(StreamOutput out) throws IOException {
assertTrue(ESTestCase.terminate(threadPool));
}
}

public void testCheckBlocksAndFilterIndices() {
final ProjectId projectId = randomProjectIdOrDefault();
String[] concreteIndices = { "index1", "index2", "index3" };

// No blocks
{
final ClusterState clusterState = ClusterState.builder(ClusterName.DEFAULT)
.putProjectMetadata(ProjectMetadata.builder(projectId).build())
.build();
final ProjectState projectState = clusterState.projectState(projectId);
String[] result = checkBlocksAndFilterIndices(projectState, concreteIndices);
assertArrayEquals(concreteIndices, result);
}

// Global READ block
{
final ClusterState clusterState = ClusterState.builder(ClusterName.DEFAULT)
.putProjectMetadata(ProjectMetadata.builder(projectId).build())
.blocks(
ClusterBlocks.builder()
.addGlobalBlock(
new ClusterBlock(
0,
"id",
false,
false,
false,
RestStatus.SERVICE_UNAVAILABLE,
EnumSet.of(ClusterBlockLevel.READ)
)
)
)
.build();
final ProjectState projectState = clusterState.projectState(projectId);
expectThrows(ClusterBlockException.class, () -> checkBlocksAndFilterIndices(projectState, concreteIndices));
}

// Index-level READ block
{
final ClusterState clusterState = ClusterState.builder(ClusterName.DEFAULT)
.putProjectMetadata(ProjectMetadata.builder(projectId).build())
.blocks(ClusterBlocks.builder().addIndexBlock(projectId, "index1", IndexMetadata.INDEX_READ_BLOCK))
.build();
final ProjectState projectState = clusterState.projectState(projectId);
expectThrows(ClusterBlockException.class, () -> checkBlocksAndFilterIndices(projectState, concreteIndices));
}

// Index-level INDEX_REFRESH_BLOCK
{
final ClusterState clusterState = ClusterState.builder(ClusterName.DEFAULT)
.putProjectMetadata(ProjectMetadata.builder(projectId).build())
.blocks(ClusterBlocks.builder().addIndexBlock(projectId, "index2", IndexMetadata.INDEX_REFRESH_BLOCK))
.build();
final ProjectState projectState = clusterState.projectState(projectId);
String[] result = checkBlocksAndFilterIndices(projectState, concreteIndices);
assertArrayEquals(new String[] { "index1", "index3" }, result);
}
}
}