diff --git a/.code-samples.meilisearch.yaml b/.code-samples.meilisearch.yaml index 410b0118..3908a839 100644 --- a/.code-samples.meilisearch.yaml +++ b/.code-samples.meilisearch.yaml @@ -260,6 +260,18 @@ update_displayed_attributes_1: |- }); reset_displayed_attributes_1: |- client.index("movies").resetDisplayedAttributesSettings(); +getting_started_typo_tolerance: |- + HashMap minWordSizeTypos = + new HashMap() { + { + put("oneTypo", 4); + } + }; + + TypoTolerance typoTolerance = new TypoTolerance(); + typoTolerance.setMinWordSizeForTypos(minWordSizeTypos); + + client.index("movies").updateTypoToleranceSettings(typoTolerance); get_typo_tolerance_1: client.index("books").getTypoToleranceSettings(); update_typo_tolerance_1: |- @@ -311,7 +323,7 @@ update_non_separator_tokens_1: |- String[] newSeparatorTokens = { "@", "#" }; client.index("articles").updateNonSeparatorTokensSettings(newSeparatorTokens); reset_non_separator_tokens_1: |- - client.index("articles").resetNonSeparatorTokensSettings(); + client.index("articles").resetNonSeparatorTokensSettings(); get_dictionary_1: |- client.index("books").getDictionarySettings(); update_dictionary_1: |- @@ -511,9 +523,9 @@ search_parameter_guide_facet_stats_1: |- faceted_search_update_settings_1: client.index("movie_ratings").updateFilterableAttributesSettings(new String[] { - "genres", - "director", - "language" + "genres", + "director", + "language" }); faceted_search_walkthrough_filter_1: |- SearchRequest searchRequest = @@ -681,10 +693,9 @@ multi_search_1: |- multiIndexSearch.addQuery(new IndexSearchRequest("movie_ratings").setQuery("us")); client.multiSearch(multiSearchRequest); -get_similar_post_1: - SimilarDocumentRequest query = new SimilarDocumentRequest() - .setId("143") - .setEmbedder("manual"); +get_similar_post_1: SimilarDocumentRequest query = new SimilarDocumentRequest() + .setId("143") + .setEmbedder("manual"); client.index("movies").searchSimilarDocuments(query) search_parameter_reference_distinct_1: |- SearchRequest searchRequest = SearchRequest.builder().q("QUERY TERMS").distinct("ATTRIBUTE_A").build(); @@ -720,3 +731,23 @@ compact_index_1: |- client.index("INDEX_NAME").compact(); rename_an_index_1: |- client.updateIndex("indexA", null, "indexB"); +get_webhooks_1: |- + client.getWebhook(); +get_webhook_1: |- + client.getWebhook(); +create_webhook_1: |- + HashMap headers = new HashMap<>(); + headers.put("authorization", "MASTER_KEY"); + headers.put("referer", "http://example.com"); + CreateUpdateWebhookRequest webhookReq1 = new CreateUpdateWebhookRequest("http://webiste.com", headers); + + Webhook webhook = client.createWebhook(); +update_webhook_1: |- + Webhook webhook = this.client.createWebhook(webhookReq1); + HashMap headers = new HashMap<>(); + headers.put("referer", null); + CreateUpdateWebhookRequest webhookReq2 = new CreateUpdateWebhookRequest(webhook.getUrl(), headers); + + Webhook updated_webhook = this.client.updateWebhook(webhook.getUuid(), webhookReq2); +delete_webhook_1: |- + this.client.deleteWebhook("WEBHOOK_UUID"); diff --git a/src/main/java/com/meilisearch/sdk/Client.java b/src/main/java/com/meilisearch/sdk/Client.java index 888a52dd..356817f4 100644 --- a/src/main/java/com/meilisearch/sdk/Client.java +++ b/src/main/java/com/meilisearch/sdk/Client.java @@ -20,6 +20,7 @@ public class Client { private TasksHandler tasksHandler; private KeysHandler keysHandler; private JsonHandler jsonHandler; + private WebHooksHandler webHooksHandler; /** * Calls instance for Meilisearch client @@ -33,6 +34,7 @@ public Client(Config config) { this.tasksHandler = new TasksHandler(config); this.keysHandler = new KeysHandler(config); this.jsonHandler = config.jsonHandler; + this.webHooksHandler = new WebHooksHandler(config); } /** @@ -544,6 +546,64 @@ public String generateTenantToken( return jwtToken; } + /** + * Get a list of all webhooks configured in the current Meilisearch instance. + * + * @return List of all webhooks. + * @throws MeilisearchException if an error occurs. + */ + public Results getWebhooks() throws MeilisearchException { + return this.webHooksHandler.getWebhooks(); + } + + /** + * Get a webhook specified by its unique Uuid. + * + * @return A single Webhook instance. + * @param webhookUuid Uuid v4 identifier of a webhook. + * @throws MeilisearchException if an error occurs. + */ + public Webhook getWebhook(UUID webhookUuid) throws MeilisearchException { + return this.webHooksHandler.getWebhook(webhookUuid); + } + + /** + * Create a new webhook. When Meilisearch finishes processing a task, it sends the relevant task + * object to all configured webhooks + * + * @return A single Webhook instance. + * @param createUpdateWebhookRequest Request body containing headers and url for the new + * webhook. + * @throws MeilisearchException If an error occurs. + */ + public Webhook createWebhook(CreateUpdateWebhookRequest createUpdateWebhookRequest) + throws MeilisearchException { + return this.webHooksHandler.createWebhook(createUpdateWebhookRequest); + } + + /** + * Update the configuration for the specified webhook. To remove a field, set its value to null. + * + * @param webhook_uuid Uuid v4 identifier of a webhook. + * @param createUpdateWebhookRequest Request body containing new header or url. + * @return A single webhook instance. + * @throws MeilisearchException If an error occurs. + */ + public Webhook updateWebhook( + UUID webhook_uuid, CreateUpdateWebhookRequest createUpdateWebhookRequest) + throws MeilisearchException { + return this.webHooksHandler.updateWebhook(webhook_uuid, createUpdateWebhookRequest); + } + + /** + * Delete a webhook and stop sending task completion data to the target URL. + * + * @param webhook_uuid Uuid v4 identifier of a webhook. + */ + public void deleteWebhook(UUID webhook_uuid) throws MeilisearchException { + this.webHooksHandler.deleteWebhook(webhook_uuid); + } + private Boolean isValidUUID(String apiKeyUid) { try { UUID uuid = UUID.fromString(apiKeyUid); diff --git a/src/main/java/com/meilisearch/sdk/HttpClient.java b/src/main/java/com/meilisearch/sdk/HttpClient.java index 4b450036..f6474d53 100644 --- a/src/main/java/com/meilisearch/sdk/HttpClient.java +++ b/src/main/java/com/meilisearch/sdk/HttpClient.java @@ -154,7 +154,6 @@ T delete(String api, Class targetClass) throws MeilisearchException { HttpRequest requestConfig = request.create(HttpMethod.DELETE, api, this.headers, null); HttpResponse httpRequest = this.client.delete(requestConfig); HttpResponse httpResponse = response.create(httpRequest, targetClass); - if (httpResponse.getStatusCode() >= 400) { throw new MeilisearchApiException( jsonHandler.decode(httpRequest.getContent(), APIError.class)); diff --git a/src/main/java/com/meilisearch/sdk/WebHooksHandler.java b/src/main/java/com/meilisearch/sdk/WebHooksHandler.java new file mode 100644 index 00000000..4b0b376d --- /dev/null +++ b/src/main/java/com/meilisearch/sdk/WebHooksHandler.java @@ -0,0 +1,82 @@ +package com.meilisearch.sdk; + +import com.meilisearch.sdk.exceptions.MeilisearchException; +import com.meilisearch.sdk.http.URLBuilder; +import com.meilisearch.sdk.model.CreateUpdateWebhookRequest; +import com.meilisearch.sdk.model.Results; +import com.meilisearch.sdk.model.Webhook; +import java.util.UUID; + +public class WebHooksHandler { + private final HttpClient httpClient; + + protected WebHooksHandler(Config config) { + this.httpClient = config.httpClient; + } + + /** + * Gets a list of webhooks + * + * @return List of webhooks. + * @throws MeilisearchException if an error occurs + */ + Results getWebhooks() throws MeilisearchException { + return this.httpClient.get(webhooksPath().getURL(), Results.class, Webhook.class); + } + + /** + * Gets a webhook from its uuid + * + * @param uuid Unique identifier of the webhook to get + * @return Meilisearch API response as Webhook instance + * @throws MeilisearchException if an error occurs + */ + Webhook getWebhook(UUID uuid) throws MeilisearchException { + return this.httpClient.get( + webhooksPath().addSubroute(uuid.toString()).getURL(), Webhook.class); + } + + /** + * Create a new webhook + * + * @param createUpdateWebhookRequest Request body for creating a new webhook + * @return Meilisearch API response as Webhook instance + * @throws MeilisearchException if an error occurs + */ + Webhook createWebhook(CreateUpdateWebhookRequest createUpdateWebhookRequest) + throws MeilisearchException { + return this.httpClient.post( + webhooksPath().getURL(), createUpdateWebhookRequest, Webhook.class); + } + + /** + * Update a webhook + * + * @param webhookUuid Unique identifier of a webhook to update + * @param createUpdateWebhookRequest Request body for updating a webhook + * @return Meilisearch API response as Webhook instance + * @throws MeilisearchException if an error occurs + */ + Webhook updateWebhook(UUID webhookUuid, CreateUpdateWebhookRequest createUpdateWebhookRequest) + throws MeilisearchException { + return this.httpClient.patch( + webhooksPath().addSubroute(webhookUuid.toString()).getURL(), + createUpdateWebhookRequest, + Webhook.class); + } + + /** + * Delete a webhook + * + * @param webhookUuid Unique identifier of a webhook to update + * @throws MeilisearchException if an error occurs + */ + void deleteWebhook(UUID webhookUuid) throws MeilisearchException { + this.httpClient.delete( + webhooksPath().addSubroute(webhookUuid.toString()).getURL(), String.class); + } + + private URLBuilder webhooksPath() { + return new URLBuilder("/webhooks"); + } +} diff --git a/src/main/java/com/meilisearch/sdk/model/CreateUpdateWebhookRequest.java b/src/main/java/com/meilisearch/sdk/model/CreateUpdateWebhookRequest.java new file mode 100644 index 00000000..0d4b5851 --- /dev/null +++ b/src/main/java/com/meilisearch/sdk/model/CreateUpdateWebhookRequest.java @@ -0,0 +1,21 @@ +package com.meilisearch.sdk.model; + +import java.io.Serializable; +import java.util.HashMap; +import lombok.NonNull; + +/** + * Data structure used in request body while creating or updating a webhook. + * + * @see API Specification + */ +public class CreateUpdateWebhookRequest implements Serializable { + final String url; + final HashMap headers; + + public CreateUpdateWebhookRequest( + @NonNull String url, @NonNull HashMap headers) { + this.url = url; + this.headers = headers; + } +} diff --git a/src/main/java/com/meilisearch/sdk/model/Webhook.java b/src/main/java/com/meilisearch/sdk/model/Webhook.java new file mode 100644 index 00000000..ed832af9 --- /dev/null +++ b/src/main/java/com/meilisearch/sdk/model/Webhook.java @@ -0,0 +1,25 @@ +package com.meilisearch.sdk.model; + +import java.io.Serializable; +import java.util.HashMap; +import java.util.UUID; +import lombok.Getter; + +/** + * Webhook data structure. + * + * @see API specification + */ +public class Webhook implements Serializable { + @Getter protected final UUID uuid; + @Getter protected final String url; + @Getter protected final HashMap headers; + @Getter protected final boolean isEditable; + + public Webhook(UUID uuid, String url, HashMap headers, boolean isEditable) { + this.uuid = uuid; + this.url = url; + this.headers = headers; + this.isEditable = isEditable; + } +} diff --git a/src/test/java/com/meilisearch/integration/WebhooksTest.java b/src/test/java/com/meilisearch/integration/WebhooksTest.java new file mode 100644 index 00000000..851d3421 --- /dev/null +++ b/src/test/java/com/meilisearch/integration/WebhooksTest.java @@ -0,0 +1,150 @@ +package com.meilisearch.integration; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.*; + +import com.meilisearch.integration.classes.AbstractIT; +import com.meilisearch.sdk.model.CreateUpdateWebhookRequest; +import com.meilisearch.sdk.model.Results; +import com.meilisearch.sdk.model.Webhook; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.TimeZone; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; + +@Tag("integration") +public class WebhooksTest extends AbstractIT { + + @BeforeEach + public void initialize() { + this.setUp(); + this.setUpJacksonClient(); + TimeZone.setDefault(TimeZone.getTimeZone("UTC")); + } + + @AfterAll + static void cleanMeilisearch() { + cleanup(); + } + + void cleanUp() { + Results webhooks = client.getWebhooks(); + for (Webhook wb : webhooks.getResults()) { + client.deleteWebhook(wb.getUuid()); + } + } + + @Test + public void testCreateWebhook() throws Exception { + HashMap headers = new HashMap<>(); + headers.put("authorization", "MASTER_KEY"); + headers.put("referer", "http://example.com"); + CreateUpdateWebhookRequest webhookReq1 = + new CreateUpdateWebhookRequest("http://webiste.com", headers); + + Webhook webhook = this.client.createWebhook(webhookReq1); + + assertThat(webhook, is(instanceOf(Webhook.class))); + assertThat(webhook.getUuid(), is(notNullValue())); + assertThat(webhook.getHeaders(), is(notNullValue())); + assertThat(webhook.getUrl(), is(notNullValue())); + assertThat(webhook.isEditable(), is(notNullValue())); + cleanUp(); + } + + @Test + public void testGetWebhooks() throws Exception { + HashMap headers = new HashMap<>(); + headers.put("authorization", "MASTER_KEY"); + headers.put("referer", "http://example.com"); + CreateUpdateWebhookRequest webhookReq1 = + new CreateUpdateWebhookRequest("http://webiste.com", headers); + CreateUpdateWebhookRequest webhookReq2 = + new CreateUpdateWebhookRequest("http://webiste1.com", headers); + + this.client.createWebhook(webhookReq1); + this.client.createWebhook(webhookReq2); + + Results webhooks = client.getWebhooks(); + Webhook webhook = webhooks.getResults()[0]; + Webhook webhook1 = webhooks.getResults()[1]; + + assertThat(webhook, is(instanceOf(Webhook.class))); + assertThat(webhook.getUuid(), is(notNullValue())); + assertThat(webhook.getHeaders(), is(notNullValue())); + assertThat(webhook.getUrl(), is(notNullValue())); + assertThat(webhook.isEditable(), is(notNullValue())); + + assertThat(webhook1, is(instanceOf(Webhook.class))); + assertThat(webhook1.getUuid(), is(notNullValue())); + assertThat(webhook1.getHeaders(), is(notNullValue())); + assertThat(webhook1.getUrl(), is(notNullValue())); + assertThat(webhook1.isEditable(), is(notNullValue())); + cleanUp(); + } + + @Test + public void testGetWebhook() throws Exception { + HashMap headers = new HashMap<>(); + headers.put("authorization", "MASTER_KEY"); + headers.put("referer", "http://example.com"); + CreateUpdateWebhookRequest webhookReq1 = + new CreateUpdateWebhookRequest("http://webiste.com", headers); + + Webhook webhook = this.client.createWebhook(webhookReq1); + + Webhook webhook_res = client.getWebhook(webhook.getUuid()); + + assertThat(webhook_res, is(instanceOf(Webhook.class))); + assertThat(webhook_res.getUuid(), is(notNullValue())); + assertThat(webhook_res.getHeaders(), is(notNullValue())); + assertThat(webhook_res.getUrl(), is(notNullValue())); + assertThat(webhook_res.isEditable(), is(notNullValue())); + cleanUp(); + } + + @Test + public void testUpdateWebhook() throws Exception { + HashMap headers = new HashMap<>(); + headers.put("authorization", "MASTER_KEY"); + headers.put("referer", "http://example.com"); + CreateUpdateWebhookRequest webhookReq1 = + new CreateUpdateWebhookRequest("http://webiste.com", headers); + Webhook webhook = this.client.createWebhook(webhookReq1); + + headers.put("referer", null); + CreateUpdateWebhookRequest webhookReq2 = + new CreateUpdateWebhookRequest(webhook.getUrl(), headers); + + Webhook updated_webhook = this.client.updateWebhook(webhook.getUuid(), webhookReq2); + + assertThat(updated_webhook, is(instanceOf(Webhook.class))); + assertThat(updated_webhook.getUuid(), is(notNullValue())); + assertThat(updated_webhook.getHeaders(), is(notNullValue())); + assertThat(updated_webhook.getUrl(), is(notNullValue())); + assertThat(updated_webhook.isEditable(), is(notNullValue())); + assertThat(updated_webhook.getHeaders(), is(aMapWithSize(1))); + cleanUp(); + } + + @Test + public void testDeleteWebhook() throws Exception { + HashMap headers = new HashMap<>(); + headers.put("authorization", "MASTER_KEY"); + headers.put("referer", "http://example.com"); + CreateUpdateWebhookRequest webhookReq1 = + new CreateUpdateWebhookRequest("http://webiste.com", headers); + Webhook webhook = this.client.createWebhook(webhookReq1); + + this.client.deleteWebhook(webhook.getUuid()); + + List webhooks = Arrays.asList(this.client.getWebhooks().getResults()); + + assertThat(webhooks, hasSize(0)); + cleanUp(); + } +}