diff --git a/doc/3/controllers/document/m-create/index.md b/doc/3/controllers/document/m-create/index.md new file mode 100644 index 00000000..f26864fa --- /dev/null +++ b/doc/3/controllers/document/m-create/index.md @@ -0,0 +1,70 @@ +--- +code: true +type: page +title: mCreate +description: Creates multiple documents +--- + +# mCreate + +Creates multiple documents. + +--- + +## Arguments + +```java +public CompletableFuture>> mCreate( + final String index, + final String collection, + final ArrayList> documents) +throws NotConnectedException, InternalException + +public CompletableFuture>> mCreate( + final String index, + final String collection, + final ArrayList> documents, + final Boolean waitForRefresh) +throws NotConnectedException, InternalException +``` + +| Arguments | Type | Description | +| ------------------ | ------------------------------------------------------- | --------------------------------- | +| `index` |
String
| Index | +| `collection` |
String
| Collection | +| `documents` |
ArrayList>
| ArrayList containing the documents to create | +| `waitForRefresh` |
Boolean
| If set to `true`, Kuzzle will wait for the persistence layer to finish indexing | + +--- + +### documents + +Each document has the following properties: + +| Arguments | Type | Description | +| ------------------ | -------------------------------------------- | --------------------------------- | +| `_id` |
String
| Optional document ID. Will be auto-generated if not defined. | +| `body` |
ConcurrentHashMap
| Document body | + +## Return + +A `ConcurrentHashMap>` which has a `successes` and `errors` `ArrayList`: +Each created document is an object of the `successes` array with the following properties: + +| Property | Type | Description | +|------------- |--------------------------------------------- |--------------------------------- | +| `_source` |
ConcurrentHashMap
| Created document | +| `_id` |
String
| ID of the newly created document | +| `_version` |
Integer
| Version of the document in the persistent data storage | + +Each errored document is an object of the `errors` array with the following properties: + +| Property | Type | Description | +|------------- |--------------------------------------------- |--------------------------------- | +| `document` |
ConcurrentHashMap
| Document that causes the error | +| `status` |
Integer
| HTTP error status | +| `reason` |
String
| Human readable reason | + +## Usage + +<<< ./snippets/m-create.java diff --git a/doc/3/controllers/document/m-create/snippets/m-create.java b/doc/3/controllers/document/m-create/snippets/m-create.java new file mode 100644 index 00000000..24f9696f --- /dev/null +++ b/doc/3/controllers/document/m-create/snippets/m-create.java @@ -0,0 +1,54 @@ +ConcurrentHashMap document1 = new ConcurrentHashMap<>(); +ConcurrentHashMap document2 = new ConcurrentHashMap<>(); +ConcurrentHashMap body = new ConcurrentHashMap<>(); +ConcurrentHashMap body2 = new ConcurrentHashMap<>(); + +body.put("Agent", "Smith"); +body2.put("Gordon", "Freeman"); + +document1.put("_id", "some-id"); +document1.put("body", body); + +document2.put("_id", "some-id2"); +document2.put("body", body2); + +final ArrayList> documents = new ArrayList<>(); +documents.add(document1); +documents.add(document2); + +ConcurrentHashMap> result = kuzzle + .getDocumentController() + .mCreate("nyc-open-data", "yellow-taxi", documents) + .get(); + +/* +result = + { + successes= + [ + { + result=created, + _source= + { + Agent=Smith, + _kuzzle_info={createdAt=1582892842099, author=-1} + }, + _id=some-id, + _version=1, + status=201 + }, + { + result=created, + _source= + { + Gordon=Freeman, + _kuzzle_info={createdAt=1582892842099, author=-1} + }, + _id=some-id2, + _version=1, + status=201 + } + ], + errors=[] + } +*/ diff --git a/doc/3/controllers/document/m-create/snippets/m-create.test.yml b/doc/3/controllers/document/m-create/snippets/m-create.test.yml new file mode 100644 index 00000000..a513ed5a --- /dev/null +++ b/doc/3/controllers/document/m-create/snippets/m-create.test.yml @@ -0,0 +1,12 @@ +name: document#mCreate +description: Creates multiple documents +hooks: + before: | + curl -XDELETE kuzzle:7512/nyc-open-data + curl -XPOST kuzzle:7512/nyc-open-data/_create + curl -XPUT kuzzle:7512/nyc-open-data/yellow-taxi + after: +template: print-result-array +expected: + - "id=some-id, _version=1, status=201" + - "id=some-id2, _version=1, status=201" \ No newline at end of file diff --git a/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java b/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java index ad4f7c84..c3c97cd6 100644 --- a/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java +++ b/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java @@ -74,6 +74,56 @@ public CompletableFuture> create( return this.create(index, collection, document, null); } + /** + * Creates multiple documents in a given collection and index. + * + * @param index + * @param collection + * @param documents + * @param waitForRefresh + * @return a CompletableFuture + * @throws NotConnectedException + * @throws InternalException + */ + public CompletableFuture>> mCreate( + final String index, + final String collection, + final ArrayList> documents, + final Boolean waitForRefresh) throws NotConnectedException, InternalException { + + final KuzzleMap query = new KuzzleMap(); + query + .put("index", index) + .put("collection", collection) + .put("controller", "document") + .put("action", "mCreate") + .put("body", new KuzzleMap().put("documents", documents)) + .put("waitForRefresh", waitForRefresh); + + return kuzzle + .query(query) + .thenApplyAsync( + (response) -> (ConcurrentHashMap>) response.result); + } + + /** + * Creates multiple documents in a given collection and index. + * + * @param index + * @param collection + * @param documents + * @return a CompletableFuture + * @throws NotConnectedException + * @throws InternalException + */ + public CompletableFuture>> mCreate( + final String index, + final String collection, + final ArrayList> documents) throws NotConnectedException, InternalException { + + return this.mCreate(index, collection, documents, null); + } + /** * Deletes multiple documents. * diff --git a/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java b/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java index 72f40540..9bf7177c 100644 --- a/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java +++ b/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java @@ -95,6 +95,107 @@ public void createDocumentThrowWhenNotConnected() throws NotConnectedException, } + @Test + public void mCreateDocumentTestA() throws NotConnectedException, InternalException { + + Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); + String index = "nyc-open-data"; + String collection = "yellow-taxi"; + + ConcurrentHashMap document1 = new ConcurrentHashMap<>(); + ConcurrentHashMap document2 = new ConcurrentHashMap<>(); + ConcurrentHashMap body1 = new ConcurrentHashMap<>(); + ConcurrentHashMap body2 = new ConcurrentHashMap<>(); + + document1.put("_id", "some-id1"); + body1.put("key1", "value1"); + document1.put("body", body1); + + document2.put("_id", "some-id2"); + body2.put("key2", "value2"); + document2.put("body", body2); + + final ArrayList> documents = new ArrayList<>(); + documents.add(document1); + documents.add(document2); + + ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); + + kuzzleMock.getDocumentController().mCreate(index, collection, documents); + Mockito.verify(kuzzleMock, Mockito.times(1)).query(arg.capture()); + + assertEquals((arg.getValue()).getString("controller"), "document"); + assertEquals((arg.getValue()).getString("action"), "mCreate"); + assertEquals((arg.getValue()).getString("index"), "nyc-open-data"); + assertEquals((arg.getValue()).getBoolean("waitForRefresh"), null); + assertEquals(((ArrayList>)(((KuzzleMap)(arg.getValue()).get("body"))).get("documents")).get(0).get("_id").toString(), "some-id1"); + assertEquals(((ArrayList>)(((KuzzleMap)(arg.getValue()).get("body"))).get("documents")).get(1).get("_id").toString(), "some-id2"); + } + + @Test + public void mCreateDocumentTestB() throws NotConnectedException, InternalException { + + Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); + String index = "nyc-open-data"; + String collection = "yellow-taxi"; + + ConcurrentHashMap document1 = new ConcurrentHashMap<>(); + ConcurrentHashMap document2 = new ConcurrentHashMap<>(); + ConcurrentHashMap body = new ConcurrentHashMap<>(); + + document1.put("_id", "some-id1"); + body.put("key1", "value1"); + document1.put("body", body); + + document2.put("_id", "some-id2"); + body.put("key2", "value2"); + document2.put("body", body); + + final ArrayList> documents = new ArrayList<>(); + documents.add(document1); + documents.add(document2); + + ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); + + kuzzleMock.getDocumentController().mCreate(index, collection, documents, false); + Mockito.verify(kuzzleMock, Mockito.times(1)).query(arg.capture()); + + assertEquals((arg.getValue()).getString("controller"), "document"); + assertEquals((arg.getValue()).getString("action"), "mCreate"); + assertEquals((arg.getValue()).getString("index"), "nyc-open-data"); + assertEquals((arg.getValue()).getBoolean("waitForRefresh"), false); + assertEquals(((ArrayList>)(((KuzzleMap)(arg.getValue()).get("body"))).get("documents")).get(0).get("_id").toString(), "some-id1"); + assertEquals(((ArrayList>)(((KuzzleMap)(arg.getValue()).get("body"))).get("documents")).get(1).get("_id").toString(), "some-id2"); + } + + @Test(expected = NotConnectedException.class) + public void mCreateDocumentShouldThrowWhenNotConnected() throws NotConnectedException, InternalException { + AbstractProtocol fakeNetworkProtocol = Mockito.mock(WebSocket.class); + Mockito.when(fakeNetworkProtocol.getState()).thenAnswer((Answer) invocation -> ProtocolState.CLOSE); + + Kuzzle kuzzleMock = spy(new Kuzzle(fakeNetworkProtocol)); + String index = "nyc-open-data"; + String collection = "yellow-taxi"; + + ConcurrentHashMap document1 = new ConcurrentHashMap<>(); + ConcurrentHashMap document2 = new ConcurrentHashMap<>(); + ConcurrentHashMap body = new ConcurrentHashMap<>(); + + document1.put("_id", "some-id1"); + body.put("key1", "value1"); + document1.put("body", body); + + document2.put("_id", "some-id2"); + body.put("key2", "value2"); + document2.put("body", body); + + final ArrayList> documents = new ArrayList<>(); + documents.add(document1); + documents.add(document2); + + kuzzleMock.getDocumentController().mCreate(index, collection, documents); + } + @Test public void mDeleteDocumentTestA() throws NotConnectedException, InternalException {