From acf286f9106e14bdf81837c1694703fa1189aba3 Mon Sep 17 00:00:00 2001 From: Julie Tibshirani Date: Wed, 23 Jan 2019 16:29:11 -0800 Subject: [PATCH 1/9] Support both typed and typeless 'get mapping' requests in the HLRC. --- .../elasticsearch/client/IndicesClient.java | 78 ++++++++++-- .../client/IndicesRequestConverters.java | 18 ++- .../client/indices/GetMappingsRequest.java | 75 ++++++++++++ .../client/indices/GetMappingsResponse.java | 85 +++++++++++++ .../elasticsearch/client/IndicesClientIT.java | 54 +++++++- .../client/IndicesRequestConvertersTests.java | 38 +++++- .../IndicesClientDocumentationIT.java | 19 ++- .../GetFieldMappingsResponseTests.java | 7 +- .../indices/GetMappingsResponseTests.java | 115 ++++++++++++++++++ .../high-level/indices/get_mappings.asciidoc | 7 +- .../mapping/get/GetMappingsResponse.java | 21 ++-- .../admin/indices/RestGetMappingAction.java | 4 +- .../get/GetFieldMappingsResponseTests.java | 4 +- .../mapping/get/GetMappingsResponseTests.java | 70 ++--------- 14 files changed, 480 insertions(+), 115 deletions(-) create mode 100644 client/rest-high-level/src/main/java/org/elasticsearch/client/indices/GetMappingsRequest.java create mode 100644 client/rest-high-level/src/main/java/org/elasticsearch/client/indices/GetMappingsResponse.java create mode 100644 client/rest-high-level/src/test/java/org/elasticsearch/client/indices/GetMappingsResponseTests.java diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/IndicesClient.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/IndicesClient.java index bed7d30242801..212403cd6f300 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/IndicesClient.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/IndicesClient.java @@ -39,8 +39,6 @@ import org.elasticsearch.action.admin.indices.get.GetIndexResponse; import org.elasticsearch.client.indices.GetFieldMappingsRequest; import org.elasticsearch.client.indices.GetFieldMappingsResponse; -import org.elasticsearch.action.admin.indices.mapping.get.GetMappingsRequest; -import org.elasticsearch.action.admin.indices.mapping.get.GetMappingsResponse; import org.elasticsearch.action.admin.indices.open.OpenIndexRequest; import org.elasticsearch.action.admin.indices.open.OpenIndexResponse; import org.elasticsearch.action.admin.indices.refresh.RefreshRequest; @@ -61,6 +59,8 @@ import org.elasticsearch.client.core.ShardsAcknowledgedResponse; import org.elasticsearch.client.indices.FreezeIndexRequest; import org.elasticsearch.client.indices.GetIndexTemplatesRequest; +import org.elasticsearch.client.indices.GetMappingsRequest; +import org.elasticsearch.client.indices.GetMappingsResponse; import org.elasticsearch.client.indices.IndexTemplatesExistRequest; import org.elasticsearch.client.indices.PutMappingRequest; import org.elasticsearch.client.indices.UnfreezeIndexRequest; @@ -215,8 +215,11 @@ public void putMappingAsync(org.elasticsearch.action.admin.indices.mapping.put.P * @throws IOException in case there is a problem sending the request or parsing back the response */ public GetMappingsResponse getMapping(GetMappingsRequest getMappingsRequest, RequestOptions options) throws IOException { - return restHighLevelClient.performRequestAndParseEntity(getMappingsRequest, IndicesRequestConverters::getMappings, options, - GetMappingsResponse::fromXContent, emptySet()); + return restHighLevelClient.performRequestAndParseEntity(getMappingsRequest, + IndicesRequestConverters::getMappings, + options, + GetMappingsResponse::fromXContent, + emptySet()); } /** @@ -229,8 +232,60 @@ public GetMappingsResponse getMapping(GetMappingsRequest getMappingsRequest, Req */ public void getMappingAsync(GetMappingsRequest getMappingsRequest, RequestOptions options, ActionListener listener) { - restHighLevelClient.performRequestAsyncAndParseEntity(getMappingsRequest, IndicesRequestConverters::getMappings, options, - GetMappingsResponse::fromXContent, listener, emptySet()); + restHighLevelClient.performRequestAsyncAndParseEntity(getMappingsRequest, + IndicesRequestConverters::getMappings, + options, + GetMappingsResponse::fromXContent, + listener, + emptySet()); + } + + /** + * Retrieves the mappings on an index or indices using the Get Mapping API. + * See + * Get Mapping API on elastic.co + * @param getMappingsRequest the request + * @param options the request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized + * @return the response + * @throws IOException in case there is a problem sending the request or parsing back the response + * + * @deprecated This method uses an old request and response objects which still refer to types, a deprecated + * feature. The method {@link #getMapping(GetMappingsRequest, RequestOptions)} should be used instead, which + * accepts a new request object. + */ + @Deprecated + public org.elasticsearch.action.admin.indices.mapping.get.GetMappingsResponse getMapping( + org.elasticsearch.action.admin.indices.mapping.get.GetMappingsRequest getMappingsRequest, + RequestOptions options) throws IOException { + return restHighLevelClient.performRequestAndParseEntity(getMappingsRequest, + IndicesRequestConverters::getMappings, + options, + org.elasticsearch.action.admin.indices.mapping.get.GetMappingsResponse::fromXContent, + emptySet()); + } + + /** + * Asynchronously retrieves the mappings on an index on indices using the Get Mapping API. + * See + * Get Mapping API on elastic.co + * @param getMappingsRequest the request + * @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 + * + * @deprecated This method uses old request and response objects which still refer to types, a deprecated feature. + * The method {@link #getMapping(GetMappingsRequest, RequestOptions)} should be used instead, which accepts a new + * request object. + */ + @Deprecated + public void getMappingAsync(org.elasticsearch.action.admin.indices.mapping.get.GetMappingsRequest getMappingsRequest, + RequestOptions options, + ActionListener listener) { + restHighLevelClient.performRequestAsyncAndParseEntity(getMappingsRequest, + IndicesRequestConverters::getMappings, + options, + org.elasticsearch.action.admin.indices.mapping.get.GetMappingsResponse::fromXContent, + listener, + emptySet()); } /** @@ -242,8 +297,9 @@ public void getMappingAsync(GetMappingsRequest getMappingsRequest, RequestOption * @return the response * @throws IOException in case there is a problem sending the request or parsing back the response * - * @deprecated This method uses an old request object which still refers to types, a deprecated feature. The method - * {@link #getFieldMapping(GetFieldMappingsRequest, RequestOptions)} should be used instead, which accepts a new request object. + * @deprecated This method uses old request and response objects which still refer to types, a deprecated feature. + * The method {@link #getFieldMapping(GetFieldMappingsRequest, RequestOptions)} should be used instead, which + * accepts a new request object. */ @Deprecated public org.elasticsearch.action.admin.indices.mapping.get.GetFieldMappingsResponse getFieldMapping( @@ -261,9 +317,9 @@ public org.elasticsearch.action.admin.indices.mapping.get.GetFieldMappingsRespon * @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 * - * @deprecated This method uses an old request object which still refers to types, a deprecated feature. The - * method {@link #getFieldMappingAsync(GetFieldMappingsRequest, RequestOptions, ActionListener)} should be used instead, - * which accepts a new request object. + * @deprecated This method uses an request and response objects which still refers to types, a deprecated feature. + * The method {@link #getFieldMappingAsync(GetFieldMappingsRequest, RequestOptions, ActionListener)} should be + * used instead, which accepts a new request object. */ @Deprecated public void getFieldMappingAsync(org.elasticsearch.action.admin.indices.mapping.get.GetFieldMappingsRequest getFieldMappingsRequest, diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/IndicesRequestConverters.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/IndicesRequestConverters.java index ece8bdffa2566..b6b4d1d2ddcbf 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/IndicesRequestConverters.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/IndicesRequestConverters.java @@ -36,7 +36,6 @@ import org.elasticsearch.action.admin.indices.forcemerge.ForceMergeRequest; import org.elasticsearch.action.admin.indices.get.GetIndexRequest; import org.elasticsearch.client.indices.GetFieldMappingsRequest; -import org.elasticsearch.action.admin.indices.mapping.get.GetMappingsRequest; import org.elasticsearch.action.admin.indices.open.OpenIndexRequest; import org.elasticsearch.action.admin.indices.refresh.RefreshRequest; import org.elasticsearch.action.admin.indices.rollover.RolloverRequest; @@ -49,6 +48,7 @@ import org.elasticsearch.action.admin.indices.validate.query.ValidateQueryRequest; import org.elasticsearch.client.indices.FreezeIndexRequest; import org.elasticsearch.client.indices.GetIndexTemplatesRequest; +import org.elasticsearch.client.indices.GetMappingsRequest; import org.elasticsearch.client.indices.IndexTemplatesExistRequest; import org.elasticsearch.client.indices.PutMappingRequest; import org.elasticsearch.client.indices.UnfreezeIndexRequest; @@ -151,7 +151,20 @@ static Request putMapping(org.elasticsearch.action.admin.indices.mapping.put.Put return request; } - static Request getMappings(GetMappingsRequest getMappingsRequest) throws IOException { + static Request getMappings(GetMappingsRequest getMappingsRequest) { + String[] indices = getMappingsRequest.indices() == null ? Strings.EMPTY_ARRAY : getMappingsRequest.indices(); + + Request request = new Request(HttpGet.METHOD_NAME, RequestConverters.endpoint(indices, "_mapping")); + + RequestConverters.Params parameters = new RequestConverters.Params(request); + parameters.withMasterTimeout(getMappingsRequest.masterNodeTimeout()); + parameters.withIndicesOptions(getMappingsRequest.indicesOptions()); + parameters.withLocal(getMappingsRequest.local()); + + return request; + } + + static Request getMappings(org.elasticsearch.action.admin.indices.mapping.get.GetMappingsRequest getMappingsRequest) { String[] indices = getMappingsRequest.indices() == null ? Strings.EMPTY_ARRAY : getMappingsRequest.indices(); String[] types = getMappingsRequest.types() == null ? Strings.EMPTY_ARRAY : getMappingsRequest.types(); @@ -161,6 +174,7 @@ static Request getMappings(GetMappingsRequest getMappingsRequest) throws IOExcep parameters.withMasterTimeout(getMappingsRequest.masterNodeTimeout()); parameters.withIndicesOptions(getMappingsRequest.indicesOptions()); parameters.withLocal(getMappingsRequest.local()); + parameters.putParam(INCLUDE_TYPE_NAME_PARAMETER, "true"); return request; } diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/indices/GetMappingsRequest.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/indices/GetMappingsRequest.java new file mode 100644 index 0000000000000..b2657697cd604 --- /dev/null +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/indices/GetMappingsRequest.java @@ -0,0 +1,75 @@ +/* + * Licensed to Elasticsearch under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.elasticsearch.client.indices; + +import org.elasticsearch.action.support.IndicesOptions; +import org.elasticsearch.client.TimedRequest; +import org.elasticsearch.client.Validatable; +import org.elasticsearch.common.Strings; + +public class GetMappingsRequest extends TimedRequest implements Validatable { + + private boolean local = false; + private boolean includeDefaults = false; + private String[] indices = Strings.EMPTY_ARRAY; + private IndicesOptions indicesOptions = IndicesOptions.strictExpandOpen(); + + /** + * Indicates whether the receiving node should operate based on local index information or + * forward requests, where needed, to other nodes. If running locally, request will not + * raise errors if local index information is missing. + */ + public GetMappingsRequest local(boolean local) { + this.local = local; + return this; + } + + public boolean local() { + return local; + } + + public GetMappingsRequest indices(String... indices) { + this.indices = indices; + return this; + } + + public GetMappingsRequest indicesOptions(IndicesOptions indicesOptions) { + this.indicesOptions = indicesOptions; + return this; + } + + public String[] indices() { + return indices; + } + + public IndicesOptions indicesOptions() { + return indicesOptions; + } + + public boolean includeDefaults() { + return includeDefaults; + } + + /** Indicates whether default mapping settings should be returned */ + public GetMappingsRequest includeDefaults(boolean includeDefaults) { + this.includeDefaults = includeDefaults; + return this; + } +} diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/indices/GetMappingsResponse.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/indices/GetMappingsResponse.java new file mode 100644 index 0000000000000..e89915c60bdbd --- /dev/null +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/indices/GetMappingsResponse.java @@ -0,0 +1,85 @@ +/* + * Licensed to Elasticsearch under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.elasticsearch.client.indices; + +import org.elasticsearch.cluster.metadata.MappingMetaData; +import org.elasticsearch.common.ParseField; +import org.elasticsearch.common.xcontent.XContentParser; +import org.elasticsearch.common.xcontent.XContentParserUtils; +import org.elasticsearch.index.mapper.MapperService; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; + +public class GetMappingsResponse { + + static final ParseField MAPPINGS = new ParseField("mappings"); + + private Map mappings; + + public GetMappingsResponse(Map mappings) { + this.mappings = mappings; + } + + public Map mappings() { + return mappings; + } + + public static GetMappingsResponse fromXContent(XContentParser parser) throws IOException { + if (parser.currentToken() == null) { + parser.nextToken(); + } + + XContentParserUtils.ensureExpectedToken(parser.currentToken(), + XContentParser.Token.START_OBJECT, + parser::getTokenLocation); + + Map parts = parser.map(); + + Map mappings = new HashMap<>(); + for (Map.Entry entry : parts.entrySet()) { + String indexName = entry.getKey(); + assert entry.getValue() instanceof Map : "expected a map as type mapping, but got: " + entry.getValue().getClass(); + + @SuppressWarnings("unchecked") + final Map fieldMappings = (Map) ((Map) entry.getValue()) + .get(MAPPINGS.getPreferredName()); + + mappings.put(indexName, new MappingMetaData(MapperService.SINGLE_MAPPING_NAME, fieldMappings)); + } + + return new GetMappingsResponse(mappings); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + GetMappingsResponse that = (GetMappingsResponse) o; + return Objects.equals(mappings, that.mappings); + } + + @Override + public int hashCode() { + return Objects.hash(mappings); + } +} diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/IndicesClientIT.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/IndicesClientIT.java index 72bc366e7a9c9..b68d87f99e418 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/IndicesClientIT.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/IndicesClientIT.java @@ -45,8 +45,6 @@ import org.elasticsearch.action.admin.indices.get.GetIndexResponse; import org.elasticsearch.client.indices.GetFieldMappingsRequest; import org.elasticsearch.client.indices.GetFieldMappingsResponse; -import org.elasticsearch.action.admin.indices.mapping.get.GetMappingsRequest; -import org.elasticsearch.action.admin.indices.mapping.get.GetMappingsResponse; import org.elasticsearch.action.admin.indices.open.OpenIndexRequest; import org.elasticsearch.action.admin.indices.open.OpenIndexResponse; import org.elasticsearch.action.admin.indices.refresh.RefreshRequest; @@ -72,6 +70,8 @@ import org.elasticsearch.client.core.ShardsAcknowledgedResponse; import org.elasticsearch.client.indices.FreezeIndexRequest; import org.elasticsearch.client.indices.GetIndexTemplatesRequest; +import org.elasticsearch.client.indices.GetMappingsRequest; +import org.elasticsearch.client.indices.GetMappingsResponse; import org.elasticsearch.client.indices.IndexTemplatesExistRequest; import org.elasticsearch.client.indices.PutMappingRequest; import org.elasticsearch.client.indices.UnfreezeIndexRequest; @@ -94,6 +94,7 @@ import org.elasticsearch.index.query.QueryBuilders; import org.elasticsearch.rest.RestStatus; import org.elasticsearch.rest.action.admin.indices.RestGetFieldMappingAction; +import org.elasticsearch.rest.action.admin.indices.RestGetMappingAction; import org.elasticsearch.rest.action.admin.indices.RestPutMappingAction; import java.io.IOException; @@ -462,8 +463,9 @@ public void testGetMapping() throws IOException { mappingBuilder.endObject().endObject().endObject(); putMappingRequest.source(mappingBuilder); - AcknowledgedResponse putMappingResponse = - execute(putMappingRequest, highLevelClient().indices()::putMapping, highLevelClient().indices()::putMappingAsync); + AcknowledgedResponse putMappingResponse = execute(putMappingRequest, + highLevelClient().indices()::putMapping, + highLevelClient().indices()::putMappingAsync); assertTrue(putMappingResponse.isAcknowledged()); Map getIndexResponse = getAsMap(indexName); @@ -471,8 +473,48 @@ public void testGetMapping() throws IOException { GetMappingsRequest request = new GetMappingsRequest().indices(indexName); - GetMappingsResponse getMappingsResponse = - execute(request, highLevelClient().indices()::getMapping, highLevelClient().indices()::getMappingAsync); + GetMappingsResponse getMappingsResponse = execute( + request, + highLevelClient().indices()::getMapping, + highLevelClient().indices()::getMappingAsync); + + Map mappings = getMappingsResponse.mappings().get(indexName).sourceAsMap(); + Map type = new HashMap<>(); + type.put("type", "text"); + Map field = new HashMap<>(); + field.put("field", type); + Map expected = new HashMap<>(); + expected.put("properties", field); + assertThat(mappings, equalTo(expected)); + } + + public void testGetMappingWithTypes() throws IOException { + String indexName = "test"; + createIndex(indexName, Settings.EMPTY); + + PutMappingRequest putMappingRequest = new PutMappingRequest(indexName); + XContentBuilder mappingBuilder = JsonXContent.contentBuilder(); + mappingBuilder.startObject().startObject("properties").startObject("field"); + mappingBuilder.field("type", "text"); + mappingBuilder.endObject().endObject().endObject(); + putMappingRequest.source(mappingBuilder); + + AcknowledgedResponse putMappingResponse = execute(putMappingRequest, + highLevelClient().indices()::putMapping, + highLevelClient().indices()::putMappingAsync); + assertTrue(putMappingResponse.isAcknowledged()); + + Map getIndexResponse = getAsMap(indexName); + assertEquals("text", XContentMapValues.extractValue(indexName + ".mappings.properties.field.type", getIndexResponse)); + + org.elasticsearch.action.admin.indices.mapping.get.GetMappingsRequest request = + new org.elasticsearch.action.admin.indices.mapping.get.GetMappingsRequest().indices(indexName); + + org.elasticsearch.action.admin.indices.mapping.get.GetMappingsResponse getMappingsResponse = execute( + request, + highLevelClient().indices()::getMapping, + highLevelClient().indices()::getMappingAsync, + expectWarnings(RestGetMappingAction.TYPES_DEPRECATION_MESSAGE)); Map mappings = getMappingsResponse.getMappings().get(indexName).get("_doc").sourceAsMap(); Map type = new HashMap<>(); diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/IndicesRequestConvertersTests.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/IndicesRequestConvertersTests.java index 3e4dcd0209764..0a8695de95743 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/IndicesRequestConvertersTests.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/IndicesRequestConvertersTests.java @@ -38,7 +38,6 @@ import org.elasticsearch.action.admin.indices.flush.SyncedFlushRequest; import org.elasticsearch.action.admin.indices.forcemerge.ForceMergeRequest; import org.elasticsearch.action.admin.indices.get.GetIndexRequest; -import org.elasticsearch.action.admin.indices.mapping.get.GetMappingsRequest; import org.elasticsearch.action.admin.indices.open.OpenIndexRequest; import org.elasticsearch.action.admin.indices.refresh.RefreshRequest; import org.elasticsearch.action.admin.indices.rollover.RolloverRequest; @@ -50,10 +49,11 @@ import org.elasticsearch.action.admin.indices.template.put.PutIndexTemplateRequest; import org.elasticsearch.action.admin.indices.validate.query.ValidateQueryRequest; import org.elasticsearch.action.support.master.AcknowledgedRequest; +import org.elasticsearch.client.indices.GetFieldMappingsRequest; import org.elasticsearch.client.indices.GetIndexTemplatesRequest; +import org.elasticsearch.client.indices.GetMappingsRequest; import org.elasticsearch.client.indices.IndexTemplatesExistRequest; import org.elasticsearch.client.indices.PutMappingRequest; -import org.elasticsearch.client.indices.GetFieldMappingsRequest; import org.elasticsearch.common.CheckedFunction; import org.elasticsearch.common.Strings; import org.elasticsearch.common.settings.Settings; @@ -216,7 +216,7 @@ public void testPutMappingWithTypes() throws IOException { RequestConvertersTests.assertToXContentBody(putMappingRequest, request.getEntity()); } - public void testGetMapping() throws IOException { + public void testGetMapping() { GetMappingsRequest getMappingRequest = new GetMappingsRequest(); String[] indices = Strings.EMPTY_ARRAY; @@ -227,6 +227,37 @@ public void testGetMapping() throws IOException { getMappingRequest.indices((String[]) null); } + Map expectedParams = new HashMap<>(); + RequestConvertersTests.setRandomIndicesOptions(getMappingRequest::indicesOptions, + getMappingRequest::indicesOptions, expectedParams); + RequestConvertersTests.setRandomMasterTimeout(getMappingRequest, expectedParams); + RequestConvertersTests.setRandomLocal(getMappingRequest::local, expectedParams); + + Request request = IndicesRequestConverters.getMappings(getMappingRequest); + StringJoiner endpoint = new StringJoiner("/", "/", ""); + String index = String.join(",", indices); + if (Strings.hasLength(index)) { + endpoint.add(index); + } + endpoint.add("_mapping"); + + Assert.assertThat(endpoint.toString(), equalTo(request.getEndpoint())); + Assert.assertThat(expectedParams, equalTo(request.getParameters())); + Assert.assertThat(HttpGet.METHOD_NAME, equalTo(request.getMethod())); + } + + public void testGetMappingWithTypes() { + org.elasticsearch.action.admin.indices.mapping.get.GetMappingsRequest getMappingRequest = + new org.elasticsearch.action.admin.indices.mapping.get.GetMappingsRequest(); + + String[] indices = Strings.EMPTY_ARRAY; + if (ESTestCase.randomBoolean()) { + indices = RequestConvertersTests.randomIndicesNames(0, 5); + getMappingRequest.indices(indices); + } else if (ESTestCase.randomBoolean()) { + getMappingRequest.indices((String[]) null); + } + String type = null; if (ESTestCase.randomBoolean()) { type = ESTestCase.randomAlphaOfLengthBetween(3, 10); @@ -241,6 +272,7 @@ public void testGetMapping() throws IOException { getMappingRequest::indicesOptions, expectedParams); RequestConvertersTests.setRandomMasterTimeout(getMappingRequest, expectedParams); RequestConvertersTests.setRandomLocal(getMappingRequest, expectedParams); + expectedParams.put(INCLUDE_TYPE_NAME_PARAMETER, "true"); Request request = IndicesRequestConverters.getMappings(getMappingRequest); StringJoiner endpoint = new StringJoiner("/", "/", ""); diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/IndicesClientDocumentationIT.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/IndicesClientDocumentationIT.java index ef649dcfc48f9..16d487b35de8d 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/IndicesClientDocumentationIT.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/IndicesClientDocumentationIT.java @@ -44,8 +44,6 @@ import org.elasticsearch.action.admin.indices.get.GetIndexResponse; import org.elasticsearch.client.indices.GetFieldMappingsRequest; import org.elasticsearch.client.indices.GetFieldMappingsResponse; -import org.elasticsearch.action.admin.indices.mapping.get.GetMappingsRequest; -import org.elasticsearch.action.admin.indices.mapping.get.GetMappingsResponse; import org.elasticsearch.action.admin.indices.open.OpenIndexRequest; import org.elasticsearch.action.admin.indices.open.OpenIndexResponse; import org.elasticsearch.action.admin.indices.refresh.RefreshRequest; @@ -76,6 +74,8 @@ import org.elasticsearch.client.core.ShardsAcknowledgedResponse; import org.elasticsearch.client.indices.FreezeIndexRequest; import org.elasticsearch.client.indices.GetIndexTemplatesRequest; +import org.elasticsearch.client.indices.GetMappingsRequest; +import org.elasticsearch.client.indices.GetMappingsResponse; import org.elasticsearch.client.indices.IndexTemplatesExistRequest; import org.elasticsearch.client.indices.PutMappingRequest; import org.elasticsearch.client.indices.UnfreezeIndexRequest; @@ -602,8 +602,7 @@ public void testGetMapping() throws IOException { // end::get-mappings-request // tag::get-mappings-request-masterTimeout - request.masterNodeTimeout(TimeValue.timeValueMinutes(1)); // <1> - request.masterNodeTimeout("1m"); // <2> + request.setMasterTimeout(TimeValue.timeValueMinutes(1)); // <1> // end::get-mappings-request-masterTimeout // tag::get-mappings-request-indicesOptions @@ -615,9 +614,9 @@ public void testGetMapping() throws IOException { // end::get-mappings-execute // tag::get-mappings-response - ImmutableOpenMap> allMappings = getMappingResponse.mappings(); // <1> - MappingMetaData typeMapping = allMappings.get("twitter").get("_doc"); // <2> - Map mapping = typeMapping.sourceAsMap(); // <3> + Map allMappings = getMappingResponse.mappings(); // <1> + MappingMetaData indexMapping = allMappings.get("twitter"); // <2> + Map mapping = indexMapping.sourceAsMap(); // <3> // end::get-mappings-response Map type = new HashMap<>(); @@ -673,9 +672,9 @@ public void onFailure(Exception e) { final CountDownLatch latch = new CountDownLatch(1); final ActionListener latchListener = new LatchedActionListener<>(listener, latch); listener = ActionListener.wrap(r -> { - ImmutableOpenMap> allMappings = r.mappings(); - MappingMetaData typeMapping = allMappings.get("twitter").get("_doc"); - Map mapping = typeMapping.sourceAsMap(); + Map allMappings = r.mappings(); + MappingMetaData indexMapping = allMappings.get("twitter"); + Map mapping = indexMapping.sourceAsMap(); Map type = new HashMap<>(); type.put("type", "text"); diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/indices/GetFieldMappingsResponseTests.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/indices/GetFieldMappingsResponseTests.java index aa8ce3bb6c098..827b2f005aef8 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/indices/GetFieldMappingsResponseTests.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/indices/GetFieldMappingsResponseTests.java @@ -44,14 +44,14 @@ public void testFromXContent() throws IOException { .test(); } - Predicate getRandomFieldsExcludeFilter() { + private Predicate getRandomFieldsExcludeFilter() { // allow random fields at the level of `index` and `index.mappings.field` // otherwise random field could be evaluated as index name or type name return s -> false == (s.matches("(?[^.]+)") || s.matches("(?[^.]+)\\.mappings\\.(?[^.]+)")); } - static GetFieldMappingsResponse createTestInstance() { + private static GetFieldMappingsResponse createTestInstance() { Map> mappings = new HashMap<>(); // if mappings is empty, means that fields are not found if (randomBoolean()) { @@ -72,12 +72,11 @@ static GetFieldMappingsResponse createTestInstance() { } // As the client class GetFieldMappingsResponse doesn't have toXContent method, adding this method here only for the test - static void toXContent(GetFieldMappingsResponse response, XContentBuilder builder) throws IOException { + private static void toXContent(GetFieldMappingsResponse response, XContentBuilder builder) throws IOException { builder.startObject(); for (Map.Entry> indexEntry : response.mappings().entrySet()) { builder.startObject(indexEntry.getKey()); builder.startObject("mappings"); - Map mappings = null; for (Map.Entry fieldEntry : indexEntry.getValue().entrySet()) { builder.startObject(fieldEntry.getKey()); builder.field("full_name", fieldEntry.getValue().fullName()); diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/indices/GetMappingsResponseTests.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/indices/GetMappingsResponseTests.java new file mode 100644 index 0000000000000..032c117d15996 --- /dev/null +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/indices/GetMappingsResponseTests.java @@ -0,0 +1,115 @@ +/* + * Licensed to Elasticsearch under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.elasticsearch.client.indices; + +import org.elasticsearch.cluster.metadata.MappingMetaData; +import org.elasticsearch.common.collect.ImmutableOpenMap; +import org.elasticsearch.common.xcontent.ToXContent; +import org.elasticsearch.common.xcontent.ToXContent.Params; +import org.elasticsearch.common.xcontent.XContentBuilder; +import org.elasticsearch.index.mapper.MapperService; +import org.elasticsearch.rest.BaseRestHandler; +import org.elasticsearch.test.ESTestCase; + +import java.io.IOException; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import java.util.function.Predicate; + +import static org.elasticsearch.client.indices.GetMappingsResponse.MAPPINGS; +import static org.elasticsearch.test.AbstractXContentTestCase.xContentTester; + +public class GetMappingsResponseTests extends ESTestCase { + + public void testFromXContent() throws IOException { + xContentTester( + this::createParser, + GetMappingsResponseTests::createTestInstance, + GetMappingsResponseTests::toXContent, + GetMappingsResponse::fromXContent) + .supportsUnknownFields(true) + .randomFieldsExcludeFilter(getRandomFieldsExcludeFilter()) + .test(); + } + + private static GetMappingsResponse createTestInstance() { + Map allMappings = new HashMap<>(); + allMappings.put("index-" + randomAlphaOfLength(5), randomMappingMetaData()); + return new GetMappingsResponse(allMappings); + } + + private Predicate getRandomFieldsExcludeFilter() { + return field -> !field.equals(MAPPINGS.getPreferredName()); + } + + public static MappingMetaData randomMappingMetaData() { + Map mappings = new HashMap<>(); + + if (frequently()) { // rarely have no fields + mappings.put("field1", randomFieldMapping()); + if (randomBoolean()) { + mappings.put("field2", randomFieldMapping()); + } + } + + try { + return new MappingMetaData(MapperService.SINGLE_MAPPING_NAME, mappings); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + private static Map randomFieldMapping() { + Map mappings = new HashMap<>(); + if (randomBoolean()) { + mappings.put("type", randomFrom("text", "keyword")); + mappings.put("index", "analyzed"); + mappings.put("analyzer", "english"); + } else { + mappings.put("type", randomFrom("integer", "float", "long", "double")); + mappings.put("index", Objects.toString(randomBoolean())); + } + return mappings; + } + + // Because the client-side class does not have a toXContent method, we first convert it to a server + // class, and then use its method (with include_type_name set to 'false') to generate the xContent. + private static void toXContent(GetMappingsResponse response, XContentBuilder builder) throws IOException { + ImmutableOpenMap.Builder> allMappings = ImmutableOpenMap.builder(); + + for (Map.Entry indexEntry : response.mappings().entrySet()) { + ImmutableOpenMap.Builder mappings = ImmutableOpenMap.builder(); + mappings.put(MapperService.SINGLE_MAPPING_NAME, indexEntry.getValue()); + allMappings.put(indexEntry.getKey(), mappings.build()); + } + + org.elasticsearch.action.admin.indices.mapping.get.GetMappingsResponse serverResponse = + new org.elasticsearch.action.admin.indices.mapping.get.GetMappingsResponse(allMappings.build()); + + Params params = new ToXContent.MapParams( + Collections.singletonMap(BaseRestHandler.INCLUDE_TYPE_NAME_PARAMETER, "false")); + + builder.startObject(); + serverResponse.toXContent(builder, params); + builder.endObject(); + } +} diff --git a/docs/java-rest/high-level/indices/get_mappings.asciidoc b/docs/java-rest/high-level/indices/get_mappings.asciidoc index a42a8ac77b338..516e0633f83c8 100644 --- a/docs/java-rest/high-level/indices/get_mappings.asciidoc +++ b/docs/java-rest/high-level/indices/get_mappings.asciidoc @@ -10,13 +10,13 @@ [id="{upid}-{api}-request"] ==== Get Mappings Request -A +{request}+ can have an optional list of indices and optional list of types: +A +{request}+ can have an optional list of indices: ["source","java",subs="attributes,callouts,macros"] -------------------------------------------------- include-tagged::{doc-tests-file}[{api}-request] -------------------------------------------------- -<1> An empty request that will return all indices and types +<1> An empty request that will return all indices <2> Setting the indices to fetch mapping for ==== Optional arguments @@ -27,7 +27,6 @@ The following arguments can also optionally be provided: include-tagged::{doc-tests-file}[{api}-request-masterTimeout] -------------------------------------------------- <1> Timeout to connect to the master node as a `TimeValue` -<2> Timeout to connect to the master node as a `String` ["source","java",subs="attributes,callouts,macros"] -------------------------------------------------- @@ -48,5 +47,5 @@ executed operation as follows: include-tagged::{doc-tests-file}[{api}-response] -------------------------------------------------- <1> Returning all indices' mappings -<2> Retrieving the mappings for a particular index and type +<2> Retrieving the mappings for a particular index <3> Getting the mappings as a Java Map diff --git a/server/src/main/java/org/elasticsearch/action/admin/indices/mapping/get/GetMappingsResponse.java b/server/src/main/java/org/elasticsearch/action/admin/indices/mapping/get/GetMappingsResponse.java index 50b7a36426802..7abbea9c1d941 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/indices/mapping/get/GetMappingsResponse.java +++ b/server/src/main/java/org/elasticsearch/action/admin/indices/mapping/get/GetMappingsResponse.java @@ -20,7 +20,6 @@ package org.elasticsearch.action.admin.indices.mapping.get; import com.carrotsearch.hppc.cursors.ObjectObjectCursor; - import org.elasticsearch.action.ActionResponse; import org.elasticsearch.cluster.metadata.MappingMetaData; import org.elasticsearch.common.ParseField; @@ -31,7 +30,6 @@ import org.elasticsearch.common.xcontent.ToXContentFragment; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentParser; -import org.elasticsearch.index.mapper.MapperService; import org.elasticsearch.rest.BaseRestHandler; import java.io.IOException; @@ -45,7 +43,7 @@ public class GetMappingsResponse extends ActionResponse implements ToXContentFra private ImmutableOpenMap> mappings = ImmutableOpenMap.of(); - GetMappingsResponse(ImmutableOpenMap> mappings) { + public GetMappingsResponse(ImmutableOpenMap> mappings) { this.mappings = mappings; } @@ -102,17 +100,20 @@ public static GetMappingsResponse fromXContent(XContentParser parser) throws IOE for (Map.Entry entry : parts.entrySet()) { final String indexName = entry.getKey(); assert entry.getValue() instanceof Map : "expected a map as type mapping, but got: " + entry.getValue().getClass(); + final Map mapping = (Map) ((Map) entry.getValue()).get(MAPPINGS.getPreferredName()); + ImmutableOpenMap.Builder typeBuilder = new ImmutableOpenMap.Builder<>(); - @SuppressWarnings("unchecked") - final Map fieldMappings = (Map) ((Map) entry.getValue()) - .get(MAPPINGS.getPreferredName()); - if (fieldMappings.isEmpty() == false) { - assert fieldMappings instanceof Map : "expected a map as inner type mapping, but got: " + fieldMappings.getClass(); - MappingMetaData mmd = new MappingMetaData(MapperService.SINGLE_MAPPING_NAME, fieldMappings); - typeBuilder.put(MapperService.SINGLE_MAPPING_NAME, mmd); + for (Map.Entry typeEntry : mapping.entrySet()) { + final String typeName = typeEntry.getKey(); + assert typeEntry.getValue() instanceof Map : "expected a map as inner type mapping, but got: " + + typeEntry.getValue().getClass(); + final Map fieldMappings = (Map) typeEntry.getValue(); + MappingMetaData mmd = new MappingMetaData(typeName, fieldMappings); + typeBuilder.put(typeName, mmd); } builder.put(indexName, typeBuilder.build()); } + return new GetMappingsResponse(builder.build()); } diff --git a/server/src/main/java/org/elasticsearch/rest/action/admin/indices/RestGetMappingAction.java b/server/src/main/java/org/elasticsearch/rest/action/admin/indices/RestGetMappingAction.java index 8826932e252ba..74f451ab30cd2 100644 --- a/server/src/main/java/org/elasticsearch/rest/action/admin/indices/RestGetMappingAction.java +++ b/server/src/main/java/org/elasticsearch/rest/action/admin/indices/RestGetMappingAction.java @@ -60,8 +60,8 @@ public class RestGetMappingAction extends BaseRestHandler { private static final Logger logger = LogManager.getLogger(RestGetMappingAction.class); private static final DeprecationLogger deprecationLogger = new DeprecationLogger(logger); - static final String TYPES_DEPRECATION_MESSAGE = "[types removal] Using include_type_name in get mapping requests is deprecated. " - + "The parameter will be removed in the next major version."; + public static final String TYPES_DEPRECATION_MESSAGE = "[types removal] Using include_type_name in get" + + " mapping requests is deprecated. The parameter will be removed in the next major version."; public RestGetMappingAction(final Settings settings, final RestController controller) { super(settings); diff --git a/server/src/test/java/org/elasticsearch/action/admin/indices/mapping/get/GetFieldMappingsResponseTests.java b/server/src/test/java/org/elasticsearch/action/admin/indices/mapping/get/GetFieldMappingsResponseTests.java index 734de94b1c419..2b8db458eb82f 100644 --- a/server/src/test/java/org/elasticsearch/action/admin/indices/mapping/get/GetFieldMappingsResponseTests.java +++ b/server/src/test/java/org/elasticsearch/action/admin/indices/mapping/get/GetFieldMappingsResponseTests.java @@ -124,8 +124,8 @@ protected Predicate getRandomFieldsExcludeFilter() { } /** - * For now, we only unit test the legacy typed responses. This will soon no longer be the case, - * as we introduce support for typeless xContent parsing in {@link GetFieldMappingsResponse}. + * For xContent roundtrip testing we force the xContent output to still contain types because the parser + * still expects them. The new typeless parsing is implemented in the client side GetFieldMappingsResponse. */ @Override protected ToXContent.Params getToXContentParams() { diff --git a/server/src/test/java/org/elasticsearch/action/admin/indices/mapping/get/GetMappingsResponseTests.java b/server/src/test/java/org/elasticsearch/action/admin/indices/mapping/get/GetMappingsResponseTests.java index 7d1a19c65ed52..677a7b4b7eced 100644 --- a/server/src/test/java/org/elasticsearch/action/admin/indices/mapping/get/GetMappingsResponseTests.java +++ b/server/src/test/java/org/elasticsearch/action/admin/indices/mapping/get/GetMappingsResponseTests.java @@ -20,13 +20,11 @@ package org.elasticsearch.action.admin.indices.mapping.get; import com.carrotsearch.hppc.cursors.ObjectCursor; - import org.elasticsearch.cluster.metadata.MappingMetaData; import org.elasticsearch.common.collect.ImmutableOpenMap; import org.elasticsearch.common.xcontent.ToXContent; import org.elasticsearch.common.xcontent.ToXContent.Params; import org.elasticsearch.common.xcontent.XContentParser; -import org.elasticsearch.common.xcontent.XContentType; import org.elasticsearch.index.mapper.MapperService; import org.elasticsearch.rest.BaseRestHandler; import org.elasticsearch.test.AbstractStreamableXContentTestCase; @@ -41,8 +39,6 @@ import java.util.Map; import java.util.Objects; -import static org.elasticsearch.test.AbstractXContentTestCase.xContentTester; - public class GetMappingsResponseTests extends AbstractStreamableXContentTestCase { @Override @@ -117,15 +113,20 @@ public static ImmutableOpenMap createMappingsForIndex(i return typeBuilder.build(); } + /** + * For xContent roundtrip testing we force the xContent output to still contain types because the parser + * still expects them. The new typeless parsing is implemented in the client side GetMappingsResponse. + */ @Override - protected GetMappingsResponse createTestInstance() { - return createTestInstance(true); + protected Params getToXContentParams() { + return new ToXContent.MapParams(Collections.singletonMap(BaseRestHandler.INCLUDE_TYPE_NAME_PARAMETER, "true")); } - private GetMappingsResponse createTestInstance(boolean randomTypeNames) { + @Override + protected GetMappingsResponse createTestInstance() { ImmutableOpenMap.Builder> indexBuilder = ImmutableOpenMap.builder(); int typeCount = rarely() ? 0 : 1; - indexBuilder.put("index-" + randomAlphaOfLength(5), createMappingsForIndex(typeCount, randomTypeNames)); + indexBuilder.put("index-" + randomAlphaOfLength(5), createMappingsForIndex(typeCount, randomBoolean())); GetMappingsResponse resp = new GetMappingsResponse(indexBuilder.build()); logger.debug("--> created: {}", resp); return resp; @@ -163,57 +164,4 @@ private static Map randomFieldMapping() { } return mappings; } - - @Override - protected GetMappingsResponse createXContextTestInstance(XContentType xContentType) { - // don't use random type names for XContent roundtrip tests because we cannot parse them back anymore - return createTestInstance(false); - } - - /** - * check that the "old" legacy response format with types works as expected - */ - public void testToXContentWithTypes() throws IOException { - Params params = new ToXContent.MapParams(Collections.singletonMap(BaseRestHandler.INCLUDE_TYPE_NAME_PARAMETER, "true")); - xContentTester(this::createParser, t -> createTestInstance(), params, this::fromXContentWithTypes) - .numberOfTestRuns(NUMBER_OF_TEST_RUNS) - .supportsUnknownFields(supportsUnknownFields()) - .shuffleFieldsExceptions(getShuffleFieldsExceptions()) - .randomFieldsExcludeFilter(getRandomFieldsExcludeFilter()) - .assertEqualsConsumer(this::assertEqualInstances) - .assertToXContentEquivalence(true) - .test(); - } - - /** - * including the pre-7.0 parsing code here to test that older HLRC clients using this can parse the responses that are - * returned when "include_type_name=true" - */ - private GetMappingsResponse fromXContentWithTypes(XContentParser parser) throws IOException { - if (parser.currentToken() == null) { - parser.nextToken(); - } - assert parser.currentToken() == XContentParser.Token.START_OBJECT; - Map parts = parser.map(); - - ImmutableOpenMap.Builder> builder = new ImmutableOpenMap.Builder<>(); - for (Map.Entry entry : parts.entrySet()) { - final String indexName = entry.getKey(); - assert entry.getValue() instanceof Map : "expected a map as type mapping, but got: " + entry.getValue().getClass(); - final Map mapping = (Map) ((Map) entry.getValue()).get("mappings"); - - ImmutableOpenMap.Builder typeBuilder = new ImmutableOpenMap.Builder<>(); - for (Map.Entry typeEntry : mapping.entrySet()) { - final String typeName = typeEntry.getKey(); - assert typeEntry.getValue() instanceof Map : "expected a map as inner type mapping, but got: " - + typeEntry.getValue().getClass(); - final Map fieldMappings = (Map) typeEntry.getValue(); - MappingMetaData mmd = new MappingMetaData(typeName, fieldMappings); - typeBuilder.put(typeName, mmd); - } - builder.put(indexName, typeBuilder.build()); - } - - return new GetMappingsResponse(builder.build()); - } } From 4e05f79687441cc7cf9584a4aada28c4cda5c59f Mon Sep 17 00:00:00 2001 From: Julie Tibshirani Date: Thu, 24 Jan 2019 11:25:06 -0800 Subject: [PATCH 2/9] Fix a typo in IndicesClient. --- .../src/main/java/org/elasticsearch/client/IndicesClient.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/IndicesClient.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/IndicesClient.java index 212403cd6f300..f66ef6652fe0c 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/IndicesClient.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/IndicesClient.java @@ -317,7 +317,7 @@ public org.elasticsearch.action.admin.indices.mapping.get.GetFieldMappingsRespon * @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 * - * @deprecated This method uses an request and response objects which still refers to types, a deprecated feature. + * @deprecated This method uses request and response objects which still refers to types, a deprecated feature. * The method {@link #getFieldMappingAsync(GetFieldMappingsRequest, RequestOptions, ActionListener)} should be * used instead, which accepts a new request object. */ From 28f425d0e590fdae8448f3ab0890cc5a720ece8b Mon Sep 17 00:00:00 2001 From: Julie Tibshirani Date: Thu, 24 Jan 2019 11:25:51 -0800 Subject: [PATCH 3/9] Add some missing deprecated annotations in IndicesRequestConverters. --- .../org/elasticsearch/client/IndicesRequestConverters.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/IndicesRequestConverters.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/IndicesRequestConverters.java index b6b4d1d2ddcbf..8866068109326 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/IndicesRequestConverters.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/IndicesRequestConverters.java @@ -133,6 +133,7 @@ static Request putMapping(PutMappingRequest putMappingRequest) throws IOExceptio return request; } + @Deprecated static Request putMapping(org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequest putMappingRequest) throws IOException { // The concreteIndex is an internal concept, not applicable to requests made over the REST API. if (putMappingRequest.getConcreteIndex() != null) { @@ -164,6 +165,7 @@ static Request getMappings(GetMappingsRequest getMappingsRequest) { return request; } + @Deprecated static Request getMappings(org.elasticsearch.action.admin.indices.mapping.get.GetMappingsRequest getMappingsRequest) { String[] indices = getMappingsRequest.indices() == null ? Strings.EMPTY_ARRAY : getMappingsRequest.indices(); String[] types = getMappingsRequest.types() == null ? Strings.EMPTY_ARRAY : getMappingsRequest.types(); @@ -200,6 +202,7 @@ static Request getFieldMapping(GetFieldMappingsRequest getFieldMappingsRequest) return request; } + @Deprecated static Request getFieldMapping(org.elasticsearch.action.admin.indices.mapping.get.GetFieldMappingsRequest getFieldMappingsRequest) { String[] indices = getFieldMappingsRequest.indices() == null ? Strings.EMPTY_ARRAY : getFieldMappingsRequest.indices(); String[] types = getFieldMappingsRequest.types() == null ? Strings.EMPTY_ARRAY : getFieldMappingsRequest.types(); From 05c870dcd0330ebc0dec564b1dd58fec00f7ab72 Mon Sep 17 00:00:00 2001 From: Julie Tibshirani Date: Thu, 24 Jan 2019 11:27:00 -0800 Subject: [PATCH 4/9] Minor clean up in GetMappingsRequest. --- .../org/elasticsearch/client/indices/GetMappingsRequest.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/indices/GetMappingsRequest.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/indices/GetMappingsRequest.java index b2657697cd604..0bc4ba4af77c1 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/indices/GetMappingsRequest.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/indices/GetMappingsRequest.java @@ -21,10 +21,9 @@ import org.elasticsearch.action.support.IndicesOptions; import org.elasticsearch.client.TimedRequest; -import org.elasticsearch.client.Validatable; import org.elasticsearch.common.Strings; -public class GetMappingsRequest extends TimedRequest implements Validatable { +public class GetMappingsRequest extends TimedRequest { private boolean local = false; private boolean includeDefaults = false; From 06805cc431f9d25bdcbe70c4ab24181b6b200fa2 Mon Sep 17 00:00:00 2001 From: Julie Tibshirani Date: Thu, 24 Jan 2019 11:28:53 -0800 Subject: [PATCH 5/9] Remove equals and hashCode from GetMappingsResponse. --- .../client/indices/GetMappingsResponse.java | 13 ------------- .../client/indices/GetMappingsResponseTests.java | 5 +++++ 2 files changed, 5 insertions(+), 13 deletions(-) diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/indices/GetMappingsResponse.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/indices/GetMappingsResponse.java index e89915c60bdbd..69feb55662468 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/indices/GetMappingsResponse.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/indices/GetMappingsResponse.java @@ -69,17 +69,4 @@ public static GetMappingsResponse fromXContent(XContentParser parser) throws IOE return new GetMappingsResponse(mappings); } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - GetMappingsResponse that = (GetMappingsResponse) o; - return Objects.equals(mappings, that.mappings); - } - - @Override - public int hashCode() { - return Objects.hash(mappings); - } } diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/indices/GetMappingsResponseTests.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/indices/GetMappingsResponseTests.java index 032c117d15996..573c79062f8fc 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/indices/GetMappingsResponseTests.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/indices/GetMappingsResponseTests.java @@ -46,6 +46,7 @@ public void testFromXContent() throws IOException { GetMappingsResponseTests::createTestInstance, GetMappingsResponseTests::toXContent, GetMappingsResponse::fromXContent) + .assertEqualsConsumer(this::assertEqualInstances) .supportsUnknownFields(true) .randomFieldsExcludeFilter(getRandomFieldsExcludeFilter()) .test(); @@ -61,6 +62,10 @@ private Predicate getRandomFieldsExcludeFilter() { return field -> !field.equals(MAPPINGS.getPreferredName()); } + private void assertEqualInstances(GetMappingsResponse expected, GetMappingsResponse actual) { + assertEquals(expected.mappings(), actual.mappings()); + } + public static MappingMetaData randomMappingMetaData() { Map mappings = new HashMap<>(); From 3b0270916edeae7eb49b4c2dd379d7a8d87f3e85 Mon Sep 17 00:00:00 2001 From: Julie Tibshirani Date: Thu, 24 Jan 2019 11:30:33 -0800 Subject: [PATCH 6/9] Some clean up in IndicesRequestConvertersTests. --- .../client/indices/GetMappingsResponse.java | 1 - .../client/IndicesRequestConvertersTests.java | 44 +++++++++---------- 2 files changed, 22 insertions(+), 23 deletions(-) diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/indices/GetMappingsResponse.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/indices/GetMappingsResponse.java index 69feb55662468..54f569ab94b06 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/indices/GetMappingsResponse.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/indices/GetMappingsResponse.java @@ -28,7 +28,6 @@ import java.io.IOException; import java.util.HashMap; import java.util.Map; -import java.util.Objects; public class GetMappingsResponse { diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/IndicesRequestConvertersTests.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/IndicesRequestConvertersTests.java index 0a8695de95743..867cbfa3f0186 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/IndicesRequestConvertersTests.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/IndicesRequestConvertersTests.java @@ -220,10 +220,10 @@ public void testGetMapping() { GetMappingsRequest getMappingRequest = new GetMappingsRequest(); String[] indices = Strings.EMPTY_ARRAY; - if (ESTestCase.randomBoolean()) { + if (randomBoolean()) { indices = RequestConvertersTests.randomIndicesNames(0, 5); getMappingRequest.indices(indices); - } else if (ESTestCase.randomBoolean()) { + } else if (randomBoolean()) { getMappingRequest.indices((String[]) null); } @@ -251,18 +251,18 @@ public void testGetMappingWithTypes() { new org.elasticsearch.action.admin.indices.mapping.get.GetMappingsRequest(); String[] indices = Strings.EMPTY_ARRAY; - if (ESTestCase.randomBoolean()) { + if (randomBoolean()) { indices = RequestConvertersTests.randomIndicesNames(0, 5); getMappingRequest.indices(indices); - } else if (ESTestCase.randomBoolean()) { + } else if (randomBoolean()) { getMappingRequest.indices((String[]) null); } String type = null; - if (ESTestCase.randomBoolean()) { - type = ESTestCase.randomAlphaOfLengthBetween(3, 10); + if (randomBoolean()) { + type = randomAlphaOfLengthBetween(3, 10); getMappingRequest.types(type); - } else if (ESTestCase.randomBoolean()) { + } else if (randomBoolean()) { getMappingRequest.types((String[]) null); } @@ -294,21 +294,21 @@ public void testGetFieldMapping() { GetFieldMappingsRequest getFieldMappingsRequest = new GetFieldMappingsRequest(); String[] indices = Strings.EMPTY_ARRAY; - if (ESTestCase.randomBoolean()) { + if (randomBoolean()) { indices = RequestConvertersTests.randomIndicesNames(0, 5); getFieldMappingsRequest.indices(indices); - } else if (ESTestCase.randomBoolean()) { + } else if (randomBoolean()) { getFieldMappingsRequest.indices((String[]) null); } String[] fields = null; - if (ESTestCase.randomBoolean()) { - fields = new String[ESTestCase.randomIntBetween(1, 5)]; + if (randomBoolean()) { + fields = new String[randomIntBetween(1, 5)]; for (int i = 0; i < fields.length; i++) { - fields[i] = ESTestCase.randomAlphaOfLengthBetween(3, 10); + fields[i] = randomAlphaOfLengthBetween(3, 10); } getFieldMappingsRequest.fields(fields); - } else if (ESTestCase.randomBoolean()) { + } else if (randomBoolean()) { getFieldMappingsRequest.fields((String[]) null); } @@ -338,29 +338,29 @@ public void testGetFieldMappingWithTypes() { new org.elasticsearch.action.admin.indices.mapping.get.GetFieldMappingsRequest(); String[] indices = Strings.EMPTY_ARRAY; - if (ESTestCase.randomBoolean()) { + if (randomBoolean()) { indices = RequestConvertersTests.randomIndicesNames(0, 5); getFieldMappingsRequest.indices(indices); - } else if (ESTestCase.randomBoolean()) { + } else if (randomBoolean()) { getFieldMappingsRequest.indices((String[]) null); } String type = null; - if (ESTestCase.randomBoolean()) { - type = ESTestCase.randomAlphaOfLengthBetween(3, 10); + if (randomBoolean()) { + type = randomAlphaOfLengthBetween(3, 10); getFieldMappingsRequest.types(type); - } else if (ESTestCase.randomBoolean()) { + } else if (randomBoolean()) { getFieldMappingsRequest.types((String[]) null); } String[] fields = null; - if (ESTestCase.randomBoolean()) { - fields = new String[ESTestCase.randomIntBetween(1, 5)]; + if (randomBoolean()) { + fields = new String[randomIntBetween(1, 5)]; for (int i = 0; i < fields.length; i++) { - fields[i] = ESTestCase.randomAlphaOfLengthBetween(3, 10); + fields[i] = randomAlphaOfLengthBetween(3, 10); } getFieldMappingsRequest.fields(fields); - } else if (ESTestCase.randomBoolean()) { + } else if (randomBoolean()) { getFieldMappingsRequest.fields((String[]) null); } From bd476a01f02ecee154353a9cb8cd330d1ed02370 Mon Sep 17 00:00:00 2001 From: Julie Tibshirani Date: Thu, 24 Jan 2019 12:15:56 -0800 Subject: [PATCH 7/9] In GetMappingsResponseTests, generate a random server object as opposed to a client one. --- .../indices/GetMappingsResponseTests.java | 47 +++++++++++-------- 1 file changed, 27 insertions(+), 20 deletions(-) diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/indices/GetMappingsResponseTests.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/indices/GetMappingsResponseTests.java index 573c79062f8fc..e4122b9cf6255 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/indices/GetMappingsResponseTests.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/indices/GetMappingsResponseTests.java @@ -19,11 +19,13 @@ package org.elasticsearch.client.indices; +import org.elasticsearch.action.admin.indices.mapping.get.GetMappingsResponse; import org.elasticsearch.cluster.metadata.MappingMetaData; import org.elasticsearch.common.collect.ImmutableOpenMap; import org.elasticsearch.common.xcontent.ToXContent; import org.elasticsearch.common.xcontent.ToXContent.Params; import org.elasticsearch.common.xcontent.XContentBuilder; +import org.elasticsearch.common.xcontent.XContentParser; import org.elasticsearch.index.mapper.MapperService; import org.elasticsearch.rest.BaseRestHandler; import org.elasticsearch.test.ESTestCase; @@ -40,32 +42,34 @@ public class GetMappingsResponseTests extends ESTestCase { + // Because the client-side class does not have a toXContent method, we test xContent serialization by creating + // a random server object, serializing it to xContent, then parsing it back as a client object. We check + // equality by converting the parsed client object to a server one, and comparing it to the original. public void testFromXContent() throws IOException { xContentTester( this::createParser, GetMappingsResponseTests::createTestInstance, GetMappingsResponseTests::toXContent, - GetMappingsResponse::fromXContent) - .assertEqualsConsumer(this::assertEqualInstances) + GetMappingsResponseTests::fromXContent) .supportsUnknownFields(true) .randomFieldsExcludeFilter(getRandomFieldsExcludeFilter()) .test(); } private static GetMappingsResponse createTestInstance() { - Map allMappings = new HashMap<>(); - allMappings.put("index-" + randomAlphaOfLength(5), randomMappingMetaData()); - return new GetMappingsResponse(allMappings); + ImmutableOpenMap.Builder mappings = ImmutableOpenMap.builder(); + mappings.put(MapperService.SINGLE_MAPPING_NAME, randomMappingMetaData()); + + ImmutableOpenMap.Builder> allMappings = ImmutableOpenMap.builder(); + allMappings.put("index-" + randomAlphaOfLength(5), mappings.build()); + + return new GetMappingsResponse(allMappings.build()); } private Predicate getRandomFieldsExcludeFilter() { return field -> !field.equals(MAPPINGS.getPreferredName()); } - private void assertEqualInstances(GetMappingsResponse expected, GetMappingsResponse actual) { - assertEquals(expected.mappings(), actual.mappings()); - } - public static MappingMetaData randomMappingMetaData() { Map mappings = new HashMap<>(); @@ -96,9 +100,20 @@ private static Map randomFieldMapping() { return mappings; } - // Because the client-side class does not have a toXContent method, we first convert it to a server - // class, and then use its method (with include_type_name set to 'false') to generate the xContent. private static void toXContent(GetMappingsResponse response, XContentBuilder builder) throws IOException { + Params params = new ToXContent.MapParams( + Collections.singletonMap(BaseRestHandler.INCLUDE_TYPE_NAME_PARAMETER, "false")); + + builder.startObject(); + response.toXContent(builder, params); + builder.endObject(); + } + + private static GetMappingsResponse fromXContent( + XContentParser parser) throws IOException { + org.elasticsearch.client.indices.GetMappingsResponse response = + org.elasticsearch.client.indices.GetMappingsResponse.fromXContent(parser); + ImmutableOpenMap.Builder> allMappings = ImmutableOpenMap.builder(); for (Map.Entry indexEntry : response.mappings().entrySet()) { @@ -107,14 +122,6 @@ private static void toXContent(GetMappingsResponse response, XContentBuilder bui allMappings.put(indexEntry.getKey(), mappings.build()); } - org.elasticsearch.action.admin.indices.mapping.get.GetMappingsResponse serverResponse = - new org.elasticsearch.action.admin.indices.mapping.get.GetMappingsResponse(allMappings.build()); - - Params params = new ToXContent.MapParams( - Collections.singletonMap(BaseRestHandler.INCLUDE_TYPE_NAME_PARAMETER, "false")); - - builder.startObject(); - serverResponse.toXContent(builder, params); - builder.endObject(); + return new GetMappingsResponse(allMappings.build()); } } From 811c473d2ea959a47a09a74c3b6535e22c552081 Mon Sep 17 00:00:00 2001 From: Julie Tibshirani Date: Thu, 24 Jan 2019 12:27:20 -0800 Subject: [PATCH 8/9] Fix more typos in IndicesClient. --- .../src/main/java/org/elasticsearch/client/IndicesClient.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/IndicesClient.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/IndicesClient.java index f66ef6652fe0c..6ca926b2f72f1 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/IndicesClient.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/IndicesClient.java @@ -249,7 +249,7 @@ public void getMappingAsync(GetMappingsRequest getMappingsRequest, RequestOption * @return the response * @throws IOException in case there is a problem sending the request or parsing back the response * - * @deprecated This method uses an old request and response objects which still refer to types, a deprecated + * @deprecated This method uses old request and response objects which still refer to types, a deprecated * feature. The method {@link #getMapping(GetMappingsRequest, RequestOptions)} should be used instead, which * accepts a new request object. */ @@ -317,7 +317,7 @@ public org.elasticsearch.action.admin.indices.mapping.get.GetFieldMappingsRespon * @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 * - * @deprecated This method uses request and response objects which still refers to types, a deprecated feature. + * @deprecated This method uses old request and response objects which still refer to types, a deprecated feature. * The method {@link #getFieldMappingAsync(GetFieldMappingsRequest, RequestOptions, ActionListener)} should be * used instead, which accepts a new request object. */ From 705880dc8a183f6082343530db82d828315a69fc Mon Sep 17 00:00:00 2001 From: Julie Tibshirani Date: Sun, 27 Jan 2019 12:56:54 -0800 Subject: [PATCH 9/9] In GetMappingsResponseTests, switch to comparing client-side objects. --- .../indices/GetMappingsResponseTests.java | 43 ++++++++----------- 1 file changed, 18 insertions(+), 25 deletions(-) diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/indices/GetMappingsResponseTests.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/indices/GetMappingsResponseTests.java index e4122b9cf6255..0601609a8a766 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/indices/GetMappingsResponseTests.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/indices/GetMappingsResponseTests.java @@ -19,13 +19,11 @@ package org.elasticsearch.client.indices; -import org.elasticsearch.action.admin.indices.mapping.get.GetMappingsResponse; import org.elasticsearch.cluster.metadata.MappingMetaData; import org.elasticsearch.common.collect.ImmutableOpenMap; import org.elasticsearch.common.xcontent.ToXContent; import org.elasticsearch.common.xcontent.ToXContent.Params; import org.elasticsearch.common.xcontent.XContentBuilder; -import org.elasticsearch.common.xcontent.XContentParser; import org.elasticsearch.index.mapper.MapperService; import org.elasticsearch.rest.BaseRestHandler; import org.elasticsearch.test.ESTestCase; @@ -43,30 +41,31 @@ public class GetMappingsResponseTests extends ESTestCase { // Because the client-side class does not have a toXContent method, we test xContent serialization by creating - // a random server object, serializing it to xContent, then parsing it back as a client object. We check - // equality by converting the parsed client object to a server one, and comparing it to the original. + // a random client object, converting it to a server object then serializing it to xContent, and finally + // parsing it back as a client object. We check equality between the original client object, and the parsed one. public void testFromXContent() throws IOException { xContentTester( this::createParser, GetMappingsResponseTests::createTestInstance, GetMappingsResponseTests::toXContent, - GetMappingsResponseTests::fromXContent) + GetMappingsResponse::fromXContent) .supportsUnknownFields(true) - .randomFieldsExcludeFilter(getRandomFieldsExcludeFilter()) + .assertEqualsConsumer(GetMappingsResponseTests::assertEqualInstances) + .randomFieldsExcludeFilter(randomFieldsExcludeFilter()) .test(); } private static GetMappingsResponse createTestInstance() { - ImmutableOpenMap.Builder mappings = ImmutableOpenMap.builder(); - mappings.put(MapperService.SINGLE_MAPPING_NAME, randomMappingMetaData()); - - ImmutableOpenMap.Builder> allMappings = ImmutableOpenMap.builder(); - allMappings.put("index-" + randomAlphaOfLength(5), mappings.build()); + Map mappings = Collections.singletonMap( + "index-" + randomAlphaOfLength(5), randomMappingMetaData()); + return new GetMappingsResponse(mappings); + } - return new GetMappingsResponse(allMappings.build()); + private static void assertEqualInstances(GetMappingsResponse expected, GetMappingsResponse actual) { + assertEquals(expected.mappings(), actual.mappings()); } - private Predicate getRandomFieldsExcludeFilter() { + private Predicate randomFieldsExcludeFilter() { return field -> !field.equals(MAPPINGS.getPreferredName()); } @@ -103,17 +102,6 @@ private static Map randomFieldMapping() { private static void toXContent(GetMappingsResponse response, XContentBuilder builder) throws IOException { Params params = new ToXContent.MapParams( Collections.singletonMap(BaseRestHandler.INCLUDE_TYPE_NAME_PARAMETER, "false")); - - builder.startObject(); - response.toXContent(builder, params); - builder.endObject(); - } - - private static GetMappingsResponse fromXContent( - XContentParser parser) throws IOException { - org.elasticsearch.client.indices.GetMappingsResponse response = - org.elasticsearch.client.indices.GetMappingsResponse.fromXContent(parser); - ImmutableOpenMap.Builder> allMappings = ImmutableOpenMap.builder(); for (Map.Entry indexEntry : response.mappings().entrySet()) { @@ -122,6 +110,11 @@ private static GetMappingsResponse fromXContent( allMappings.put(indexEntry.getKey(), mappings.build()); } - return new GetMappingsResponse(allMappings.build()); + org.elasticsearch.action.admin.indices.mapping.get.GetMappingsResponse serverResponse = + new org.elasticsearch.action.admin.indices.mapping.get.GetMappingsResponse(allMappings.build()); + + builder.startObject(); + serverResponse.toXContent(builder, params); + builder.endObject(); } }