-
Notifications
You must be signed in to change notification settings - Fork 25k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Propagate index errors in field_caps (#70245)
Currently we don't report any exceptions occuring during field_caps requests back to the user. This PR adds a new failure section to the response which contains exceptions per index. In addition the response contains another field, `failed_indices`, with the number of indices that threw an exception. If all of the requested indices fail, the whole request fails, otherwise the request succeeds and it is up to the caller to check for potential errors in the response body. Closes #68994
- Loading branch information
Christoph Büscher
authored
Apr 6, 2021
1 parent
a07d876
commit a413ae6
Showing
11 changed files
with
629 additions
and
77 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
108 changes: 108 additions & 0 deletions
108
...c/internalClusterTest/java/org/elasticsearch/search/fieldcaps/CCSFieldCapabilitiesIT.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License | ||
* 2.0 and the Server Side Public License, v 1; you may not use this file except | ||
* in compliance with, at your election, the Elastic License 2.0 or the Server | ||
* Side Public License, v 1. | ||
*/ | ||
|
||
package org.elasticsearch.search.fieldcaps; | ||
|
||
import org.elasticsearch.ExceptionsHelper; | ||
import org.elasticsearch.action.fieldcaps.FieldCapabilitiesFailure; | ||
import org.elasticsearch.action.fieldcaps.FieldCapabilitiesResponse; | ||
import org.elasticsearch.client.Client; | ||
import org.elasticsearch.plugins.Plugin; | ||
import org.elasticsearch.search.fieldcaps.FieldCapabilitiesIT.ExceptionOnRewriteQueryBuilder; | ||
import org.elasticsearch.search.fieldcaps.FieldCapabilitiesIT.ExceptionOnRewriteQueryPlugin; | ||
import org.elasticsearch.test.AbstractMultiClustersTestCase; | ||
import org.elasticsearch.transport.RemoteTransportException; | ||
|
||
import java.util.ArrayList; | ||
import java.util.Arrays; | ||
import java.util.Collection; | ||
import java.util.List; | ||
|
||
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked; | ||
import static org.hamcrest.Matchers.containsInAnyOrder; | ||
import static org.hamcrest.Matchers.equalTo; | ||
|
||
public class CCSFieldCapabilitiesIT extends AbstractMultiClustersTestCase { | ||
|
||
@Override | ||
protected Collection<String> remoteClusterAlias() { | ||
return List.of("remote_cluster"); | ||
} | ||
|
||
@Override | ||
protected Collection<Class<? extends Plugin>> nodePlugins(String clusterAlias) { | ||
final List<Class<? extends Plugin>> plugins = new ArrayList<>(super.nodePlugins(clusterAlias)); | ||
plugins.add(ExceptionOnRewriteQueryPlugin.class); | ||
return plugins; | ||
} | ||
|
||
public void testFailuresFromRemote() { | ||
final Client localClient = client(LOCAL_CLUSTER); | ||
final Client remoteClient = client("remote_cluster"); | ||
String localIndex = "local_test"; | ||
assertAcked(localClient.admin().indices().prepareCreate(localIndex)); | ||
localClient.prepareIndex(localIndex).setId("1").setSource("foo", "bar").get(); | ||
localClient.admin().indices().prepareRefresh(localIndex).get(); | ||
|
||
String remoteErrorIndex = "remote_test_error"; | ||
assertAcked(remoteClient.admin().indices().prepareCreate(remoteErrorIndex)); | ||
remoteClient.prepareIndex(remoteErrorIndex).setId("2").setSource("foo", "bar").get(); | ||
remoteClient.admin().indices().prepareRefresh(remoteErrorIndex).get(); | ||
|
||
// regular field_caps across clusters | ||
FieldCapabilitiesResponse response = client().prepareFieldCaps("*", "remote_cluster:*").setFields("*").get(); | ||
assertThat(Arrays.asList(response.getIndices()), containsInAnyOrder(localIndex, "remote_cluster:" + remoteErrorIndex)); | ||
|
||
// adding an index filter so remote call should fail | ||
response = client().prepareFieldCaps("*", "remote_cluster:*") | ||
.setFields("*") | ||
.setIndexFilter(new ExceptionOnRewriteQueryBuilder()) | ||
.get(); | ||
assertThat(response.getIndices()[0], equalTo(localIndex)); | ||
assertThat(response.getFailedIndices()[0], equalTo("remote_cluster:*")); | ||
FieldCapabilitiesFailure failure = response.getFailures() | ||
.stream() | ||
.filter(f -> Arrays.asList(f.getIndices()).contains("remote_cluster:*")) | ||
.findFirst().get(); | ||
Exception ex = failure.getException(); | ||
assertEquals(RemoteTransportException.class, ex.getClass()); | ||
Throwable cause = ExceptionsHelper.unwrapCause(ex); | ||
assertEquals(IllegalArgumentException.class, cause.getClass()); | ||
assertEquals("I throw because I choose to.", cause.getMessage()); | ||
|
||
// if we only query the remote we should get back an exception only | ||
ex = expectThrows( | ||
IllegalArgumentException.class, | ||
() -> client().prepareFieldCaps("remote_cluster:*") | ||
.setFields("*") | ||
.setIndexFilter(new ExceptionOnRewriteQueryBuilder()) | ||
.get()); | ||
assertEquals("I throw because I choose to.", ex.getMessage()); | ||
|
||
// add an index that doesn't fail to the remote | ||
assertAcked(remoteClient.admin().indices().prepareCreate("okay_remote_index")); | ||
remoteClient.prepareIndex("okay_remote_index").setId("2").setSource("foo", "bar").get(); | ||
remoteClient.admin().indices().prepareRefresh("okay_remote_index").get(); | ||
|
||
response = client().prepareFieldCaps("*", "remote_cluster:*") | ||
.setFields("*") | ||
.setIndexFilter(new ExceptionOnRewriteQueryBuilder()) | ||
.get(); | ||
assertThat(Arrays.asList(response.getIndices()), containsInAnyOrder(localIndex, "remote_cluster:okay_remote_index")); | ||
assertThat(response.getFailedIndices()[0], equalTo("remote_cluster:" + remoteErrorIndex)); | ||
failure = response.getFailures() | ||
.stream() | ||
.filter(f -> Arrays.asList(f.getIndices()).contains("remote_cluster:" + remoteErrorIndex)) | ||
.findFirst().get(); | ||
ex = failure.getException(); | ||
assertEquals(RemoteTransportException.class, ex.getClass()); | ||
cause = ExceptionsHelper.unwrapCause(ex); | ||
assertEquals(IllegalArgumentException.class, cause.getClass()); | ||
assertEquals("I throw because I choose to.", cause.getMessage()); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.