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

HLRC: Add get watch API #35531

Merged
merged 14 commits into from Nov 30, 2018
Merged

HLRC: Add get watch API #35531

merged 14 commits into from Nov 30, 2018

Conversation

jimczi
Copy link
Contributor

@jimczi jimczi commented Nov 14, 2018

This changes adds the support for the get watch API in the high level rest client.

Relates #29827

This changes adds the support for the get watch API in the high level rest client.
@elasticmachine
Copy link
Collaborator

Pinging @elastic/es-core-infra

@jimczi
Copy link
Contributor Author

jimczi commented Nov 16, 2018

run gradle build tests

Copy link
Contributor

@jtibshirani jtibshirani left a comment

Choose a reason for hiding this comment

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

It looks good to me overall, just left a few comments.

.addPathPart(getWatchRequest.getId())
.build();

Request request = new Request(HttpGet.METHOD_NAME, endpoint);
Copy link
Contributor

Choose a reason for hiding this comment

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

Super small comment: can just be return new Request(...);.

private final BytesReference source;
private final XContentType xContentType;

public GetWatchResponse(String id) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Small comment: it would be nice to add a comment to this constructor explaining that it is for a 'missing watch', as opposed to the one below.

return source;
}

public XContentType getContentType() {
Copy link
Contributor

Choose a reason for hiding this comment

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

I wonder if it would make sense to always return JSON content as we do in GetFieldMappingsResponse. In that class, it also looks like we have a sourceAsMap() for convenience.

try (XContentBuilder builder = XContentBuilder.builder(parser.contentType().xContent())) {
builder.copyCurrentStructure(parser);
BytesReference ref = BytesReference.bytes(builder);
return new XContentSource(ref, parser.contentType());
Copy link
Contributor

Choose a reason for hiding this comment

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

Could we return the builder here instead of creating a new class XContentSource?

@@ -0,0 +1,56 @@
[[java-rest-high-x-pack-watcher-get-watch]]
=== Get Watch API
Copy link
Contributor

Choose a reason for hiding this comment

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

There were a couple changes made to the HLRC docs set-up:

  • It's now common to define and use variables like :api: instead of hard-coding names.
  • With these variables defined, you can use include::../execution.asciidoc[] to automatically include the 'asynchronous execution' section.

Here's an example that has been updated to the new format: https://raw.githubusercontent.com/elastic/elasticsearch/master/docs/java-rest/high-level/watcher/ack-watch.asciidoc

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 adapted the docs


import static org.elasticsearch.index.mapper.DateFieldMapper.DEFAULT_DATE_TIME_FORMATTER;

public class GetWatchResponseTests extends AbstractXContentTestCase<GetWatchResponseTests.ResponseWrapper> {
Copy link
Contributor

Choose a reason for hiding this comment

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

I think the new standard is to extend AbstractHlrcStreamableXContentTestCase. @vladimirdolzhenko introduced this testing option, and had linked to 'put license' as an example: https://github.com/elastic/elasticsearch/pull/34547/files#diff-1ed9d64125ce162773bfc2a4b02f5783

Copy link
Contributor Author

Choose a reason for hiding this comment

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

for this to work we'd need to implement toXContent on the HLRC GetWatchResponse and by extension to WatchStatus. I can add it but I thought that we've decided not to add this if it's solely used in tests ?

Copy link
Contributor

Choose a reason for hiding this comment

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

This new testing approach wasn't available when we had that discussion (which I think was part of the 'ack watch' PR). The test works by depending on both the HLRC and transport classes. I think it creates random instances of the transport GetWatchResponse, calls toXContent on them, and then checks that the HLRC GetWatchResponse can correctly parse the output. It shouldn't be necessary to implement toXContent on the HLRC objects.

One slight issue is that the transport GetWatchResponse doesn't currently implement the interface ToXContent. But I think this wouldn't be too hard to refactor, since most of the complexity is in WatchStatus, which does implement ToXContentObject.

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 don't know why I was under the impression that fromXContent was also needed on the transport GetWatchResponse to implement AbstractHlrcStreamableXContentTestCase but that's not the case. I switched to the new testing approach in 22c0c7a, thanks.

@jimczi
Copy link
Contributor Author

jimczi commented Nov 28, 2018

@jtibshirani I think I addressed all your comments. Can you take another look ?

Copy link
Contributor

@jtibshirani jtibshirani left a comment

Choose a reason for hiding this comment

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

Thanks @jimczi, I had a few more questions:

  • I wonder if the choice to only return the watch in JSON format led to more complications than it's worth. To me it seems cleaner to stick with your original approach. Sorry about that, I didn't foresee how it would interact with the new testing strategy, where both the transport + HLRC objects are used.
  • Why did we add a headers field to the HLRC WatchStatus (and make some other changes involving headers)?

* Returns the source as a map
*/
public Map<String, Object> getSourceAsMap() throws IOException {
if (sourceAsMap == null && source != null) {
Copy link
Contributor

Choose a reason for hiding this comment

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

A couple questions:

  • Sorry if I'm missing something, but why don't we use XContentHelper#convertToMap here?
  • For me it'd be better to avoid introducing the cached sourceAsMap variable, and just do the conversion every time as we do in GetFieldMappingsResponse and IndexRequest. That way this object can remain immutable, and we don't need to reason about thread safety at all.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

+1, I changed it to return XContentHelper#convertToMap all the time


@Override
protected boolean supportsUnknownFields() {
return false;
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm wondering why this is false. Enabling this is useful, as it helps test that clients can handle unforeseen changes in the responses. Should we instead be using randomFieldsExcludeFilter to only omit watch, as we do for shuffled fields?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Right thanks

return new GetWatchResponse(id, version, status, new XContentSource(source, XContentType.JSON));
}

private static BytesReference emptyWatch() {
Copy link
Contributor

Choose a reason for hiding this comment

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

It would be nice to return a simple, non-empty structure here so that we test that aspect of the response parsing.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

++

Copy link
Contributor Author

@jimczi jimczi left a comment

Choose a reason for hiding this comment

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

@jtibshirani I pushed more changes to address your comments. I reintroduced the xContentType and finished the support for headers in the response. Can you take another look ?

Copy link
Contributor

@jtibshirani jtibshirani left a comment

Choose a reason for hiding this comment

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

It looks good to me! Thanks for the fixes to WatchStatus as well.

@jimczi jimczi merged commit 5c7b2c5 into elastic:master Nov 30, 2018
@jimczi jimczi deleted the hlrc_get_watch branch November 30, 2018 10:02
jimczi added a commit that referenced this pull request Nov 30, 2018
This changes adds the support for the get watch API in the high level rest client.
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.

None yet

4 participants