diff --git a/Makefile b/Makefile index d8f59f5f364a6b6a7dceec3c37cd58119f6be4f9..e4e786be648fa4c18f87476390fb3b82729a7802 100644 --- a/Makefile +++ b/Makefile @@ -1,10 +1,10 @@ SHELL = /bin/bash pre-setup:; @echo "Creating environment file from template" - @rm -f .env && envsubst < config/.env.sample > .env + @rm -f .env && envsubst < config/.env.sample | tr -d '\r' > .env setup:; @echo "Generating secret files from templates using environment file + variables" - @source .env && rm -f ./config/application/secret.properties && envsubst < config/application/secret.properties.sample > config/application/secret.properties + @source .env && rm -f ./config/application/secret.properties && envsubst < config/application/secret.properties.sample | tr -d '\r' > config/application/secret.properties dev-start:; source .env && mvn compile quarkus:dev clean:; diff --git a/docker-compose.gitlab.yaml b/docker-compose.gitlab.yaml index c87fd09e75c3bf5be825191e3ddd56e7bb4c041d..fbba762cb6b138e2e191b2e4a483c296985f3ba4 100644 --- a/docker-compose.gitlab.yaml +++ b/docker-compose.gitlab.yaml @@ -1,8 +1,8 @@ version: '3' services: - web: + gitlab: container_name: gitlab - image: 'gitlab/gitlab-ce:latest' + image: 'gitlab/gitlab-ee:14.7.7-ee.0' restart: always environment: VIRTUAL_HOST: "gitlab.dev.docker" @@ -19,4 +19,24 @@ services: - '/localdocker/gitlab/config:/etc/gitlab' - '/localdocker/gitlab/logs:/var/log/gitlab' - '/localdocker/gitlab/data:/var/opt/gitlab' + application: + build: + dockerfile: ./src/main/docker/Dockerfile.jvm + ports: + - 8090:8080 + environment: + - CONFIG_SECRET_PATH=/var/run/secrets/secret.properties + volumes: + - $CONFIG_SECRET_PATH:/var/run/secrets/secret.properties + deploy: + restart_policy: + condition: on-failure + max_attempts: 5 + resources: + limits: + cpus: '0.5' + memory: 256M + reservations: + cpus: '0.001' + memory: 192M diff --git a/src/main/java/org/eclipsefoundation/git/eca/model/WebhookBody.java b/src/main/java/org/eclipsefoundation/git/eca/model/WebhookBody.java new file mode 100644 index 0000000000000000000000000000000000000000..d898fa7c34fb19caa197efc4c87b4fabbdad98b4 --- /dev/null +++ b/src/main/java/org/eclipsefoundation/git/eca/model/WebhookBody.java @@ -0,0 +1,50 @@ +package org.eclipsefoundation.git.eca.model; + +import java.util.Date; + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder; +import com.google.auto.value.AutoValue; + +public abstract class WebhookBody { + public abstract Date getCreatedAt(); + public abstract Date getUpdatedAt(); + public abstract String getEventName(); + public abstract String getUserEmail(); + public abstract String getUserName(); + public abstract String getUserUsername(); + public abstract int getUserId(); + + public static abstract class Builder<T extends Builder<T>> { + public abstract T setCreatedAt(Date createdAt); + public abstract T setUpdatedAt(Date updatedAt); + public abstract T setEventName(String eventName); + public abstract T setUserEmail(String userEmail); + public abstract T setUserName(String userName); + public abstract T setUserUsername(String userUsername); + public abstract T setUserId(int userId); + } + + @AutoValue + @JsonDeserialize(builder = AutoValue_WebhookBody_GroupAccessWebhook.Builder.class) + public static abstract class GroupAccessWebhook extends WebhookBody { + public abstract String getGroupName(); + public abstract String getGroupPath(); + public abstract String getGroupAccess(); + public abstract int getGroupId(); + + public static Builder builder() { + return new AutoValue_WebhookBody_GroupAccessWebhook.Builder(); + } + + @AutoValue.Builder + @JsonPOJOBuilder(withPrefix = "set") + public static abstract class Builder extends WebhookBody.Builder<Builder> { + public abstract Builder setGroupName(String groupName); + public abstract Builder setGroupPath(String groupPath); + public abstract Builder setGroupAccess(String groupAccess); + public abstract Builder setGroupId(int groupId); + public abstract GroupAccessWebhook build(); + } + } +} diff --git a/src/main/java/org/eclipsefoundation/git/eca/resource/WebhookResource.java b/src/main/java/org/eclipsefoundation/git/eca/resource/WebhookResource.java new file mode 100644 index 0000000000000000000000000000000000000000..06ac65dbfc671d96bdc6b9d1a3e9f768310cc7d2 --- /dev/null +++ b/src/main/java/org/eclipsefoundation/git/eca/resource/WebhookResource.java @@ -0,0 +1,28 @@ +package org.eclipsefoundation.git.eca.resource; + +import javax.ws.rs.GET; +import javax.ws.rs.HeaderParam; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.core.Response; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@Path("webhooks") +public class WebhookResource { + private static final Logger LOGGER = LoggerFactory.getLogger(WebhookResource.class); + + @GET + @Path("group_access") + public Response ok(){ + return Response.ok().build(); + } + + @POST + @Path("group_access") + public Response ok(@HeaderParam("X-Gitlab-Event") String eventType, String json) { + LOGGER.error("Event type: {}, body: {}", eventType, json); + return Response.ok().build(); + } +} diff --git a/src/main/java/org/eclipsefoundation/git/eca/service/EventProcessingService.java b/src/main/java/org/eclipsefoundation/git/eca/service/EventProcessingService.java new file mode 100644 index 0000000000000000000000000000000000000000..3c4ff20721f1e06d2d36ac04c41204567c87711e --- /dev/null +++ b/src/main/java/org/eclipsefoundation/git/eca/service/EventProcessingService.java @@ -0,0 +1,20 @@ +/** + * Copyright (c) 2022 Eclipse Foundation + * + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * Author: Martin Lowe <martin.lowe@eclipse-foundation.org> + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.eclipsefoundation.git.eca.service; + +/** + * Interface for service that processes webhook events from Gitlab. + */ +public interface EventProcessingService { + + void processEvent(String eventType, String body); +} diff --git a/src/main/java/org/eclipsefoundation/git/eca/service/impl/AsyncEventProcessingService.java b/src/main/java/org/eclipsefoundation/git/eca/service/impl/AsyncEventProcessingService.java new file mode 100644 index 0000000000000000000000000000000000000000..a5e8fca774134ab0aa1972d6680efe0a63ece2c1 --- /dev/null +++ b/src/main/java/org/eclipsefoundation/git/eca/service/impl/AsyncEventProcessingService.java @@ -0,0 +1,57 @@ +package org.eclipsefoundation.git.eca.service.impl; + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +import javax.annotation.PostConstruct; +import javax.enterprise.context.ApplicationScoped; +import javax.inject.Inject; + +import org.eclipsefoundation.git.eca.model.WebhookBody.GroupAccessWebhook; +import org.eclipsefoundation.git.eca.service.EventProcessingService; + +import com.fasterxml.jackson.databind.ObjectMapper; + +/** + * Default asynchronous event pool for handling gitlab events. + */ +@ApplicationScoped +public class AsyncEventProcessingService implements EventProcessingService { + + @Inject + ObjectMapper objectMapper; + + private ExecutorService pool; + + @PostConstruct + void init() { + // create a fixed thread pool to queue events that come in + this.pool = Executors.newFixedThreadPool(5); + } + + @Override + public void processEvent(String eventType, String body) { + this.pool.execute(() -> { + switch (eventType) { + case "user_add_to_group": + case "user_update_for_group": + processGroupMembershipChange(null); + break; + case "user_add_to_team": + case "user_update_for_team": + processTeamMembershipChange(null); + break; + default: + } + }); + } + + private void processGroupMembershipChange(GroupAccessWebhook b) { + + } + + private void processTeamMembershipChange(GroupAccessWebhook b) { + + } + +}