From 1dcccd6584f6be6d1c22a2018937489cb6a95505 Mon Sep 17 00:00:00 2001 From: Olivier Levitt Date: Fri, 20 Sep 2024 11:40:46 +0200 Subject: [PATCH 1/2] Add events webhook --- .../api/events/WebhookEventListener.java | 107 ++++++++++++++++++ .../src/main/resources/application.properties | 8 ++ 2 files changed, 115 insertions(+) create mode 100644 onyxia-api/src/main/java/fr/insee/onyxia/api/events/WebhookEventListener.java diff --git a/onyxia-api/src/main/java/fr/insee/onyxia/api/events/WebhookEventListener.java b/onyxia-api/src/main/java/fr/insee/onyxia/api/events/WebhookEventListener.java new file mode 100644 index 00000000..d6219cb5 --- /dev/null +++ b/onyxia-api/src/main/java/fr/insee/onyxia/api/events/WebhookEventListener.java @@ -0,0 +1,107 @@ +package fr.insee.onyxia.api.events; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import okhttp3.MediaType; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.RequestBody; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.event.EventListener; +import org.springframework.scheduling.annotation.Async; +import org.springframework.scheduling.annotation.EnableAsync; +import org.springframework.stereotype.Component; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +@EnableAsync +@Component +@ConditionalOnProperty(name = "event.webhook.enabled", havingValue = "true") +public class WebhookEventListener { + + private final ObjectMapper objectMapper; + + private static final MediaType JSON = MediaType.get("application/json"); + + private static final Logger LOGGER = LoggerFactory.getLogger(WebhookEventListener.class); + + @Value("${event.webhook.url}") + private String url; + + @Value("${event.webhook.includes}") + private List includes = new ArrayList<>(); + + @Value("${event.webhook.excludes}") + private List excludes = new ArrayList<>(); + + private final OkHttpClient httpClient; + + @Autowired + public WebhookEventListener(ObjectMapper objectMapper, OkHttpClient okHttpClient) { + this.objectMapper = objectMapper; + this.httpClient = okHttpClient; + } + + @Async + @EventListener + public void onOnyxiaEvent(OnyxiaEvent onyxiaEvent) throws JsonProcessingException { + if (!includes.isEmpty()) { + if (!includes.contains(onyxiaEvent.getType())) { + return; + } + } + if (!excludes.isEmpty()) { + if (excludes.contains(onyxiaEvent.getType())) { + return; + } + } + RequestBody body = RequestBody.create(objectMapper.writeValueAsString(onyxiaEvent), JSON); + Request request = new Request.Builder() + .url(url) + .post(body) + .build(); + try { + httpClient.newCall(request).execute(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public ObjectMapper getObjectMapper() { + return objectMapper; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public List getIncludes() { + return includes; + } + + public void setIncludes(List includes) { + this.includes = includes; + } + + public List getExcludes() { + return excludes; + } + + public void setExcludes(List excludes) { + this.excludes = excludes; + } + + public OkHttpClient getHttpClient() { + return httpClient; + } +} diff --git a/onyxia-api/src/main/resources/application.properties b/onyxia-api/src/main/resources/application.properties index 36f11194..4a79c4d0 100644 --- a/onyxia-api/src/main/resources/application.properties +++ b/onyxia-api/src/main/resources/application.properties @@ -29,5 +29,13 @@ springdoc.swagger-ui.oauth.clientId= springdoc.swagger-ui.oauth.clientSecret= # Enable events logging event.logging.enabled=true +# Enable events webhook +event.webhook.enabled=false +# URL to send the events to +event.webhook.url= +# List of events types to send the webhook for (empty = all events). e.g service.uninstall,service.install +event.webhook.includes= +# List of events types to ignore for the webhook. e.g service.uninstall,service.install +event.webhook.excludes= # Response stream configuration spring.mvc.async.request-timeout=600000 \ No newline at end of file From db912dfaee0557f07fac3753653c818a9a6ebfbb Mon Sep 17 00:00:00 2001 From: Olivier Levitt Date: Fri, 20 Sep 2024 11:43:57 +0200 Subject: [PATCH 2/2] Fix spotless --- .../onyxia/api/events/WebhookEventListener.java | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/onyxia-api/src/main/java/fr/insee/onyxia/api/events/WebhookEventListener.java b/onyxia-api/src/main/java/fr/insee/onyxia/api/events/WebhookEventListener.java index d6219cb5..af2f53fd 100644 --- a/onyxia-api/src/main/java/fr/insee/onyxia/api/events/WebhookEventListener.java +++ b/onyxia-api/src/main/java/fr/insee/onyxia/api/events/WebhookEventListener.java @@ -2,6 +2,9 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; import okhttp3.MediaType; import okhttp3.OkHttpClient; import okhttp3.Request; @@ -16,10 +19,6 @@ import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.stereotype.Component; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - @EnableAsync @Component @ConditionalOnProperty(name = "event.webhook.enabled", havingValue = "true") @@ -62,10 +61,7 @@ public void onOnyxiaEvent(OnyxiaEvent onyxiaEvent) throws JsonProcessingExceptio } } RequestBody body = RequestBody.create(objectMapper.writeValueAsString(onyxiaEvent), JSON); - Request request = new Request.Builder() - .url(url) - .post(body) - .build(); + Request request = new Request.Builder().url(url).post(body).build(); try { httpClient.newCall(request).execute(); } catch (IOException e) {