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

Add typless client side GetIndexRequest calls and response class #37778

Merged
merged 18 commits into from
Feb 5, 2019

Conversation

cbuescher
Copy link
Member

@cbuescher cbuescher commented Jan 23, 2019

The HLRC client currently uses org.elasticsearch.action.admin.indices.get.GetIndexRequest
and org.elasticsearch.action.admin.indices.get.GetIndexResponse in its get index calls. Both request and
response are designed for the typed APIs, including some return types e.g. for getMappings() which in
the maps it returns still use a level including the type name.
In order to change this without breaking existing users of the HLRC API, this PR introduces two new request
and response objects in the org.elasticsearch.client.indices client package. These are used by the
IndicesClient#get and IndicesClient#exists calls now by default and support the type-less API. The old request
and response objects are still kept for use in similarly named, but deprecated methods.
The newly introduced client side classes are simplified versions of the server side request/response classes since
they don't need to support wire serialization, and only the response needs fromXContent parsing (but no
xContent-serialization, since this is the responsibility of the server-side class).
Also changing the return type of GetIndexResponse#getMapping to
ImmutableOpenMap<String, MappingMetaData> getMappings(), while it previously was returning another map
keyed by the type-name.

@elasticmachine
Copy link
Collaborator

Pinging @elastic/es-search

@elasticmachine
Copy link
Collaborator

Pinging @elastic/es-core-features

@cbuescher
Copy link
Member Author

@elasticmachine run elasticsearch-ci/1

@@ -61,7 +60,7 @@
private ImmutableOpenMap<String, Settings> defaultSettings = ImmutableOpenMap.of();
private String[] indices;

GetIndexResponse(String[] indices,
public GetIndexResponse(String[] indices,
Copy link
Member Author

Choose a reason for hiding this comment

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

Needed this access for tests.

@cbuescher
Copy link
Member Author

@jtibshirani thanks for the reviews, I pushed a round of changes hopefully adressing your comments.

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.

Sorry for the confusion in my previous review, this is now looking good to me from the types deprecation side. I just left a couple questions around tests.

*
* TODO: ideally we would create a random instance of the client side response that contains the rendering code
* write it to xContent, parse it back and compare the results
* this currently would mean we would need test dependencies to server:test
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 not sure I really understand this TODO. For what purpose would we need a dependency on server:test?

Copy link
Contributor

Choose a reason for hiding this comment

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

An update: as I was working on the same refactor for 'get mappings', I found it nice to use an xContentTester. I ended up creating a method GetMappingsResponseTests#toXContent that converts an HLRC GetMappingsResponse to a server-side one, then calls toXContent on that. Here's the test class in case you'd like to take a look: https://github.com/elastic/elasticsearch/pull/37796/files#diff-f66406b858061334c3239c8d2148b2caR41

Copy link
Member Author

Choose a reason for hiding this comment

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

Thanks, I'll take a look...

Copy link
Member Author

Choose a reason for hiding this comment

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

I see what you did there, I think its basically the same as my approach, although I have to say I really dislike using xContentTester for all the fuss around having to set up functions for everything. If you've used it several times it becomes clearer what it does, but its over-engineered from my point of view. I can change to using it if you really like though.
The main point though is to get an xContent rendering of the server side response. While you are generating a random instance of the client-side class, then convert it to server-side to call its xContent, I copied the code to create a randomized server-side response directly from org.elasticsearch.action.admin.indices.get.GetIndexResponseTests. I think it boild down to the same disadvantage, namely having to copy randomization code (which you also seem to have copied over, at least partially). By my comment I mean it would be great if we could call org.elasticsearch.action.admin.indices.get.GetIndexResponseTests#createTestInstance in the client-side test to be sure we get a "real" server side response with all its randomization variants, and call its "real" toXContent, because that is what the client is going to have to parse. In order to avoid code changing on the server side unnoticed it would be good to actually use that code, not rely on the copy being up to date which we have to do if we copy. Does this make sense?

The problem I'm running into here is that the client project can see org.elasticsearch.action.admin.indices.get.GetIndexResponse but not org.elasticsearch.action.admin.indices.get.GetIndexResponseTests. Maybe we could have a test dependency for this? But @hub-cap might know. We can probably do this in a follow up though if people think its useful to have.

Copy link
Contributor

Choose a reason for hiding this comment

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

Thanks, I understand your comment now! Doing a bit more digging, I see AbstractHlrcXContentTestCase, which I think was designed for this situation. This sort of class tests both server serialization and HLRC serialization at the same time, which means there is a single place to generate random server objects. HLRC serialization is tested by generating a random server object, calling toXContent on it, and parsing it back as an client object. However, this class currently lives in the x-pack directory, which doesn't seem like a natural place to move GetMappingsResponseTests, GetIndexResponseTests, etc.

A proposal for what to do with our two open PRs:

  • We can plan to follow-up with @hub-cap to discuss where to move AbstractHlrcXContentTestCase, then refactor Get*Tests to all extend this class.
  • For now we can generate random server objects (as you do in this PR). I'll switch my PR to do that instead of generating a client-side one, so we are closer to modeling what actually happens during an HLRC call.
  • I would prefer us to use xContentTester, because although it's a bit overkill, it is used extensively and I think being consistent with the test framework leads to overall less confusion than being inconsistent but slightly simpler in one or two tests.

Copy link
Contributor

@jtibshirani jtibshirani Jan 28, 2019

Choose a reason for hiding this comment

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

An update: after a more in-depth discussion with @hub-cap, these are his preferences for how to test these Get*Response classes that contain mappings:

  • He agrees we should use an xContentTester object, to be consistent with the many other tests that have been written in this style.
  • We should test serialization by first generating a random client instance, then converting it to a server object and calling toXContent, then finally parsing it back as a client object using fromXContent. Here is an example of this approach: https://github.com/elastic/elasticsearch/pull/37796/files#diff-f66406b858061334c3239c8d2148b2caR41. This approach is more straightforward and lets us test equality on the client objects.

I updated my 'get mappings' PR to be in line with the two points above, and we've made sure the tests for 'get index template' do the same. It would be great to rework this test to also follow this approach before merging, so that all of our tests are consistent.

I share your concern around duplicating the logic to generate a random instance, and having to make sure that all updates to the server-side test are also reflected in the client-side. We can plan to follow-up with a discussion on this point (that may include a discussion of AbstractHlrcXContentTestCase, as mentioned above).

@cbuescher
Copy link
Member Author

@jtibshirani thanks, I adressed one of your comments, left a response to the other. Let me know if we should discuss this again later.

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.

I left one comment about refactoring the test to use xContent, to be consistent with our overall testing approach. However this is looking very nice and I'm approving now so as not to hold up merging after the test changes.

@cbuescher
Copy link
Member Author

not to hold up merging after the test changes

@jtibshirani sorry, I'm not sure if this refers to changes you want me to still make or changes we can do as a follow re our discussion in #37778 (comment). Reading that comment I don't see any changes needed for this PR, but will wait for confirmation just before merging.

@cbuescher
Copy link
Member Author

@jtibshirani I updated the test in 6a8a8a9. I have to admit I'm not very happy with the way we test this, but I tried following your suggestions from #37778 (comment) to get this PR merged. I think we should iterate on the testing later on.
Furthermore I simplified most getters for the new client-side GetIndexResponse to return plain Maps instead of the ImmutableOpenMaps that the server side response returns. I saw e.g the new client side GetMappingsResponse does the same so I adapted this approach. Let me know if this works for you.

@jtibshirani
Copy link
Contributor

Thank you @cbuescher for making these updates, they look good to me. Sounds good about iterating on the approach to testing -- at least the strategy is consistent now across the different HLRC classes, which will make it easier to do a follow-up refactor.

@cbuescher cbuescher merged commit d255303 into elastic:master Feb 5, 2019
jasontedor added a commit to jasontedor/elasticsearch that referenced this pull request Feb 5, 2019
…-lease-expiration

* elastic/master: (24 commits)
  Add support for API keys to access Elasticsearch (elastic#38291)
  Add typless client side GetIndexRequest calls and response class (elastic#37778)
  Limit token expiry to 1 hour maximum (elastic#38244)
  add docs saying mixed-cluster ILM is not supported (elastic#37954)
  Skip unsupported languages for tests (elastic#38328)
  Deprecate `_type` in simulate pipeline requests (elastic#37949)
  Mute testCannotShrinkLeaderIndex (elastic#38374)
  Tighten mapping syncing in ccr remote restore (elastic#38071)
  Add test for `PutFollowAction` on a closed index (elastic#38236)
  Fix SSLContext pinning to TLSV1.2 in reload tests (elastic#38341)
  Mute RareClusterStateIT.testDelayedMappingPropagationOnReplica (elastic#38357)
  Deprecate types in rollover index API (elastic#38039)
  Types removal - fix FullClusterRestartIT warning expectations (elastic#38310)
  Fix ILM explain response to allow unknown fields (elastic#38054)
  Mute testFollowIndexAndCloseNode (elastic#38360)
  Docs: Drop inline callout from scroll example (elastic#38340)
  Deprecate HLRC security methods (elastic#37883)
  Remove types from Monitoring plugin "backend" code (elastic#37745)
  Add Composite to AggregationBuilders (elastic#38207)
  Clarify slow cluster-state log messages (elastic#38302)
  ...
cbuescher pushed a commit to cbuescher/elasticsearch that referenced this pull request Feb 5, 2019
…stic#37778)

The HLRC client currently uses `org.elasticsearch.action.admin.indices.get.GetIndexRequest`
and `org.elasticsearch.action.admin.indices.get.GetIndexResponse` in its get index
calls. Both request and response are designed for the typed APIs, including some
return types e.g. for `getMappings()` which in the maps it returns still use a
level including the type name.  In order to change this without breaking
existing users of the HLRC API, this PR introduces two new request and response
objects in the `org.elasticsearch.client.indices` client package. These are used
by the IndicesClient#get and IndicesClient#exists calls now by default and
support the type-less API. The old request and response objects are still kept
for use in similarly named, but deprecated methods.

The newly introduced client side classes are simplified versions of the server
side request/response classes since they don't need to support wire
serialization, and only the response needs fromXContent parsing (but no
xContent-serialization, since this is the responsibility of the server-side
class).  Also changing the return type of `GetIndexResponse#getMapping` to
`Map<String, MappingMetaData> getMappings()`, while it previously was returning
another map keyed by the type-name. Similar getters return simple Maps instead
of the ImmutableOpenMaps that the server side response objects return.
cbuescher pushed a commit to cbuescher/elasticsearch that referenced this pull request Feb 5, 2019
…stic#37778)

The HLRC client currently uses `org.elasticsearch.action.admin.indices.get.GetIndexRequest`
and `org.elasticsearch.action.admin.indices.get.GetIndexResponse` in its get index
calls. Both request and response are designed for the typed APIs, including some
return types e.g. for `getMappings()` which in the maps it returns still use a
level including the type name.  In order to change this without breaking
existing users of the HLRC API, this PR introduces two new request and response
objects in the `org.elasticsearch.client.indices` client package. These are used
by the IndicesClient#get and IndicesClient#exists calls now by default and
support the type-less API. The old request and response objects are still kept
for use in similarly named, but deprecated methods.

The newly introduced client side classes are simplified versions of the server
side request/response classes since they don't need to support wire
serialization, and only the response needs fromXContent parsing (but no
xContent-serialization, since this is the responsibility of the server-side
class).  Also changing the return type of `GetIndexResponse#getMapping` to
`Map<String, MappingMetaData> getMappings()`, while it previously was returning
another map keyed by the type-name. Similar getters return simple Maps instead
of the ImmutableOpenMaps that the server side response objects return.
cbuescher pushed a commit that referenced this pull request Feb 5, 2019
)

The HLRC client currently uses `org.elasticsearch.action.admin.indices.get.GetIndexRequest`
and `org.elasticsearch.action.admin.indices.get.GetIndexResponse` in its get index
calls. Both request and response are designed for the typed APIs, including some
return types e.g. for `getMappings()` which in the maps it returns still use a
level including the type name.  In order to change this without breaking
existing users of the HLRC API, this PR introduces two new request and response
objects in the `org.elasticsearch.client.indices` client package. These are used
by the IndicesClient#get and IndicesClient#exists calls now by default and
support the type-less API. The old request and response objects are still kept
for use in similarly named, but deprecated methods.

The newly introduced client side classes are simplified versions of the server
side request/response classes since they don't need to support wire
serialization, and only the response needs fromXContent parsing (but no
xContent-serialization, since this is the responsibility of the server-side
class).  Also changing the return type of `GetIndexResponse#getMapping` to
`Map<String, MappingMetaData> getMappings()`, while it previously was returning
another map keyed by the type-name. Similar getters return simple Maps instead
of the ImmutableOpenMaps that the server side response objects return.

Backport for #37778
Relates to #35190
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
>refactoring :Search Foundations/Mapping Index mappings, including merging and defining field types v7.0.0-beta1
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants