diff --git a/doc/3/controllers/collection/create/index.md b/doc/3/controllers/collection/create/index.md new file mode 100644 index 00000000..856848fb --- /dev/null +++ b/doc/3/controllers/collection/create/index.md @@ -0,0 +1,64 @@ +--- +code: true +type: page +title: create +description: Creates a new collection +--- + +# create + +Creates a new [collection](/core/2/guides/essentials/store-access-data) in Kuzzle via the persistence engine, in the provided index. + +You can also provide an optional data mapping that allows you to exploit the full capabilities of our +persistent data storage layer, [ElasticSearch](https://www.elastic.co/elastic-stack) (check here the [mapping capabilities of ElasticSearch](https://www.elastic.co/guide/en/elasticsearch/reference/7.4/mapping.html)). + +This method will only update the mapping if the collection already exists. + +
+ +--- + +## Arguments + +```java +public CompletableFuture create( + final String index, + final String collection, + final ConcurrentHashMap mapping) +throws NotConnectedException, InternalException + +public CompletableFuture create( + final String index, + final String collection) +throws NotConnectedException, InternalException +``` + +| Arguments | Type | Description | +| ------------------ | -------------------------------------------- | --------------------------------- | +| `index` |
String
| Index | +| `collection` |
String
| Collection | +| `mapping` |
ConcurrentHashMap
| Describes the data mapping to associate to the new collection, using Elasticsearch [mapping format](https://www.elastic.co/guide/en/elasticsearch/reference/7.4/mapping.html) | + +--- + +### mapping + +A `ConcurrentHashMap` representing the data mapping of the collection. + +The mapping must have a root field `properties` that contain the mapping definition: + +```java + ConcurrentHashMap mapping = new ConcurrentHashMap<>(); + ConcurrentHashMap properties = new ConcurrentHashMap<>(); + ConcurrentHashMap field = new ConcurrentHashMap<>(); + + field.put("type", "keyword"); + properties.put("field", field); + mapping.put("properties", properties); +``` + +More information about database mappings [here](/core/2/guides/essentials/database-mappings). + +## Usage + +<<< ./snippets/create.java diff --git a/doc/3/controllers/collection/create/snippets/create.java b/doc/3/controllers/collection/create/snippets/create.java new file mode 100644 index 00000000..2e59f164 --- /dev/null +++ b/doc/3/controllers/collection/create/snippets/create.java @@ -0,0 +1,10 @@ + ConcurrentHashMap mapping = new ConcurrentHashMap<>(); + ConcurrentHashMap properties = new ConcurrentHashMap<>(); + ConcurrentHashMap license = new ConcurrentHashMap<>(); + + license.put("type", "keyword"); + properties.put("license", license); + mapping.put("properties", properties); + + kuzzle.getCollectionController().create("nyc-open-data", "yellow-taxi", mapping) + .get(); \ No newline at end of file diff --git a/doc/3/controllers/collection/create/snippets/create.test.yml b/doc/3/controllers/collection/create/snippets/create.test.yml new file mode 100644 index 00000000..ad25ec5b --- /dev/null +++ b/doc/3/controllers/collection/create/snippets/create.test.yml @@ -0,0 +1,9 @@ +name: collection#create +description: Creates a new collection +hooks: + before: | + curl -XDELETE kuzzle:7512/nyc-open-data + curl -XPOST kuzzle:7512/nyc-open-data/_create + after: +template: default +expected: Success \ No newline at end of file diff --git a/doc/3/controllers/document/m-update/snippets/m-update.test.yml b/doc/3/controllers/document/m-update/snippets/m-update.test.yml index 29ccba1f..b14ef60a 100644 --- a/doc/3/controllers/document/m-update/snippets/m-update.test.yml +++ b/doc/3/controllers/document/m-update/snippets/m-update.test.yml @@ -10,5 +10,5 @@ hooks: after: template: print-result-array expected: - - "id=some-id, status=200" - - "id=some-id2, status=200" \ No newline at end of file + - "id=some-id, _version=2, status=200" + - "id=some-id2, _version=2, status=200" \ No newline at end of file diff --git a/src/main/java/io/kuzzle/sdk/API/Controllers/CollectionController.java b/src/main/java/io/kuzzle/sdk/API/Controllers/CollectionController.java index cdf96dbe..78c410a3 100644 --- a/src/main/java/io/kuzzle/sdk/API/Controllers/CollectionController.java +++ b/src/main/java/io/kuzzle/sdk/API/Controllers/CollectionController.java @@ -40,6 +40,51 @@ public CompletableFuture exists( (response) -> (Boolean) response.result); } + /** + * Creates a collection in a given index. + * + * @param index + * @param collection + * @param mappings + * @return a CompletableFuture + * @throws NotConnectedException + * @throws InternalException + */ + public CompletableFuture create( + final String index, + final String collection, + final ConcurrentHashMap mappings) throws NotConnectedException, InternalException { + + final KuzzleMap query = new KuzzleMap(); + + query + .put("index", index) + .put("collection", collection) + .put("controller", "collection") + .put("action", "create") + .put("body", mappings != null ? new KuzzleMap(mappings) : null); + + return kuzzle + .query(query) + .thenApplyAsync((response) -> null); + } + + /** + * Creates a collection in a given index. + * + * @param index + * @param collection + * @return a CompletableFuture + * @throws NotConnectedException + * @throws InternalException + */ + public CompletableFuture create( + final String index, + final String collection) throws NotConnectedException, InternalException { + + return this.create(index, collection, null); + } + /** * Get collection mapping * diff --git a/src/test/java/io/kuzzle/test/API/Controllers/CollectionTest.java b/src/test/java/io/kuzzle/test/API/Controllers/CollectionTest.java index 99523b49..dca7b1c6 100644 --- a/src/test/java/io/kuzzle/test/API/Controllers/CollectionTest.java +++ b/src/test/java/io/kuzzle/test/API/Controllers/CollectionTest.java @@ -12,6 +12,8 @@ import org.mockito.Mockito; import org.mockito.stubbing.Answer; +import java.util.concurrent.ConcurrentHashMap; + import static org.junit.Assert.assertEquals; import static org.mockito.Mockito.spy; @@ -50,6 +52,72 @@ public void existsCollectionShouldThrowWhenNotConnected() throws NotConnectedExc kuzzleMock.getCollectionController().exists(index, collection); } + @Test + public void createCollectionTestA() throws NotConnectedException, InternalException { + + Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); + String index = "nyc-open-data"; + String collection = "yellow-taxi"; + + ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); + + kuzzleMock.getCollectionController().create(index, collection); + Mockito.verify(kuzzleMock, Mockito.times(1)).query(arg.capture()); + + assertEquals((arg.getValue()).getString("controller"), "collection"); + assertEquals((arg.getValue()).getString("action"), "create"); + assertEquals((arg.getValue()).getString("collection"), "yellow-taxi"); + assertEquals((arg.getValue()).getString("index"), "nyc-open-data"); + } + + @Test + public void createCollectionTestB() throws NotConnectedException, InternalException { + + Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); + String index = "nyc-open-data"; + String collection = "yellow-taxi"; + + ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); + + ConcurrentHashMap mapping = new ConcurrentHashMap<>(); + ConcurrentHashMap properties = new ConcurrentHashMap<>(); + ConcurrentHashMap license = new ConcurrentHashMap<>(); + + license.put("type", "keyword"); + properties.put("license", license); + mapping.put("properties", properties); + + kuzzleMock.getCollectionController().create(index, collection, mapping); + Mockito.verify(kuzzleMock, Mockito.times(1)).query(arg.capture()); + + assertEquals((arg.getValue()).getString("controller"), "collection"); + assertEquals((arg.getValue()).getString("action"), "create"); + assertEquals((arg.getValue()).getString("index"), "nyc-open-data"); + assertEquals((arg.getValue()).getString("collection"), "yellow-taxi"); + assertEquals(( + (ConcurrentHashMap) ( + (ConcurrentHashMap) ( + ((ConcurrentHashMap) + ((arg.getValue()) + .get("body"))) + .get("properties"))) + .get("license")) + .get("type").toString(), "keyword"); + } + + @Test(expected = NotConnectedException.class) + public void createCollectionThrowWhenNotConnected() 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"; + + kuzzleMock.getCollectionController().create(index, collection); + } + @Test public void getMappingCollectionTest() throws NotConnectedException, InternalException {