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 get field mappings to High Level REST API Client #31423

Merged

Conversation

vladimirdolzhenko
Copy link
Contributor

Add get field mappings to High Level REST API Client
Relates to #27205

@elasticmachine
Copy link
Collaborator

Pinging @elastic/es-core-infra

@javanna javanna removed their request for review June 19, 2018 09:59
@javanna
Copy link
Member

javanna commented Jun 19, 2018

@nik9000 @hub-cap @cbuescher does either of you have time to review this one?

@nik9000
Copy link
Member

nik9000 commented Jun 19, 2018

Will look.

@@ -908,6 +923,13 @@ static String endpoint(String[] indices, String endpoint, String[] suffixes) {
.addCommaSeparatedPathParts(suffixes).build();
}

static String endpoint(String[] indices, String endpoint, String[] suffixes, String extraEndpoint, String[] extraSuffixes) {
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 I'd make just call the EndpointBuilder directly rather than making a method. Unless you know that you are going to add a few more uses of the method.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

makes sense. thanks

getFieldMappingsRequest.types((String[]) null);
}

String[] fields = new String[randomIntBetween(1, 5)];
Copy link
Member

Choose a reason for hiding this comment

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

You support leaving these null to, right? Maybe add a randomization option for that.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

agreed.

@@ -253,6 +255,10 @@ public XContentBuilder startObject() throws IOException {
return this;
}

public XContentBuilder startObject(ParseField field) throws IOException {
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 not sure we should add this one. Maybe. But I think it is worth its own little PR if we do.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

indeed.

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

* @return the response
* @throws IOException in case there is a problem sending the request or parsing back the response
*/
public GetFieldMappingsResponse getFieldMappings(GetFieldMappingsRequest getFieldMappingsRequest,
Copy link
Member

Choose a reason for hiding this comment

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

it should be singular getFieldMapping. that's what we have in the SPEC

Copy link
Contributor Author

@vladimirdolzhenko vladimirdolzhenko Jun 19, 2018

Choose a reason for hiding this comment

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

@javanna there is inconsistency with a class name GetFieldMappingsResponse

Copy link
Member

Choose a reason for hiding this comment

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

there are plenty of these, for the method names we follow the SPEC regardless of class names. If we could we would change the class names but we are trying to make it easy for people to migrate off of the transport client so we don't do that.

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 see the difficulties - sounds ok to me

--------------------------------------------------
<1> Options for expanding indices names

[[java-rest-high-get-field-mappings-sync]]
Copy link
Member

Choose a reason for hiding this comment

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

aren't we missing a couple of supported parameters here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

good spotted - I found only one - local, pls let me know if anything else you have in mind


@Override
protected Predicate<String> getRandomFieldsExcludeFilter() {
return s -> true;
Copy link
Member

Choose a reason for hiding this comment

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

what is the value of supporting unknown fields if the exclude filter always returns true?

Copy link
Member

Choose a reason for hiding this comment

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

aren't there parts of the response where we could inject random 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.

in fact not so much - but there are couple, fixed

@vladimirdolzhenko
Copy link
Contributor Author

@javanna could you pls have another look into this ?

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, LGTM otherwise


setRandomIndicesOptions(getFieldMappingsRequest::indicesOptions, getFieldMappingsRequest::indicesOptions, expectedParams);

if (randomBoolean()) {
Copy link
Member

Choose a reason for hiding this comment

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

you can use setRandomLocal

Copy link
Contributor Author

Choose a reason for hiding this comment

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

nope, you can't - setRandomLocal requires MasterNodeReadRequest while GetFieldMappingsRequest does not extend it

Copy link
Member

Choose a reason for hiding this comment

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

oh right we could make the comment accept a consumer instead then, we did it in other places, up to you on whether it's worthwhile or not.

final Map<String, Object> source = metaData1.sourceAsMap();

assertThat(fullName, equalTo("message"));
assertThat(source, equalTo(Collections.singletonMap("message", Collections.singletonMap("type", "text"))));
Copy link
Member

Choose a reason for hiding this comment

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

do we need these assertions here? given that this test is added to test the docs snippets, I would avoid testing the functionality itself.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

agree

Copy link
Member

Choose a reason for hiding this comment

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

this is still here?

final Object o = ((Map) value).get(MAPPINGS.getPreferredName());
if (!(o instanceof Map)) {
throw new ParsingException(parser.getTokenLocation(), "Nested " + MAPPINGS.getPreferredName() + " is not found");
}
Copy link
Member

Choose a reason for hiding this comment

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

is it necessary to parse everything into a map in the first place? At some point later on we do need a map, but I wonder if we can postpone calling parser.map till then.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

it's quite good point, will try to do that

// otherwise random field could be evaluated as index name or type name
return s -> {
final int c = s.length() > 0 ? charCount(s, '.') : -1;
return c != 0 && c != 3;};
Copy link
Member

Choose a reason for hiding this comment

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

maybe a regex would be more readable here :)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@vladimirdolzhenko
Copy link
Contributor Author

test this please

@vladimirdolzhenko
Copy link
Contributor Author

@javanna last glance pls

final String fullName = (String) map3.get(FieldMappingMetaData.FULL_NAME.getPreferredName());
final XContentBuilder jsonBuilder = jsonBuilder();
final Map<String, ?> values = (Map<String, ?>) map3.get(FieldMappingMetaData.MAPPING.getPreferredName());
jsonBuilder.map(values);
Copy link
Member

Choose a reason for hiding this comment

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

here you may be able to use copyCurrentStructure

Copy link
Contributor Author

Choose a reason for hiding this comment

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

unfortunately - we already call parser.map() - therefore copyCurrentStructure is not feasible here

Copy link
Member

Choose a reason for hiding this comment

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

makes sense

Copy link
Member

Choose a reason for hiding this comment

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

So, why call map in the first place? It feels like maybe we should use the pull parser a bit more, build the map as we go.

@@ -93,9 +143,34 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws
return builder;
}

private static class Builder {
Copy link
Member

Choose a reason for hiding this comment

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

do we need this class given that it has a single member? Can't we use directly the map member where needed?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

it's doable! thanks

ensureExpectedToken(XContentParser.Token.START_OBJECT, parser.nextToken(), parser::getTokenLocation);

final Map<String, Map<String, Map<String, FieldMappingMetaData>>> mappings = new HashMap<>();
final ObjectParser objectParser = createParser(mappings);
Copy link
Member

Choose a reason for hiding this comment

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

It is much more normal to create the objectParser statically. I see that you did it this way so that you could collect the results into something, but that isn't really what object parser is for. I mean, you can do it by passing the mappings map as the context to the parse method and throwing out the return value, but that is weird. Why not have the ObjectParser return the typeMappings?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

even better - agree

final String fullName = (String) map3.get(FieldMappingMetaData.FULL_NAME.getPreferredName());
final XContentBuilder jsonBuilder = jsonBuilder();
final Map<String, ?> values = (Map<String, ?>) map3.get(FieldMappingMetaData.MAPPING.getPreferredName());
jsonBuilder.map(values);
Copy link
Member

Choose a reason for hiding this comment

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

So, why call map in the first place? It feels like maybe we should use the pull parser a bit more, build the map as we go.

@vladimirdolzhenko
Copy link
Contributor Author

thanks @nik9000 for suggestion - I did another try - indeed it looks way better

final Map<String, FieldMappingMetaData> typeMapping = new HashMap<>();
typeMappings.put(typeName, typeMapping);

if (p.nextToken() == XContentParser.Token.START_OBJECT) {
Copy link
Member

Choose a reason for hiding this comment

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

So, if nextToken is START_ARRAY I think this falls over. I think the outer while loop terminates in a weird spot. I think we should skip children in that case.

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

@vladimirdolzhenko
Copy link
Contributor Author

thanks @nik9000 and @javanna for the review 👍

@vladimirdolzhenko vladimirdolzhenko merged commit b7ef75f into elastic:master Jun 23, 2018
@vladimirdolzhenko vladimirdolzhenko deleted the get_field_mappings_hlrestapi branch June 23, 2018 07:39
dnhatn added a commit that referenced this pull request Jun 23, 2018
* master:
  Add get field mappings to High Level REST API Client (#31423)
  [DOCS] Updates Watcher examples for code testing (#31152)
  TEST: Add bwc recovery tests with synced-flush index
  [DOCS] Move sql to docs (#31474)
  [DOCS] Move monitoring to docs folder (#31477)
  Core: Combine doExecute methods in TransportAction (#31517)
  IndexShard should not return null stats (#31528)
  fix repository update with the same settings but different type (#31458)
  Fix Mockito trying to mock IOException that isn't thrown by method (#31433) (#31527)
  Node selector per client rather than per request (#31471)
  Core: Combine messageRecieved methods in TransportRequestHandler (#31519)
  Upgrade to Lucene 7.4.0. (#31529)
  [ML] Add ML filter update API (#31437)
  Allow multiple unicast host providers (#31509)
  Avoid deprecation warning when running the ML datafeed extractor. (#31463)
  REST high-level client: add simulate pipeline API (#31158)
  Get Mapping API to honour allow_no_indices and ignore_unavailable (#31507)
  [PkiRealm] Invalidate cache on role mappings change (#31510)
  [Security] Check auth scheme case insensitively (#31490)
  In NumberFieldType equals and hashCode, make sure that NumberType is taken into account. (#31514)
  [DOCS] Fix REST tests in SQL docs
  [DOCS] Add code snippet testing in more ML APIs (#31339)
  Core: Remove ThreadPool from base TransportAction (#31492)
  [DOCS] Remove fixed file from build.gradle
  Rename createNewTranslog to fileBasedRecovery (#31508)
  Test: Skip assertion on windows
  [DOCS] Creates field and document level security overview (#30937)
  [DOCS] Significantly improve SQL docs
  [DOCS] Move migration APIs to docs (#31473)
  Core: Convert TransportAction.execute uses to client calls (#31487)
  Return transport addresses from UnicastHostsProvider (#31426)
  Ensure local addresses aren't null (#31440)
  Remove unused generic type for client execute method (#31444)
  Introduce http and tcp server channels (#31446)
colings86 pushed a commit that referenced this pull request Jun 25, 2018
Add get field mappings to High Level REST API Client
Relates to #27205
jasontedor added a commit to hub-cap/elasticsearch that referenced this pull request Jun 25, 2018
* elastic/master: (92 commits)
  Reduce number of raw types warnings (elastic#31523)
  Migrate scripted metric aggregation scripts to ScriptContext design (elastic#30111)
  turn GetFieldMappingsResponse to ToXContentObject (elastic#31544)
  Close xcontent parsers (partial) (elastic#31513)
  Ingest Attachment: Upgrade Tika to 1.18 (elastic#31252)
  TEST: Correct the assertion arguments order (elastic#31540)
  Add get field mappings to High Level REST API Client (elastic#31423)
  [DOCS] Updates Watcher examples for code testing (elastic#31152)
  TEST: Add bwc recovery tests with synced-flush index
  [DOCS] Move sql to docs (elastic#31474)
  [DOCS] Move monitoring to docs folder (elastic#31477)
  Core: Combine doExecute methods in TransportAction (elastic#31517)
  IndexShard should not return null stats (elastic#31528)
  fix repository update with the same settings but different type (elastic#31458)
  Fix Mockito trying to mock IOException that isn't thrown by method (elastic#31433) (elastic#31527)
  Node selector per client rather than per request (elastic#31471)
  Core: Combine messageRecieved methods in TransportRequestHandler (elastic#31519)
  Upgrade to Lucene 7.4.0. (elastic#31529)
  [ML] Add ML filter update API (elastic#31437)
  Allow multiple unicast host providers (elastic#31509)
  ...
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.

5 participants