Browse Source

Deprecate the document create endpoint. (#36863)

Julie Tibshirani 6 years ago
parent
commit
ecb822c666
20 changed files with 349 additions and 46 deletions
  1. 10 2
      client/rest-high-level/src/main/java/org/elasticsearch/client/RequestConverters.java
  2. 7 7
      client/rest-high-level/src/test/java/org/elasticsearch/client/RequestConvertersTests.java
  3. 1 1
      docs/reference/docs/index_.asciidoc
  4. 2 3
      rest-api-spec/src/main/resources/rest-api-spec/api/create.json
  5. 3 5
      rest-api-spec/src/main/resources/rest-api-spec/test/create/10_with_id.yml
  6. 33 0
      rest-api-spec/src/main/resources/rest-api-spec/test/create/11_with_id_with_types.yml
  7. 3 1
      rest-api-spec/src/main/resources/rest-api-spec/test/create/15_without_id.yml
  8. 8 0
      rest-api-spec/src/main/resources/rest-api-spec/test/create/15_without_id_with_types.yml
  9. 6 5
      rest-api-spec/src/main/resources/rest-api-spec/test/create/30_internal_version.yml
  10. 35 0
      rest-api-spec/src/main/resources/rest-api-spec/test/create/31_internal_version_with_types.yml
  11. 3 3
      rest-api-spec/src/main/resources/rest-api-spec/test/create/35_external_version.yml
  12. 30 0
      rest-api-spec/src/main/resources/rest-api-spec/test/create/36_external_version_with_types.yml
  13. 3 4
      rest-api-spec/src/main/resources/rest-api-spec/test/create/40_routing.yml
  14. 43 0
      rest-api-spec/src/main/resources/rest-api-spec/test/create/41_routing_with_types.yml
  15. 9 5
      rest-api-spec/src/main/resources/rest-api-spec/test/create/60_refresh.yml
  16. 82 0
      rest-api-spec/src/main/resources/rest-api-spec/test/create/61_refresh_with_types.yml
  17. 7 6
      rest-api-spec/src/main/resources/rest-api-spec/test/create/70_nested.yml
  18. 41 0
      rest-api-spec/src/main/resources/rest-api-spec/test/create/71_nested_with_types.yml
  19. 7 3
      server/src/main/java/org/elasticsearch/rest/action/document/RestIndexAction.java
  20. 16 1
      server/src/test/java/org/elasticsearch/rest/action/document/RestIndexActionTests.java

+ 10 - 2
client/rest-high-level/src/main/java/org/elasticsearch/client/RequestConverters.java

@@ -299,8 +299,16 @@ final class RequestConverters {
 
     static Request index(IndexRequest indexRequest) {
         String method = Strings.hasLength(indexRequest.id()) ? HttpPut.METHOD_NAME : HttpPost.METHOD_NAME;
-        boolean isCreate = (indexRequest.opType() == DocWriteRequest.OpType.CREATE);
-        String endpoint = endpoint(indexRequest.index(), indexRequest.type(), indexRequest.id(), isCreate ? "_create" : null);
+
+        String endpoint;
+        if (indexRequest.opType() == DocWriteRequest.OpType.CREATE) {
+            endpoint = indexRequest.type().equals(MapperService.SINGLE_MAPPING_NAME)
+                ? endpoint(indexRequest.index(), "_create", indexRequest.id())
+                : endpoint(indexRequest.index(), indexRequest.type(), indexRequest.id(), "_create");
+        } else {
+            endpoint = endpoint(indexRequest.index(), indexRequest.type(), indexRequest.id());
+        }
+
         Request request = new Request(method, endpoint);
 
         Params parameters = new Params(request);

+ 7 - 7
client/rest-high-level/src/test/java/org/elasticsearch/client/RequestConvertersTests.java

@@ -661,7 +661,7 @@ public class RequestConvertersTests extends ESTestCase {
 
         Request request = RequestConverters.index(indexRequest);
         if (indexRequest.opType() == DocWriteRequest.OpType.CREATE) {
-            assertEquals("/" + index + "/_doc/" + id + "/_create", request.getEndpoint());
+            assertEquals("/" + index + "/_create/" + id, request.getEndpoint());
         } else if (id != null) {
             assertEquals("/" + index + "/_doc/" + id, request.getEndpoint());
         } else {
@@ -1685,17 +1685,17 @@ public class RequestConvertersTests extends ESTestCase {
             assertEquals("/a/b", endpointBuilder.build());
         }
         {
-            EndpointBuilder endpointBuilder = new EndpointBuilder().addPathPart("a").addPathPart("b").addPathPartAsIs("_create");
-            assertEquals("/a/b/_create", endpointBuilder.build());
+            EndpointBuilder endpointBuilder = new EndpointBuilder().addPathPart("a").addPathPart("b").addPathPartAsIs("_endpoint");
+            assertEquals("/a/b/_endpoint", endpointBuilder.build());
         }
 
         {
-            EndpointBuilder endpointBuilder = new EndpointBuilder().addPathPart("a", "b", "c").addPathPartAsIs("_create");
-            assertEquals("/a/b/c/_create", endpointBuilder.build());
+            EndpointBuilder endpointBuilder = new EndpointBuilder().addPathPart("a", "b", "c").addPathPartAsIs("_endpoint");
+            assertEquals("/a/b/c/_endpoint", endpointBuilder.build());
         }
         {
-            EndpointBuilder endpointBuilder = new EndpointBuilder().addPathPart("a").addPathPartAsIs("_create");
-            assertEquals("/a/_create", endpointBuilder.build());
+            EndpointBuilder endpointBuilder = new EndpointBuilder().addPathPart("a").addPathPartAsIs("_endpoint");
+            assertEquals("/a/_endpoint", endpointBuilder.build());
         }
     }
 

+ 1 - 1
docs/reference/docs/index_.asciidoc

@@ -189,7 +189,7 @@ Another option to specify `create` is to use the following uri:
 
 [source,js]
 --------------------------------------------------
-PUT twitter/_doc/1/_create
+PUT twitter/_create/1
 {
     "user" : "kimchy",
     "post_date" : "2009-11-15T14:12:12",

+ 2 - 3
rest-api-spec/src/main/resources/rest-api-spec/api/create.json

@@ -3,8 +3,8 @@
     "documentation": "http://www.elastic.co/guide/en/elasticsearch/reference/master/docs-index_.html",
     "methods": ["PUT","POST"],
     "url": {
-      "path": "/{index}/{type}/{id}/_create",
-      "paths": ["/{index}/{type}/{id}/_create"],
+      "path": "/{index}/_create/{id}",
+      "paths": ["/{index}/_create/{id}", "/{index}/{type}/{id}/_create"],
       "parts": {
         "id": {
           "type" : "string",
@@ -18,7 +18,6 @@
         },
         "type": {
           "type" : "string",
-          "required" : true,
           "description" : "The type of the document"
         }
       },

+ 3 - 5
rest-api-spec/src/main/resources/rest-api-spec/test/create/10_with_id.yml

@@ -1,25 +1,24 @@
 ---
 "Create with ID":
+ - skip:
+      version: " - 6.99.99"
+      reason: types are required in requests before 7.0.0
  - do:
       create:
           index:  test_1
-          type:   test
           id:     1
           body:   { foo: bar }
 
  - match:   { _index:   test_1 }
- - match:   { _type:    test }
  - match:   { _id:      "1"}
  - match:   { _version: 1}
 
  - do:
       get:
           index:  test_1
-          type:   test
           id:     1
 
  - match:   { _index:   test_1 }
- - match:   { _type:    test }
  - match:   { _id:      "1"}
  - match:   { _version: 1}
  - match:   { _source: { foo: bar }}
@@ -28,6 +27,5 @@
       catch:      conflict
       create:
           index:  test_1
-          type:   test
           id:     1
           body:   { foo: bar }

+ 33 - 0
rest-api-spec/src/main/resources/rest-api-spec/test/create/11_with_id_with_types.yml

@@ -0,0 +1,33 @@
+---
+"Create with ID":
+ - do:
+      create:
+          index:  test_1
+          type:   test
+          id:     1
+          body:   { foo: bar }
+
+ - match:   { _index:   test_1 }
+ - match:   { _type:    test }
+ - match:   { _id:      "1"}
+ - match:   { _version: 1}
+
+ - do:
+      get:
+          index:  test_1
+          type:   test
+          id:     1
+
+ - match:   { _index:   test_1 }
+ - match:   { _type:    test }
+ - match:   { _id:      "1"}
+ - match:   { _version: 1}
+ - match:   { _source: { foo: bar }}
+
+ - do:
+      catch:      conflict
+      create:
+          index:  test_1
+          type:   test
+          id:     1
+          body:   { foo: bar }

+ 3 - 1
rest-api-spec/src/main/resources/rest-api-spec/test/create/15_without_id.yml

@@ -1,8 +1,10 @@
 ---
 "Create without ID":
+ - skip:
+      version: " - 6.99.99"
+      reason: types are required in requests before 7.0.0
  - do:
       catch: param
       create:
           index:  test_1
-          type:   test
           body:   { foo: bar }

+ 8 - 0
rest-api-spec/src/main/resources/rest-api-spec/test/create/15_without_id_with_types.yml

@@ -0,0 +1,8 @@
+---
+"Create without ID":
+ - do:
+      catch: param
+      create:
+          index:  test_1
+          type:   test
+          body:   { foo: bar }

+ 6 - 5
rest-api-spec/src/main/resources/rest-api-spec/test/create/30_internal_version.yml

@@ -1,10 +1,11 @@
 ---
 "Internal version":
-
+ - skip:
+      version: " - 6.99.99"
+      reason: types are required in requests before 7.0.0
  - do:
       create:
           index:  test_1
-          type:   test
           id:     1
           body:   { foo: bar }
 
@@ -14,18 +15,18 @@
       catch: conflict
       create:
           index:  test_1
-          type:   test
           id:     1
           body:   { foo: bar }
 
 ---
 "Internal versioning with explicit version":
-
+ - skip:
+      version: " - 6.99.99"
+      reason: types are required in requests before 7.0.0
  - do:
       catch: bad_request
       create:
           index:          test
-          type:           test
           id:             3
           body:           { foo: bar }
           version:        5

+ 35 - 0
rest-api-spec/src/main/resources/rest-api-spec/test/create/31_internal_version_with_types.yml

@@ -0,0 +1,35 @@
+---
+"Internal version":
+
+ - do:
+      create:
+          index:  test_1
+          type:   test
+          id:     1
+          body:   { foo: bar }
+
+ - match:   { _version: 1}
+
+ - do:
+      catch: conflict
+      create:
+          index:  test_1
+          type:   test
+          id:     1
+          body:   { foo: bar }
+
+---
+"Internal versioning with explicit version":
+
+ - do:
+      catch: bad_request
+      create:
+          index:          test
+          type:           test
+          id:             3
+          body:           { foo: bar }
+          version:        5
+
+ - match: { status: 400 }
+ - match: { error.type: action_request_validation_exception }
+ - match: { error.reason: "Validation Failed: 1: create operations do not support explicit versions. use index instead;" }

+ 3 - 3
rest-api-spec/src/main/resources/rest-api-spec/test/create/35_external_version.yml

@@ -1,11 +1,12 @@
 ---
 "External version":
-
+ - skip:
+      version: " - 6.99.99"
+      reason: types are required in requests before 7.0.0
  - do:
       catch:              bad_request
       create:
           index:          test
-          type:           test
           id:             1
           body:           { foo: bar }
           version_type:   external
@@ -19,7 +20,6 @@
       catch:              bad_request
       create:
           index:          test
-          type:           test
           id:             2
           body:           { foo: bar }
           version_type:   external

+ 30 - 0
rest-api-spec/src/main/resources/rest-api-spec/test/create/36_external_version_with_types.yml

@@ -0,0 +1,30 @@
+---
+"External version":
+
+ - do:
+      catch:              bad_request
+      create:
+          index:          test
+          type:           test
+          id:             1
+          body:           { foo: bar }
+          version_type:   external
+          version:        0
+
+ - match: { status: 400 }
+ - match: { error.type: action_request_validation_exception }
+ - match: { error.reason: "Validation Failed: 1: create operations only support internal versioning. use index instead;" }
+
+ - do:
+      catch:              bad_request
+      create:
+          index:          test
+          type:           test
+          id:             2
+          body:           { foo: bar }
+          version_type:   external
+          version:        5
+
+ - match: { status: 400 }
+ - match: { error.type: action_request_validation_exception }
+ - match: { error.reason: "Validation Failed: 1: create operations only support internal versioning. use index instead;" }

+ 3 - 4
rest-api-spec/src/main/resources/rest-api-spec/test/create/40_routing.yml

@@ -1,6 +1,8 @@
 ---
 "Routing":
-
+ - skip:
+     version: " - 6.99.99"
+     reason: types are required in requests before 7.0.0
  - do:
      indices.create:
        index:    test_1
@@ -18,7 +20,6 @@
  - do:
       create:
           index:   test_1
-          type:    test
           id:      1
           routing: 5
           body:    { foo: bar }
@@ -26,7 +27,6 @@
  - do:
       get:
           index:   test_1
-          type:    test
           id:      1
           routing: 5
           stored_fields:  [_routing]
@@ -38,6 +38,5 @@
       catch: missing
       get:
           index:   test_1
-          type:    test
           id:      1
 

+ 43 - 0
rest-api-spec/src/main/resources/rest-api-spec/test/create/41_routing_with_types.yml

@@ -0,0 +1,43 @@
+---
+"Routing":
+
+ - do:
+     indices.create:
+       index:    test_1
+       body:
+         settings:
+           index:
+             number_of_shards: 5
+             number_of_routing_shards: 5
+             number_of_replicas: 0
+
+ - do:
+      cluster.health:
+          wait_for_status: green
+
+ - do:
+      create:
+          index:   test_1
+          type:    test
+          id:      1
+          routing: 5
+          body:    { foo: bar }
+
+ - do:
+      get:
+          index:   test_1
+          type:    test
+          id:      1
+          routing: 5
+          stored_fields:  [_routing]
+
+ - match:   { _id:              "1"}
+ - match:   { _routing:  "5"}
+
+ - do:
+      catch: missing
+      get:
+          index:   test_1
+          type:    test
+          id:      1
+

+ 9 - 5
rest-api-spec/src/main/resources/rest-api-spec/test/create/60_refresh.yml

@@ -1,6 +1,8 @@
 ---
 "Refresh":
-
+ - skip:
+      version: " - 6.99.99"
+      reason: types are required in requests before 7.0.0
  - do:
       indices.create:
           index:    test_1
@@ -11,7 +13,6 @@
  - do:
       create:
           index:   test_1
-          type:    test
           id:      1
           body:    { foo: bar }
 
@@ -27,7 +28,6 @@
  - do:
       create:
           index:   test_1
-          type:    test
           id:      2
           refresh: true
           body:    { foo: bar }
@@ -44,10 +44,12 @@
 
 ---
 "When refresh url parameter is an empty string that means \"refresh immediately\"":
+ - skip:
+      version: " - 6.99.99"
+      reason: types are required in requests before 7.0.0
  - do:
       create:
           index:   test_1
-          type:    test
           id:      1
           refresh: ""
           body:    { foo: bar }
@@ -64,10 +66,12 @@
 
 ---
 "refresh=wait_for waits until changes are visible in search":
+ - skip:
+      version: " - 6.99.99"
+      reason: types are required in requests before 7.0.0
  - do:
       index:
           index:   create_60_refresh_1
-          type:    test
           id:      create_60_refresh_id1
           body:    { foo: bar }
           refresh: wait_for

+ 82 - 0
rest-api-spec/src/main/resources/rest-api-spec/test/create/61_refresh_with_types.yml

@@ -0,0 +1,82 @@
+---
+"Refresh":
+
+ - do:
+      indices.create:
+          index:    test_1
+          body:
+              settings:
+                  index.refresh_interval: -1
+                  number_of_replicas: 0
+ - do:
+      create:
+          index:   test_1
+          type:    test
+          id:      1
+          body:    { foo: bar }
+
+ - do:
+      search:
+          rest_total_hits_as_int: true
+          index:   test_1
+          body:
+            query:   { term: { _id: 1 }}
+
+ - match: { hits.total: 0 }
+
+ - do:
+      create:
+          index:   test_1
+          type:    test
+          id:      2
+          refresh: true
+          body:    { foo: bar }
+ - is_true: forced_refresh
+
+ - do:
+      search:
+          rest_total_hits_as_int: true
+          index:   test_1
+          body:
+            query:   { term: { _id: 2 }}
+
+ - match: { hits.total: 1 }
+
+---
+"When refresh url parameter is an empty string that means \"refresh immediately\"":
+ - do:
+      create:
+          index:   test_1
+          type:    test
+          id:      1
+          refresh: ""
+          body:    { foo: bar }
+ - is_true: forced_refresh
+
+ - do:
+      search:
+          rest_total_hits_as_int: true
+          index:   test_1
+          body:
+            query:   { term: { _id: 1 }}
+
+ - match: { hits.total: 1 }
+
+---
+"refresh=wait_for waits until changes are visible in search":
+ - do:
+      index:
+          index:   create_60_refresh_1
+          type:    test
+          id:      create_60_refresh_id1
+          body:    { foo: bar }
+          refresh: wait_for
+ - is_false: forced_refresh
+
+ - do:
+      search:
+          rest_total_hits_as_int: true
+          index:   create_60_refresh_1
+          body:
+            query:   { term: { _id: create_60_refresh_id1 }}
+ - match: { hits.total: 1 }

+ 7 - 6
rest-api-spec/src/main/resources/rest-api-spec/test/create/70_nested.yml

@@ -1,16 +1,19 @@
 ---
 setup:
+  - skip:
+      version: " - 6.99.99"
+      reason: types are required in requests before 7.0.0
   - do:
       indices.create:
+          include_type_name: false
           index: test_1
           body:
               settings:
                   index.mapping.nested_objects.limit: 2
               mappings:
-                  test_type:
-                      properties:
-                          nested1:
-                              type: nested
+                properties:
+                    nested1:
+                        type: nested
 
 ---
 "Indexing a doc with No. nested objects less or equal to index.mapping.nested_objects.limit should succeed":
@@ -20,7 +23,6 @@ setup:
   - do:
       create:
           index:  test_1
-          type:   test_type
           id:     1
           body:
               "nested1" : [ { "foo": "bar" }, { "foo": "bar2" } ]
@@ -35,7 +37,6 @@ setup:
       catch: /The number of nested documents has exceeded the allowed limit of \[2\]. This limit can be set by changing the \[index.mapping.nested_objects.limit\] index level setting\./
       create:
           index:  test_1
-          type:   test_type
           id:     1
           body:
               "nested1" : [ { "foo": "bar" }, { "foo": "bar2" }, { "foo": "bar3" } ]

+ 41 - 0
rest-api-spec/src/main/resources/rest-api-spec/test/create/71_nested_with_types.yml

@@ -0,0 +1,41 @@
+---
+setup:
+  - do:
+      indices.create:
+          index: test_1
+          body:
+              settings:
+                  index.mapping.nested_objects.limit: 2
+              mappings:
+                  test_type:
+                      properties:
+                          nested1:
+                              type: nested
+
+---
+"Indexing a doc with No. nested objects less or equal to index.mapping.nested_objects.limit should succeed":
+  - skip:
+      version: " - 6.99.99"
+      reason:  index.mapping.nested_objects setting has been added in 7.0.0
+  - do:
+      create:
+          index:  test_1
+          type:   test_type
+          id:     1
+          body:
+              "nested1" : [ { "foo": "bar" }, { "foo": "bar2" } ]
+  - match:   { _version: 1}
+
+---
+"Indexing a doc with No. nested objects more than index.mapping.nested_objects.limit should fail":
+  - skip:
+      version: " - 6.99.99"
+      reason:  index.mapping.nested_objects setting has been added in 7.0.0
+  - do:
+      catch: /The number of nested documents has exceeded the allowed limit of \[2\]. This limit can be set by changing the \[index.mapping.nested_objects.limit\] index level setting\./
+      create:
+          index:  test_1
+          type:   test_type
+          id:     1
+          body:
+              "nested1" : [ { "foo": "bar" }, { "foo": "bar2" }, { "foo": "bar3" } ]

+ 7 - 3
server/src/main/java/org/elasticsearch/rest/action/document/RestIndexAction.java

@@ -42,15 +42,19 @@ import static org.elasticsearch.rest.RestRequest.Method.PUT;
 public class RestIndexAction extends BaseRestHandler {
     private static final DeprecationLogger deprecationLogger = new DeprecationLogger(
         LogManager.getLogger(RestDeleteAction.class));
-    public static final String TYPES_DEPRECATION_MESSAGE = "[types removal] Specifying types in " +
-        "document index requests is deprecated, use the /{index}/_doc/{id} or /{index}/_doc endpoints instead.";
+    public static final String TYPES_DEPRECATION_MESSAGE = "[types removal] Specifying types in document " +
+        "index requests is deprecated, use the typeless endpoints instead (/{index}/_doc/{id}, /{index}/_doc, " +
+        "or /{index}/_create/{id}).";
 
     public RestIndexAction(Settings settings, RestController controller) {
         super(settings);
         controller.registerHandler(POST, "/{index}/{type}", this); // auto id creation
         controller.registerHandler(PUT, "/{index}/{type}/{id}", this);
         controller.registerHandler(POST, "/{index}/{type}/{id}", this);
+
         CreateHandler createHandler = new CreateHandler(settings);
+        controller.registerHandler(PUT, "/{index}/_create/{id}", createHandler);
+        controller.registerHandler(POST, "/{index}/_create/{id}/", createHandler);
         controller.registerHandler(PUT, "/{index}/{type}/{id}/_create", createHandler);
         controller.registerHandler(POST, "/{index}/{type}/{id}/_create", createHandler);
     }
@@ -88,7 +92,7 @@ public class RestIndexAction extends BaseRestHandler {
     public RestChannelConsumer prepareRequest(final RestRequest request, final NodeClient client) throws IOException {
         IndexRequest indexRequest;
         final String type = request.param("type");
-        if (type.equals(MapperService.SINGLE_MAPPING_NAME) == false) {
+        if (type != null && type.equals(MapperService.SINGLE_MAPPING_NAME) == false) {
             deprecationLogger.deprecatedAndMaybeLog("index_with_types", TYPES_DEPRECATION_MESSAGE);
             indexRequest = new IndexRequest(request.param("index"), type, request.param("id"));
         } else {

+ 16 - 1
server/src/test/java/org/elasticsearch/rest/action/document/RestIndexActionTests.java

@@ -52,7 +52,22 @@ public class RestIndexActionTests extends RestActionTestCase {
         dispatchRequest(validRequest);
     }
 
-    public void testCreateOpTypeValidation() throws Exception {
+    public void testCreateWithTypeInPath() {
+        RestRequest deprecatedRequest = new FakeRestRequest.Builder(xContentRegistry())
+            .withMethod(RestRequest.Method.PUT)
+            .withPath("/some_index/some_type/some_id/_create")
+            .build();
+        dispatchRequest(deprecatedRequest);
+        assertWarnings(RestIndexAction.TYPES_DEPRECATION_MESSAGE);
+
+        RestRequest validRequest = new FakeRestRequest.Builder(xContentRegistry())
+            .withMethod(RestRequest.Method.PUT)
+            .withPath("/some_index/_create/some_id")
+            .build();
+        dispatchRequest(validRequest);
+    }
+
+    public void testCreateOpTypeValidation() {
         Settings settings = settings(Version.CURRENT).build();
         RestIndexAction.CreateHandler create = action.new CreateHandler(settings);