Skip to content
Merged
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 @@ -755,6 +755,70 @@ public void testNegativeRemoteIndexNameThrows() {
assertNotNull(ee.getCause());
}

public void testClusterDetailsWhenLocalClusterHasNoMatchingIndex() throws Exception {
Map<String, Object> testClusterInfo = setupTwoClusters();
String remoteIndex = (String) testClusterInfo.get("remote.index");
int remoteNumShards = (Integer) testClusterInfo.get("remote.num_shards");

SearchRequest searchRequest = new SearchRequest("nomatch*", REMOTE_CLUSTER + ":" + remoteIndex);
if (randomBoolean()) {
searchRequest = searchRequest.scroll(TimeValue.timeValueMinutes(1));
}

searchRequest.allowPartialSearchResults(false);
if (randomBoolean()) {
searchRequest.setBatchedReduceSize(randomIntBetween(3, 20));
}

boolean minimizeRoundtrips = false;
searchRequest.setCcsMinimizeRoundtrips(minimizeRoundtrips);

boolean dfs = randomBoolean();
if (dfs) {
searchRequest.searchType(SearchType.DFS_QUERY_THEN_FETCH);
}

if (randomBoolean()) {
searchRequest.setPreFilterShardSize(1);
}

searchRequest.source(new SearchSourceBuilder().query(new MatchAllQueryBuilder()).size(10));
assertResponse(client(LOCAL_CLUSTER).search(searchRequest), response -> {
assertNotNull(response);

Clusters clusters = response.getClusters();
assertFalse("search cluster results should BE successful", clusters.hasPartialResults());
assertThat(clusters.getTotal(), equalTo(2));
assertThat(clusters.getClusterStateCount(Cluster.Status.SUCCESSFUL), equalTo(2));
assertThat(clusters.getClusterStateCount(Cluster.Status.SKIPPED), equalTo(0));
assertThat(clusters.getClusterStateCount(Cluster.Status.RUNNING), equalTo(0));
assertThat(clusters.getClusterStateCount(Cluster.Status.PARTIAL), equalTo(0));
assertThat(clusters.getClusterStateCount(Cluster.Status.FAILED), equalTo(0));

Cluster localClusterSearchInfo = clusters.getCluster(RemoteClusterAware.LOCAL_CLUSTER_GROUP_KEY);
assertNotNull(localClusterSearchInfo);
assertThat(localClusterSearchInfo.getStatus(), equalTo(Cluster.Status.SUCCESSFUL));
assertThat(localClusterSearchInfo.getIndexExpression(), equalTo("nomatch*"));
assertThat(localClusterSearchInfo.getTotalShards(), equalTo(0));
assertThat(localClusterSearchInfo.getSuccessfulShards(), equalTo(0));
assertThat(localClusterSearchInfo.getSkippedShards(), equalTo(0));
assertThat(localClusterSearchInfo.getFailedShards(), equalTo(0));
assertThat(localClusterSearchInfo.getFailures().size(), equalTo(0));
assertThat(localClusterSearchInfo.getTook().millis(), equalTo(0L));

Cluster remoteClusterSearchInfo = clusters.getCluster(REMOTE_CLUSTER);
assertNotNull(remoteClusterSearchInfo);
assertThat(remoteClusterSearchInfo.getStatus(), equalTo(Cluster.Status.SUCCESSFUL));
assertThat(remoteClusterSearchInfo.getIndexExpression(), equalTo(remoteIndex));
assertThat(remoteClusterSearchInfo.getTotalShards(), equalTo(remoteNumShards));
assertThat(remoteClusterSearchInfo.getSuccessfulShards(), equalTo(remoteNumShards));
assertThat(remoteClusterSearchInfo.getSkippedShards(), equalTo(0));
assertThat(remoteClusterSearchInfo.getFailedShards(), equalTo(0));
assertThat(remoteClusterSearchInfo.getFailures().size(), equalTo(0));
assertThat(remoteClusterSearchInfo.getTook().millis(), greaterThan(0L));
});
}

private static void assertOneFailedShard(Cluster cluster, int totalShards) {
assertNotNull(cluster);
assertThat(cluster.getStatus(), equalTo(Cluster.Status.PARTIAL));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1247,6 +1247,29 @@ private void executeSearch(
indicesAndAliases,
concreteLocalIndices
);

// localShardIterators is empty since there are no matching indices. In such cases,
// we update the local cluster's status from RUNNING to SUCCESSFUL right away. Before
// we attempt to do that, we must ensure that the local cluster was specified in the user's
// search request. This is done by trying to fetch the local cluster via getCluster() and
// checking for a non-null return value. If the local cluster was never specified, its status
// update can be skipped.
if (localShardIterators.isEmpty()
&& clusters != SearchResponse.Clusters.EMPTY
&& clusters.getCluster(RemoteClusterAware.LOCAL_CLUSTER_GROUP_KEY) != null) {
clusters.swapCluster(
RemoteClusterAware.LOCAL_CLUSTER_GROUP_KEY,
(alias, v) -> new SearchResponse.Cluster.Builder(v).setStatus(SearchResponse.Cluster.Status.SUCCESSFUL)
.setTotalShards(0)
.setSuccessfulShards(0)
.setSkippedShards(0)
.setFailedShards(0)
.setFailures(Collections.emptyList())
.setTook(TimeValue.timeValueMillis(0))
.setTimedOut(false)
.build()
);
}
}
final GroupShardsIterator<SearchShardIterator> shardIterators = mergeShardsIterators(localShardIterators, remoteShardIterators);

Expand Down