-
Notifications
You must be signed in to change notification settings - Fork 24.8k
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
Add Snapshots Status API to High Level Rest Client #31515
Conversation
SnapshotStats fromXContent added. SnapshotSharsStats fromXContent added. SnapshotIndexShardStatus fromXContent added. SnapshotIndexStatus fromXContent added. SnapshotStatus fromXContent added. SnapshotStatusResponse fromXContent added. Add RequestConverter code. Add snapshots status apis to the snapshot client. Add testing and documentation for snapshots status api
Pinging @elastic/es-core-infra |
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.
Id love to do another pass once you convert those older parsed fromXContent
methods to use an ObjectParser
:)
|
||
Params parameters = new Params(request); | ||
parameters.withMasterTimeout(snapshotsStatusRequest.masterNodeTimeout()); | ||
parameters.putParam("ignore_unavailable", Boolean.toString(snapshotsStatusRequest.ignoreUnavailable())); |
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.
it might make sense to build out ignore_unavailable
into a method now that its used in 2x places.
createSnapshot.addParameter("wait_for_completion", "true"); | ||
createSnapshot.setEntity(new NStringEntity("{\"indices\":\""+index+"\"}", ContentType.APPLICATION_JSON)); | ||
return highLevelClient().getLowLevelClient().performRequest(createSnapshot); | ||
} |
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.
You should rebase on 90d62e6. It included a createTestSnapshot
method here as well for his tests.
PutRepositoryResponse putRepositoryResponse = createTestRepository("test", FsRepository.TYPE, "{\"location\": \".\"}"); | ||
assertTrue(putRepositoryResponse.isAcknowledged()); | ||
|
||
createIndex("test_index", Settings.EMPTY); |
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.
maybe variablize test_index
so its reused in the next few places
String nodeId = null; | ||
String failure = null; | ||
SnapshotStats stats = null; | ||
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) { |
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.
any reason that you decided to not use an ObjectParser
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.
This comment applies to all of the fromXContent
methods.
// end::snapshots-status-request-snapshots | ||
// tag::snapshots-status-request-ignoreUnavailable | ||
request.ignoreUnavailable(true); // <1> | ||
// end::snapshots-status-request-ignoreUnavailable |
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.
These are not actually rendered since the doc markup does not have them included in it.
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.
LOL disregard clicked the wrong link!
Verified the doc build works. |
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 too
Request request = RequestConverters.snapshotsStatus(snapshotsStatusRequest); | ||
assertThat(request.getEndpoint(), equalTo(endpoint)); | ||
assertThat(request.getMethod(), equalTo(HttpGet.METHOD_NAME)); | ||
assertThat(request.getParameters(), equalTo(expectedParams)); |
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.
test that the body is null?
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.
Addressed in 1a85d5b
throw new ElasticsearchParseException("failed to parse snapshot shards stats, expected number for field [{}]", | ||
currentName); | ||
} | ||
totalShards = parser.intValue(); |
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 it's necessary to throw specific errors for each case here. It is nice to have good error messages, on the other hand these would be thrown anyways (I think) by the parser, maybe a bit more cryptic. But most importantly, is it worth it given that we are parsing our own output. Certainly we are not going to change the type of these fields one way?
throw new ElasticsearchParseException("failed to parse snapshot shards stats, unexpected field [{}]", currentName); | ||
} | ||
} else { | ||
throw new ElasticsearchParseException("failed to parse snapshot shards stats"); |
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 is making the parser strict and I think it breaks forward compatibility. What if one day we add a new array or object at this level? This is also valid for the other parsers added with this PR. Converting them to object parser and providing true as supportsUnknownFields
argument is also a valid fix.
throw new ElasticsearchParseException("failed to parse snapshot status, missing snapshot repository"); | ||
} else if (state == null) { | ||
throw new ElasticsearchParseException("failed to parse snapshot status, missing snapshot state"); | ||
} |
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 don't know if we need this validation, given that we parse our own output and we know that info is going to be there
|
||
@Override | ||
protected boolean supportsUnknownFields() { | ||
return false; |
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.
all these should be true, which tests forward compatibility. they can't be true now because the new parsers are too strict. It may be that there are specific places where injecting random fields is really not possible, such specific locations can be excluded by overriding getRandomFieldsExcludeFilter
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.
Im happy with this now, but I would like @javanna to also review since he had some concerns about compat with the parsing. so +0 from me.
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 and questions, nothing major, thanks @jbaiera !
* @param options the request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized | ||
* @param listener the listener to be notified upon request completion | ||
*/ | ||
public void snapshotsStatusAsync(SnapshotsStatusRequest snapshotsStatusRequest, RequestOptions options, |
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 rename the methods to status ? That's how it's defined in our REST spec.
Request createSnapshot = new Request("put", String.format(Locale.ROOT, "_snapshot/%s/%s", repository, snapshot)); | ||
createSnapshot.addParameter("wait_for_completion", "true"); | ||
createSnapshot.setEntity(new NStringEntity("{\"indices\":\""+index+"\"}", ContentType.APPLICATION_JSON)); |
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.
you can also use setJsonEntity if you wish, that's handy
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.
Oh, neato
// end::snapshots-status-execute | ||
|
||
// tag::snapshots-status-response | ||
List<SnapshotStatus> snapshotStatusesResponse = response.getSnapshots(); |
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 you go a bit deeper here and show users what they can retrieve from the response? We don't need to show everything but I would add what we'd expect users to generally do.
-------------------------------------------------- | ||
include-tagged::{doc-tests}/SnapshotClientDocumentationIT.java[snapshots-status-request-snapshots] | ||
-------------------------------------------------- | ||
<1> The list of snapshot names to check the status of. If this is set, the status for the snapshots |
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.
repository and snapshots are not optional arguments, we will throw exception if they are not provided (see validate method)
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.
Hmm, this doesn't seem to match up with the current API documentation for this end point. If they are left off the API reports on any currently running snapshots. Not sure if that's a problem or a conscious decision to not support that aspect of the request.
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.
seems to be a conscious decision given that we expose the /_snapshot/_status
endpoint alone, which is also documented in our REST spec.
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 pushed d9d35a6 for the required/optional arguments.
try { | ||
state = SnapshotsInProgress.State.valueOf(rawState); | ||
} catch (IllegalArgumentException iae) { | ||
throw new ElasticsearchParseException("failed to parse snapshot status, unknown state value [{}]", iae, rawState); |
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.
is this catch necessary?
|
||
@Override | ||
protected Predicate<String> getRandomFieldsExcludeFilter() { | ||
// Do not place random fields in the root object since its fields correspond to shard names. |
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.
++ thanks for the comment!!
XContentParserUtils.ensureExpectedToken(XContentParser.Token.START_OBJECT, parser.nextToken(), parser::getTokenLocation); | ||
XContentParserUtils.ensureExpectedToken(XContentParser.Token.FIELD_NAME, parser.nextToken(), parser::getTokenLocation); | ||
SnapshotIndexShardStatus status = SnapshotIndexShardStatus.fromXContent(parser, parser.currentName()); | ||
XContentParserUtils.ensureExpectedToken(XContentParser.Token.END_OBJECT, parser.nextToken(), parser::getTokenLocation); |
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 is a bit weird, why does the test need to consume some tokens, rather than the fromXContent itself?
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 big issue here is that the stats objects write their own names out in their toXContent
calls instead of just the object contents. This means that the test code automatically wraps them one layer deeper in an object, which needs to be unpeeled before testing the parsing. My original thought was to avoid changing that much for this PR, but it'll probably be far better to just fix the stats objects write logic.
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 was expecting this and some others below to go away with the stats changes that you made. Is this logic still required?
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 double checked, this is fine in the places where we have it now.
XContentParserUtils.ensureExpectedToken(XContentParser.Token.START_OBJECT, parser.nextToken(), parser::getTokenLocation); | ||
XContentParserUtils.ensureExpectedToken(XContentParser.Token.FIELD_NAME, parser.nextToken(), parser::getTokenLocation); | ||
SnapshotIndexStatus status = SnapshotIndexStatus.fromXContent(parser); | ||
XContentParserUtils.ensureExpectedToken(XContentParser.Token.END_OBJECT, parser.nextToken(), parser::getTokenLocation); |
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.
same comment as above about consuming tokens in the test
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.
As mentioned above, many of these objects are XContentFragments instead of objects. They are automatically wrapped in an object, and need to be unwrapped during the test parsing.
if (stats == null) { | ||
throw new ElasticsearchParseException("could not find stats"); | ||
} | ||
return stats; |
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.
here as well, why do we need this parsing logic in the test? Maybe it has to do with toXContent and fromXContent not matching 100% ?
if (stats == null) { | ||
throw new ElasticsearchParseException("could not find stats"); | ||
} | ||
return stats; |
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.
same comment as above on the parsing logic here.
Convert the stats objects to objects instead of fragments. Simplify unit tests. Add more response uses to the documentation Rename api method to 'status'
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.
LGTM besides the docs argument section that needs updating. Thanks @jbaiera !
I pushed d9d35a6 for the docs argument section. Thanks all! ❤️ |
@jbaiera dont forget to check the checkbox on the meta issue once you are backported |
* master: [TEST] Mute SlackMessageTests.testTemplateRender Docs: Explain closing the high level client [ML] Re-enable memory limit integration tests (#31328) [test] disable packaging tests for suse boxes Add nio transport to security plugin (#31942) XContentTests : Insert random fields at random positions (#30867) Force execution of fetch tasks (#31974) Fix unreachable error condition in AmazonS3Fixture (#32005) Tests: Fix SearchFieldsIT.testDocValueFields (#31995) Add Expected Reciprocal Rank metric (#31891) [ML] Get ForecastRequestStats doc in RestoreModelSnapshotIT (#31973) SQL: Add support for single parameter text manipulating functions (#31874) [ML] Ensure immutability of MlMetadata (#31957) Tests: Mute SearchFieldsIT.testDocValueFields() muted tests due to #31940 Work around reported problem in eclipse (#31960) Move build integration tests out of :buildSrc project (#31961) Tests: Remove use of joda time in some tests (#31922) [Test] Reactive 3rd party tests on CI (#31919) SQL: Support for escape sequences (#31884) SQL: HAVING clause should accept only aggregates (#31872) Docs: fix typo in datehistogram (#31972) Switch url repository rest tests to new style requests (#31944) Switch reindex tests to new style requests (#31941) Docs: Added note about cloud service to installation and getting started [DOCS] Removes alternative docker pull example (#31934) Add Snapshots Status API to High Level Rest Client (#31515) ingest: date_index_name processor template resolution (#31841) Test: fix null failure in watcher test (#31968) Switch test framework to new style requests (#31939) Switch low level rest tests to new style Requests (#31938) Switch high level rest tests to new style requests (#31937) [ML] Mute test failing due to Java 11 date time format parsing bug (#31899) [TEST] Mute SlackMessageTests.testTemplateRender Fix assertIngestDocument wrongfully passing (#31913) Remove unused reference to filePermissionsCache (#31923) rolling upgrade should use a replica to prevent relocations while running a scroll HLREST: Bundle the x-pack protocol project (#31904) Increase logging level for testStressMaybeFlush Added lenient flag for synonym token filter (#31484) [X-Pack] Beats centralized management: security role + licensing (#30520) HLRest: Move xPackInfo() to xPack().info() (#31905) Docs: add security delete role to api call table (#31907) [test] port archive distribution packaging tests (#31314) Watcher: Slack message empty text (#31596) [ML] Mute failing DetectionRulesIT.testCondition() test Fix broken NaN check in MovingFunctions#stdDev() (#31888) Date: Add DateFormatters class that uses java.time (#31856) [ML] Switch native QA tests to a 3 node cluster (#31757) Change trappy float comparison (#31889) Fix building AD URL from domain name (#31849) Add opaque_id to audit logging (#31878) re-enable backcompat tests add support for is_write_index in put-alias body parsing (#31674) Improve release notes script (#31833) [DOCS] Fix broken link in painless example Handle missing values in painless (#30975) Remove the ability to index or query context suggestions without context (#31007) Ingest: Enable Templated Fieldnames in Rename (#31690) [Docs] Fix typo in the Rollup API Quick Reference (#31855) Ingest: Add ignore_missing option to RemoveProc (#31693) Add template config for Beat state to X-Pack Monitoring (#31809) Watcher: Add ssl.trust email account setting (#31684) Remove link to oss-MSI (#31844) Painless: Restructure Definition/Whitelist (#31879) HLREST: Add x-pack-info API (#31870)
This PR adds the Snapshots Status API to the Snapshot Client, as well as additional documentation for the status api.
This PR adds the Snapshots Status API to the High Level Rest Client. There are
a few points that are strange, mainly that some of the response objects serialize
themselves differently across XContent and regular Writables.
Relates #27205