-
Notifications
You must be signed in to change notification settings - Fork 25k
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 support for Indices Update Settings API #28892
Conversation
Since this is a community submitted pull request, a Jenkins build has not been kicked off automatically. Can an Elastic organization member please verify the contents of this patch and then kick off a build manually? |
1 similar comment
Since this is a community submitted pull request, a Jenkins build has not been kicked off automatically. Can an Elastic organization member please verify the contents of this patch and then kick off a build manually? |
There was a problem hiding this 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, LGTM though
@@ -0,0 +1,142 @@ | |||
[[java-rest-high-indices-put-settings]] | |||
=== Update Indices Settings API |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shall we call the page "Update Settings API" given that it's under the Indices API group already?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 I would prefer to shorten it
But https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-update-settings.html
is using Update Indices Settings
and currently the high level rest client docs are using the same names as the ones in the reference docs...
To keep the consistency between the client and the ref docs, maybe the ref docs should be changed as well?
@javanna what do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
leave it as-is then :)
"timeout": { | ||
"type" : "time", | ||
"description" : "Explicit operation timeout" | ||
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good catch, thanks
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Relates to #27158
|
||
/** | ||
* Request for an update index settings action | ||
*/ | ||
public class UpdateSettingsRequest extends AcknowledgedRequest<UpdateSettingsRequest> implements IndicesRequest.Replaceable { | ||
public class UpdateSettingsRequest extends AcknowledgedRequest<UpdateSettingsRequest> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should we also move its parsing code from the rest action and add a test UpdateSettingsRequestTests
that tests both parsing and printing out from/to xcontent?
test this please |
test this please |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I left a few comments, mainly on testing. I will merge once those are addressed
parameters.withFlatSettings(updateSettingsRequest.flatSettings()); | ||
parameters.withPreserveExisting(updateSettingsRequest.isPreserveExisting()); | ||
|
||
String endpoint = buildEndpoint("_settings"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Along with the changes I made in #28866, this would become something like this:
String[] indices = updateSettingsRequest.indices() == null ? Strings.EMPTY_ARRAY : updateSettingsRequest.indices();
String endpoint = endpoint(indices, "_settings");
} | ||
} | ||
updateSettingsRequest.settings(settings); | ||
request.applyContentParser(parser -> updateSettingsRequest.fromXContent(parser)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this makes RequestsWithoutContentIT#testPutSettingsMissingBody
fail, as applyContentParser
doesn't require a response body. That is only because of a different error message though, as we now fail during request validation rather than on the REST layer. I think that failing earlier was better though. Can you do updateSettingsRequest.fromXContent(request.contentParser());
instead?
return builder; | ||
} | ||
}; | ||
bytesRef = toShuffledXContent(requestWithEnclosingSettings, xContentType, ToXContent.EMPTY_PARAMS, humanReadable); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this could be part of createTestItem?
|
||
import static org.hamcrest.CoreMatchers.equalTo; | ||
|
||
public class UpdateSettingsRequestTests extends ESTestCase { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
would it be possible to extend AbstractStreamableXContentTestCase
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That would be better! But now the equals and the hachCode look "funny" ( only the serialized content is included ). Do you have an idea how to go about this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just committed another version where the equals and hashCode look correct and the test code for the serialization has been tweaked. I find the second approach cleaner and we should go with it. Do you agree ?
[[java-rest-high-indices-put-settings-response]] | ||
==== Update Indices Settings Response | ||
|
||
The returned `UpdateSettings` allows to retrieve information about the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
UpdateSettingsResponse ?
@@ -1227,6 +1228,34 @@ public void testRollover() throws IOException { | |||
assertEquals(expectedParams, request.getParameters()); | |||
} | |||
|
|||
public void testIndexPutSettings() throws IOException { | |||
String[] indices = randomIndicesNames(0, 2); | |||
UpdateSettingsRequest updateSettingsRequest = new UpdateSettingsRequest(indices); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we also test the case where indices are not set at all, then the request would hold null
?
@javanna thanks for the review! |
@olcbean no worries, you can either merge master in or rebase, I don't mind. |
rewrite the PutSettingsRequestTests to extend from AbstractStreamableXContentTestCase
@javanna can you have another look ? |
@Override | ||
protected void assertEqualInstances(UpdateSettingsRequest expectedInstance, UpdateSettingsRequest newInstance) { | ||
newInstance.indices(expectedInstance.indices()); | ||
super.assertEqualInstances(expectedInstance, newInstance); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see now better what I made you do! I am sorry, I think that I don't like it :) Our requests don't fit well with this way of testing. While responses are usually entirely serialized both on the transport layer and on the REST layer, with requests the toXContent is only the request body, but there's also the query_string params that are serialized at transport but not as XContent. This makes for impossible equals/hashcode and complicated testing. To do things right, here we should probably have two different tests, one for the Xcontent part and one for the serialization. I am wondering though if this is becoming besides the scope of this PR. I am totally fine with going back to testing only XContent here. Thanks for trying, and sorry for the back and forth.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No worries, it is fun to experiment :) Now we know that it is better to keep the *RequestTests
extend ESTestCase
( or maybe AbstractStreamableTestCase
but extending from AbstractStreamableXContentTestCase
makes the tests tricky to maintain )
I still kept the serialization tests and went back to explicit to/from XContent testing.
BytesReference originalBytes = toShuffledXContent(requestWithEnclosingSettings, xContentType, ToXContent.EMPTY_PARAMS, humanReadable); | ||
if (randomBoolean()) { | ||
Predicate<String> excludeFilter = (s) -> s.startsWith("settings"); | ||
bytesRef = insertRandomFields(xContentType, originalBytes, excludeFilter, random()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I noticed something strange in the UpdateSettingsRequest#fromXContent
( maybe not as part of this PR but it is easy to show it here ;) )
If the request is something like :
{
"field1" : "value1",
"field2" : "value2",
"settings" :
{
"field3" : "value3"
}
}
only "field3" : "value3"
is parsed as a setting in the request ( exposed here by the insertRandomFields
: inserting a random object at the top level is silently ignored )
Do we want such leniency in the requests ?
Do we want to keep on supporting the possibility to wrap the settings in "settings"
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
great catch, I would assume that we want to get rid of this but it's a potentially breaking change. Would you mind opening a new issue for this please?
retest this please |
// end::put-settings-request | ||
|
||
// tag::put-settings-create-settings | ||
String settingKey = IndexMetaData.SETTING_NUMBER_OF_REPLICAS; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: shall we just use the string here? IndexMetaData is quite an internal class that will go away once the high-level REST client won't depend on Elasticsearch anymore. I wouldn't want to have users copy paste this.
-------------------------------------------------- | ||
include-tagged::{doc-tests}/IndicesClientDocumentationIT.java[put-settings-request-flat-settings] | ||
-------------------------------------------------- | ||
<1> Wether the updated settings returned in the `UpdateSettings` should |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Whether?
super.assertEqualInstances(expectedInstance, newInstance); | ||
} | ||
|
||
public void testXContent() throws IOException { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do you think that it would be possible to have two different test classes, one for the xcontent bits, that doesn't rely on equals/hashcode , and the other one like this on that we have that tests serialization and ordinary equals/hashcode ? Let me know if I am missing something.
address reviewer remarks
@javanna can you have another look ? |
@Override | ||
protected void assertEqualInstances(UpdateSettingsRequest expectedInstance, UpdateSettingsRequest newInstance) { | ||
newInstance.indices(expectedInstance.indices()); | ||
super.assertEqualInstances(expectedInstance, newInstance); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
shouldn't we rely on the ordinary equals/hashcode here? But also preserveExisting and indicesOptions should be taken into account?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🤦
import static org.elasticsearch.test.XContentTestUtils.insertRandomFields; | ||
import static org.hamcrest.Matchers.equalTo; | ||
|
||
public class UpdateSettingsRequestTests extends ESTestCase { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could we extend AbstractXContentTestCase
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AFAICS the AbstractXContentTestCase
will use the #assertEqualInstances
and then I will need to "exclude" everything but the settings from the equals / hashCode ( similar to https://github.com/olcbean/elasticsearch/blob/32454d96e71a68f395bfe20320a0018f1d1ecc10/server/src/test/java/org/elasticsearch/action/admin/indices/settings/put/UpdateSettingsRequestTests.java#L65-L68 ). Hence I opted for the basic ESTestCase
.
What do you think ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the nice thing of it is that you wouldn't need to write the usual code to test parsing etc. indeed in this case you would have to rewrite assertEqualInstances to not rely on equals/hashcode so that we only check stuff that is serialized over xcontent. I would give this a try if you don't mind, unless there are complications that I don't see :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Testing the enclosing "settings" gets a little bit more complicated.
I made two commits with a simple version for the XContentTests and the last one includes the enclosing "settings" ( as I am not sure if we actually want to test for enclosing "settings" )
retest this please |
There was a problem hiding this 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 nits, LGTM otherwise, thanks for your patience once again ;)
|
||
@Override | ||
protected boolean supportsUnknownFields() { | ||
return enclosedSettings; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if we should test this, in general requests should always be strict, unless they accept key-value pairs like in this case with settings. I think that I would always return false
here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am fine either way. I decided to leave it here till #29268 is fixed and the enclosing "settings"
are removed, then the test can be really simplified :)
IMHO for any request this should be set to false
: any object insertion at the top level should make the parsing fail ( for predefined field names ).
Off-topic : should we consider extending the AbstractXContentTestCase
to explicitly test that if supportsUnknownFields
is false
actually an exception is thrown when an object is inserted at the top-level ? ( this can lead to a lot of changes in the tests and maybe the code, but could help determine how strict the rest request parsing is... )
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would set it to false too. I think that what you propose is a good idea, we have been using that flag only to test that we are lenient with responses, but we could use it also to test that we are strict.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what I had missed is that we cannot set it to false unless we get rid of the leniency caused by parsing the settings object etc.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you want to open an issue about this ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes makes sense to me.
|
||
public class UpdateSettingsRequestTests extends AbstractXContentTestCase<UpdateSettingsRequest> { | ||
|
||
private boolean enclosedSettings = randomBoolean(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: make this final?
|
||
@Override | ||
protected void assertEqualInstances(UpdateSettingsRequest expectedInstance, UpdateSettingsRequest newInstance) { | ||
super.assertEqualInstances(new UpdateSettingsRequest(expectedInstance.settings()), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you leave a short comment here to explain why we do this? Smart way of doing it btw!
@javanna thanks for the reviews ! |
Thanks @olcbean ! |
…gs API (elastic#28892)" This reverts commit b67b5b1.
@olcbean @javanna I am sorry, I have to revert this PR from master and 6.x. We have tests of x-pack build failing because of this change. Citing @jaymode here:
I would suggest modify equality methods in MasterNodeRequest to address this. |
Ops! @mayya-sharipova I just opened a PR removing the equals for the MasterNodeRequest ( #29327 ). This should fix the problem. Hopefully ;) I do not know what tests are affected and / or the test infrastructure but if the tests in the x-pack expect the default ( identity ) equals, maybe it would be better to call |
* master: (80 commits) Remove HTTP max content length leniency (elastic#29337) Begin moving XContent to a separate lib/artifact (elastic#29300) Java versions for ci (elastic#29320) Minor cleanup in the InternalEngine (elastic#29241) Clarify expectations of false positives/negatives (elastic#27964) Update docs on vertex ordering (elastic#27963) Revert "REST high-level client: add support for Indices Update Settings API (elastic#28892)" (elastic#29323) [test] remove Streamable serde assertions (elastic#29307) Improve query string docs (elastic#28882) fix query string example for boolean query (elastic#28881) Resolve unchecked cast warnings introduced with elastic#28892 REST high-level client: add support for Indices Update Settings API (elastic#28892) Search: Validate script query is run with a single script (elastic#29304) [DOCS] Added info on WGS-84. Closes issue elastic#3590 (elastic#29305) Increase timeout on Netty client latch for tests Build: Use branch specific refspec sysprop for bwc builds (elastic#29299) TEST: trim unsafe commits before opening engine Move trimming unsafe commits from engine ctor to store (elastic#29260) Fix incorrect geohash for lat 90, lon 180 (elastic#29256) Do not load global state when deleting a snapshot (elastic#29278) ...
Related to #27205