Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

REST high-level client: add validate query API #31077

Merged
merged 11 commits into from
Jun 18, 2018

Conversation

sohaibiftikhar
Copy link
Contributor

Relates to #27205

Set<QueryExplanation> queryExplSet = new HashSet<>(getQueryExplanation());
// We only compare with the index and the shardId because for every failure this is unique.
// Also because it is hard to compare Throwable.
Set<Tuple<String, Integer>> shardFailureSet =
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nik9000 @javanna Since its hard to compare exceptions, in this case, I just check for the index and the shardId. Is this alright?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd prefer to keep the equals method complete and only use it in the test when there aren't exceptions. I dunno what we've done other places though.

I'd also like to do something like assertThat(exception.getMessage(), containsString("original message"));.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The assert part makes sense. However, I don't completely understand what needs to be done for the equals.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean to make equals just call equals on the Exceptions. It can certainly do Objects.equals for the null, but I'd prefer the equals make sure the objects are actually equal. And because we can't assert proper equality when round tripping the exceptions I'd hand write an test for the round tripping with exceptions and leave exceptions out of the AbstractStreamableTestCase infrastructure.

// We cannot have XContent equivalence for ValidateResponseTests as it holds the BroadcastResponse which
// holds a List<DefaultShardOperationFailedException>. The DefaultShardOperationFailedException uses ElasticSearchException
// for serializing/deserializing a Throwable and the serialized and deserialized versions do not match.
return false;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nik9000 @javanna I also added this for the same reason. Since exception messages change after deserialization with ElasticSearchException.

@Override
public int hashCode() {
int result = 1;
if (getIndex() != null) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd use Objects.hash because the performance here isn't that important and it is easier to review for correctness.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! I didn't know this existed either :)


@Override
public boolean equals(Object o) {
if (o instanceof QueryExplanation) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you make this look like our other equals methods?

Set<QueryExplanation> queryExplSet = new HashSet<>(getQueryExplanation());
// We only compare with the index and the shardId because for every failure this is unique.
// Also because it is hard to compare Throwable.
Set<Tuple<String, Integer>> shardFailureSet =
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd prefer to keep the equals method complete and only use it in the test when there aren't exceptions. I dunno what we've done other places though.

I'd also like to do something like assertThat(exception.getMessage(), containsString("original message"));.

* In case it does, such behaviour will be tested by comparing the XContent of the original instance
* and the parsed/deserialized instance.
*/
protected boolean assertToXContentEquivalence() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nik9000 So what do you reckon? I shouldn't extend AbstractStreamableXContentTestCase?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you can extend that to get good randomized coverage for the case when you don't have any exceptions and then hand write a couple of test cases for the exception round tripping. I think @javanna talked about doing that some other place....

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have a look at ListTasksResponseTests, where we separate testing between two scenarios: without (no big problems, assertToXContentEquivalence true) and with (assertToXContentEquivalence false). I think that this change may not be needed if you do it that way.

@nik9000
Copy link
Member

nik9000 commented Jun 4, 2018

@elasticmachine, whitelist this PR please.

@nik9000
Copy link
Member

nik9000 commented Jun 4, 2018

@elasticmachine, add to whitelist

@elasticmachine
Copy link
Collaborator

Pinging @elastic/es-core-infra

@sohaibiftikhar
Copy link
Contributor Author

I was not able to reproduce the errors on my machine. Will merge in master to see if that fixes it. There is a remote possibility that these are related though.

@@ -804,6 +805,17 @@ static Request putTemplate(PutIndexTemplateRequest putIndexTemplateRequest) thro
return request;
}

static Request validateQuery(ValidateQueryRequest validateQueryRequest) throws IOException {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, thanks for catching this.

[[java-rest-high-indices-validate-query-request]]
==== Validate Query Request

A `ValidateRequest` requires one or more `indices` on which to the query is validated. If not index
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ValidateQueryRequest

params.putParam("explain", Boolean.toString(validateQueryRequest.explain()));
params.putParam("all_shards", Boolean.toString(validateQueryRequest.allShards()));
params.putParam("rewrite", Boolean.toString(validateQueryRequest.rewrite()));
request.setEntity(createEntity(validateQueryRequest, REQUEST_BODY_CONTENT_TYPE));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

@sohaibiftikhar sohaibiftikhar Jun 4, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

types are being set in the URL I believe. I will add the indicesOptions.

@sohaibiftikhar
Copy link
Contributor Author

@nik9000 Could you have a look again when you have time?

-- Removed equals and hashCode from ValidateQueryResponse
-- Extended AbstractBroadcastResponseTestCase instead of AbstractStreamableXContentTestCase
-- Fixed asciidoc
-- Added test for RequestConverters::validateQuery
-- Added indicesOptions
Copy link
Member

@javanna javanna left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

left a couple of comments as well.

* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/search-validate.html"> Validate Query API
* on elastic.co</a>
*/
public void validateQueryAsync(ValidateQueryRequest validateQueryRequest, RequestOptions options,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you please add params tag like we have now in all of the other methods?

}



Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: can you remove some of these empty lines please?

include-tagged::{doc-tests}/IndicesClientDocumentationIT.java[validate-query-request-query]
--------------------------------------------------
<1> Build the desired query.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you add an example of how to set the query to the request?

result &= other.getExplanation() == null;
} else {
result &= getExplanation().equals(other.getExplanation());
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is there a reason not to use Objects.equals like we do in a lot of other equals methods?

Copy link
Contributor Author

@sohaibiftikhar sohaibiftikhar Jun 8, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right. I will switch this. It will at least remove the null checks.

public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
builder.field("query");
query.toXContent(builder, params);
return builder;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you make it a ToXContentObject please instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this case, I should add builder.startObject in the toXContent method, right?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yea startObject and endObject, see #31155 also

queryExplanations.add(queryExplanation);
}
Collections.shuffle(queryExplanations, random());
Collections.shuffle(shardFailures, random());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do we need to shuffle these two?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are creating the XContent thing very serially. First all successful ones and then all failures. I thought it would be more realistic if this was shuffled.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but they go to two different lists, so I think that what matters is that each item is randomized? I am not sure but shuffling buys us.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The query explanation contains the failures and the successful ones. Ok, we can do away with the shuffling of failures. But the query explanations should stay I think.

);
}

protected static ValidateQueryResponse createRandomValidateQueryResponse() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do these methods need to be protected?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Umm no I think. I will make it private.

-- added javadoc
-- added documentation for setting query to request
-- changed to Object.equals for QueryExplanation::equals
-- extended ToXContentObject instead of ToXContentFragment for request
include::indices/get_templates.asciidoc[]
>>>>>>> 0bfd18cc8b6ab7e58d1d34c50ae7a3b441799761
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this may be why the docs don't build? :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. Thanks. Seems I forgot to build the docs after merging...

@@ -490,7 +491,7 @@ static Request update(UpdateRequest updateRequest) throws IOException {
XContentType upsertContentType = updateRequest.upsertRequest().getContentType();
if ((xContentType != null) && (xContentType != upsertContentType)) {
throw new IllegalStateException("Update request cannot have different content types for doc [" + xContentType + "]" +
" and upsert [" + upsertContentType + "] documents");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you revert these formatting changes that aren't part the change? It make git blame harder to work with and I kind of like the old formatting better anyway.

@@ -712,8 +713,8 @@ public void testSyncedFlush() {
Request request = RequestConverters.flushSynced(syncedFlushRequest);
StringJoiner endpoint = new StringJoiner("/", "/", "");
if (indices != null && indices.length > 0) {
endpoint.add(String.join(",", indices));
}
endpoint.add(String.join(",", indices));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This formatting change is fine though, because the old code was just wrong.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm aware that this is somewhat contradictory.

@@ -244,17 +248,17 @@ public void testDeleteIndexAsync() throws Exception {

// tag::delete-index-execute-listener
ActionListener<DeleteIndexResponse> listener =
new ActionListener<DeleteIndexResponse>() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this change is fine but I'd prefer it in a separate PR.

@@ -287,7 +291,7 @@ public void testCreateIndex() throws IOException {
{
// tag::create-index-request-mappings
request.mapping("tweet", // <1>
"{\n" +
"{\n" +
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We want to keep the "s aligned.

@@ -378,21 +382,21 @@ public void testCreateIndex() throws IOException {
request = new CreateIndexRequest("twitter6");
// tag::create-index-whole-source
request.source("{\n" +
" \"settings\" : {\n" +
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you revert the formatting change? I think the old way is better. If we want to do it we should do it in a separate PR anyway.

@@ -1844,8 +1848,8 @@ public void testIndexPutSettings() throws Exception {
{
// tag::put-settings-settings-source
request.settings(
"{\"index.number_of_replicas\": \"2\"}"
, XContentType.JSON); // <1>
"{\"index.number_of_replicas\": \"2\"}"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you revert all of these formatting changes above?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I messed up something during the merge from master and my editor did all these formats. I will revert everything back.

@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
if (getIndex() != null) {
builder.field(INDEX_FIELD, getIndex());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tend to use the members rather than the getters for these but either way is ok by me!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I used to prefer that too. Then I saw in some classes that the getters also had some logic which I wanted to use. So I started using these...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the getters have logic that you want that is a great reason to use them!


@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this'd be better formatted like:

builder.startObject();
builder.field("query");
query.toXContent(builder, params);
return builder.endObject();

Copy link
Member

@nik9000 nik9000 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. @hub-cap, would you like another look?

@nik9000
Copy link
Member

nik9000 commented Jun 13, 2018

LGTM. @hub-cap, would you like another look?

Woops, not @hub-cap, @javanna.

Copy link
Member

@javanna javanna left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM thanks @sohaibiftikhar

@nik9000 nik9000 merged commit c4f8df3 into elastic:master Jun 18, 2018
@sohaibiftikhar sohaibiftikhar deleted the validate_query branch June 18, 2018 14:12
nik9000 pushed a commit that referenced this pull request Jun 18, 2018
Adds the validate query API to the high level rest client.
@nik9000
Copy link
Member

nik9000 commented Jun 18, 2018

Merged and backported! Thanks @sohaibiftikhar!

dnhatn added a commit that referenced this pull request Jun 19, 2018
* 6.x:
  Add get stored script and delete stored script to high level REST API
  Increasing skip version for failing test on 6.x
  Skip get_alias tests for 5.x (#31397)
  Fix defaults in GeoShapeFieldMapper output (#31302)
  Test: better error message on failure
  Mute DefaultShardsIT#testDefaultShards test
  Fix reference to XContentBuilder.string() (#31337)
  [DOCS] Adds monitoring breaking change (#31369)
  [DOCS] Adds security breaking change (#31375)
  [DOCS] Backports breaking change (#31373)
  RestAPI: Reject forcemerge requests with a body (#30792)
  Docs: Use the default distribution to test docs (#31251)
  Use system context for cluster state update tasks (#31241)
  [DOCS] Adds testing for security APIs (#31345)
  [DOCS] Removes ML item from release highlights
  [DOCS] Removes breaking change (#31376)
  REST high-level client: add validate query API (#31077)
  Move language analyzers from server to analysis-common module. (#31300)
  Expose lucene's RemoveDuplicatesTokenFilter (#31275)
  [Test] Fix :example-plugins:rest-handler on Windows
  Delete typos in SAML docs (#31199)
  Ensure we don't use a remote profile if cluster name matches (#31331)
  Test: Skip alias tests that failed all weekend
  [DOCS] Fix version in SQL JDBC Maven template
  [DOCS] Improve install and setup section for SQL JDBC
  Add ingest-attachment support for per document `indexed_chars` limit (#31352)
  SQL: Fix rest endpoint names in node stats (#31371)
  [DOCS] Fixes small issue in release notes
  Support for remote path in reindex api Closes #22913
  [ML] Put ML filter API response should contain the filter (#31362)
  Remove trial status info from start trial doc (#31365)
  [DOCS] Added links in breaking changes pages
  [DOCS] Adds links to release notes and highlights
  Docs: Document changes in rest client
  QA: Fix tribe tests to use node selector
  REST Client: NodeSelector for node attributes (#31296)
  LLClient: Fix assertion on windows
  LLClient: Support host selection (#30523)
  Add QA project and fixture based test for discovery-ec2 plugin (#31107)
  [ML] Hold ML filter items in sorted set (#31338)
  [ML] Add description to ML filters (#31330)
dnhatn added a commit that referenced this pull request Jun 19, 2018
* master:
  Add get stored script and delete stored script to high level REST API - post backport fix
  Add get stored script and delete stored script to high level REST API (#31355)
  Core: Combine Action and GenericAction (#31405)
  Fix reference to XContentBuilder.string() (#31337)
  Avoid sending duplicate remote failed shard requests (#31313)
  Fix defaults in GeoShapeFieldMapper output (#31302)
  RestAPI: Reject forcemerge requests with a body (#30792)
  Packaging: Remove windows bin files from the tar distribution (#30596)
  Docs: Use the default distribution to test docs (#31251)
  [DOCS] Adds testing for security APIs (#31345)
  Clarify that IP range data can be specified in CIDR notation. (#31374)
  Use system context for cluster state update tasks (#31241)
  Percentile/Ranks should return null instead of NaN when empty (#30460)
  REST high-level client: add validate query API (#31077)
  Move language analyzers from server to analysis-common module. (#31300)
  [Test] Fix :example-plugins:rest-handler on Windows
  Expose lucene's RemoveDuplicatesTokenFilter (#31275)
  Reload secure settings for plugins (#31383)
  Remove some cases in FieldTypeLookupTests that are no longer relevant. (#31381)
  Ensure we don't use a remote profile if cluster name matches (#31331)
  [TEST] Double write alias fault (#30942)
  [DOCS] Fix version in SQL JDBC Maven template
  [DOCS] Improve install and setup section for SQL JDBC
  SQL: Fix rest endpoint names in node stats (#31371)
  Support for remote path in reindex api - post backport fix Closes #22913
  [ML] Put ML filter API response should contain the filter (#31362)
  Support for remote path in reindex api (#31290)
  Add byte array pooling to nio http transport (#31349)
  Remove trial status info from start trial doc (#31365)
  [DOCS] Adds links to release notes and highlights
  add is-write-index flag to aliases (#30942)
  Add rollover-creation-date setting to rolled over index (#31144)
  [ML] Hold ML filter items in sorted set (#31338)
  [Tests] Fix edge case in ScriptedMetricAggregatorTests (#31357)
@camerondavison
Copy link

Is there a reason that some methods in this api such as

do not return this ValidateQueryRequest

@javanna
Copy link
Member

javanna commented Mar 15, 2019

hi @camerondavison the reason is merely that newly added methods do not return the request, while old methods do. We would prefer to have pure setters in our codebase at this point, but we don't see the value in such a big breaking change, hence we only apply the preferred standard when adding new methods for now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants