diff --git a/test/framework/src/main/java/org/elasticsearch/test/rest/yaml/ClientYamlTestClient.java b/test/framework/src/main/java/org/elasticsearch/test/rest/yaml/ClientYamlTestClient.java index 748a08384ca..c18dad907bd 100644 --- a/test/framework/src/main/java/org/elasticsearch/test/rest/yaml/ClientYamlTestClient.java +++ b/test/framework/src/main/java/org/elasticsearch/test/rest/yaml/ClientYamlTestClient.java @@ -32,7 +32,6 @@ import org.elasticsearch.client.ResponseException; import org.elasticsearch.client.RestClient; import org.elasticsearch.common.Strings; import org.elasticsearch.common.logging.Loggers; -import org.elasticsearch.common.util.set.Sets; import org.elasticsearch.test.rest.yaml.restspec.ClientYamlSuiteRestApi; import org.elasticsearch.test.rest.yaml.restspec.ClientYamlSuiteRestPath; import org.elasticsearch.test.rest.yaml.restspec.ClientYamlSuiteRestSpec; @@ -44,7 +43,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Objects; -import java.util.Set; /** * Used by {@link ESClientYamlSuiteTestCase} to execute REST requests according to the tests written in yaml suite files. Wraps a @@ -53,11 +51,6 @@ import java.util.Set; */ public class ClientYamlTestClient { private static final Logger logger = Loggers.getLogger(ClientYamlTestClient.class); - /** - * Query params that don't need to be declared in the spec, they are supported by default. - */ - private static final Set ALWAYS_ACCEPTED_QUERY_STRING_PARAMS = Sets.newHashSet( - "ignore", "error_trace", "human", "filter_path", "pretty", "source"); private final ClientYamlSuiteRestSpec restSpec; private final RestClient restClient; @@ -108,7 +101,8 @@ public class ClientYamlTestClient { if (restApi.getPathParts().contains(entry.getKey())) { pathParts.put(entry.getKey(), entry.getValue()); } else { - if (restApi.getParams().contains(entry.getKey()) || ALWAYS_ACCEPTED_QUERY_STRING_PARAMS.contains(entry.getKey())) { + if (restApi.getParams().contains(entry.getKey()) || restSpec.isGlobalParameter(entry.getKey()) + || restSpec.isClientParameter(entry.getKey())) { queryStringParams.put(entry.getKey(), entry.getValue()); } else { throw new IllegalArgumentException("param [" + entry.getKey() + "] not supported in [" diff --git a/test/framework/src/main/java/org/elasticsearch/test/rest/yaml/restspec/ClientYamlSuiteRestSpec.java b/test/framework/src/main/java/org/elasticsearch/test/rest/yaml/restspec/ClientYamlSuiteRestSpec.java index 4efed709e22..15f2f7e3016 100644 --- a/test/framework/src/main/java/org/elasticsearch/test/rest/yaml/restspec/ClientYamlSuiteRestSpec.java +++ b/test/framework/src/main/java/org/elasticsearch/test/rest/yaml/restspec/ClientYamlSuiteRestSpec.java @@ -30,18 +30,21 @@ import java.nio.file.Files; import java.nio.file.Path; import java.util.Collection; import java.util.HashMap; +import java.util.HashSet; import java.util.Map; +import java.util.Set; /** * Holds the specification used to turn {@code do} actions in the YAML suite into REST api calls. */ public class ClientYamlSuiteRestSpec { - Map restApiMap = new HashMap<>(); + private final Set globalParameters = new HashSet<>(); + private final Map restApiMap = new HashMap<>(); private ClientYamlSuiteRestSpec() { } - void addApi(ClientYamlSuiteRestApi restApi) { + private void addApi(ClientYamlSuiteRestApi restApi) { ClientYamlSuiteRestApi previous = restApiMap.putIfAbsent(restApi.getName(), restApi); if (previous != null) { throw new IllegalArgumentException("cannot register api [" + restApi.getName() + "] found in [" + restApi.getLocation() + "]. " @@ -57,6 +60,21 @@ public class ClientYamlSuiteRestSpec { return restApiMap.values(); } + /** + * Returns whether the provided parameter is one of those parameters that are supported by all Elasticsearch api + */ + public boolean isGlobalParameter(String param) { + return globalParameters.contains(param); + } + + /** + * Returns whether the provided parameter is one of those parameters that are supported by the Elasticsearch language clients, meaning + * that they influence the client behaviour and don't get sent to Elasticsearch + */ + public boolean isClientParameter(String name) { + return "ignore".equals(name); + } + /** * Parses the complete set of REST spec available under the provided directories */ @@ -66,15 +84,39 @@ public class ClientYamlSuiteRestSpec { for (String path : paths) { for (Path jsonFile : FileUtils.findJsonSpec(fileSystem, optionalPathPrefix, path)) { try (InputStream stream = Files.newInputStream(jsonFile)) { + String filename = jsonFile.getFileName().toString(); try (XContentParser parser = JsonXContent.jsonXContent.createParser(NamedXContentRegistry.EMPTY, stream)) { - ClientYamlSuiteRestApi restApi = restApiParser.parse(jsonFile.toString(), parser); - String filename = jsonFile.getFileName().toString(); - String expectedApiName = filename.substring(0, filename.lastIndexOf('.')); - if (restApi.getName().equals(expectedApiName) == false) { - throw new IllegalArgumentException("found api [" + restApi.getName() + "] in [" + jsonFile.toString() + "]. " + - "Each api is expected to have the same name as the file that defines it."); + if (filename.equals("_common.json")) { + String currentFieldName = null; + while (parser.nextToken() != XContentParser.Token.END_OBJECT) { + if (parser.currentToken() == XContentParser.Token.FIELD_NAME) { + currentFieldName = parser.currentName(); + } else if (parser.currentToken() == XContentParser.Token.START_OBJECT + && "params".equals(currentFieldName)) { + while (parser.nextToken() == XContentParser.Token.FIELD_NAME) { + String param = parser.currentName(); + if (restSpec.globalParameters.contains(param)) { + throw new IllegalArgumentException("Found duplicate global param [" + param + "]"); + } + restSpec.globalParameters.add(param); + parser.nextToken(); + if (parser.currentToken() != XContentParser.Token.START_OBJECT) { + throw new IllegalArgumentException("Expected params field in rest api definition to " + + "contain an object"); + } + parser.skipChildren(); + } + } + } + } else { + ClientYamlSuiteRestApi restApi = restApiParser.parse(jsonFile.toString(), parser); + String expectedApiName = filename.substring(0, filename.lastIndexOf('.')); + if (restApi.getName().equals(expectedApiName) == false) { + throw new IllegalArgumentException("found api [" + restApi.getName() + "] in [" + jsonFile.toString() + + "]. " + "Each api is expected to have the same name as the file that defines it."); + } + restSpec.addApi(restApi); } - restSpec.addApi(restApi); } } catch (Exception ex) { throw new IOException("Can't parse rest spec file: [" + jsonFile + "]", ex);