From 7662caab997c619326662a818bca885b4e0634d4 Mon Sep 17 00:00:00 2001 From: ahmed-ali-55 Date: Mon, 28 Aug 2023 19:15:08 +0200 Subject: [PATCH] listen webhook. work in progress --- build.gradle.kts | 3 - .../adapter/graphql/GitlabGraphqlProvider.kt | 6 +- .../application/RepositoryService.kt | 4 +- .../application/WebhookConsumerServiceImpl.kt | 45 ++++++ .../domain/WebhookConsumerService.kt | 5 + .../broker/connector/domain/WebhookData.kt | 52 +++++++ .../connector/domain/WebhookEventType.kt | 6 + .../broker/connector/json/GitlabParseUtil.kt | 22 +++ .../connector/rest/GitlabWebhookController.kt | 49 ++++++ .../connector/runner/InitialStateRunner.kt | 2 +- .../broker/shared/exception/Exceptions.kt | 10 ++ .../broker/shared/exception/VsmException.kt | 8 - .../connector/json/GitlabParseUtilTest.kt | 43 ++++++ .../webhook_calls/merge_request_merged.json | 145 ++++++++++++++++++ .../webhook_calls/merge_request_opened.json | 145 ++++++++++++++++++ .../webhook_calls/project_created.json | 18 +++ 16 files changed, 546 insertions(+), 17 deletions(-) create mode 100644 src/main/kotlin/net/leanix/vsm/gitlab/broker/connector/application/WebhookConsumerServiceImpl.kt create mode 100644 src/main/kotlin/net/leanix/vsm/gitlab/broker/connector/domain/WebhookConsumerService.kt create mode 100644 src/main/kotlin/net/leanix/vsm/gitlab/broker/connector/domain/WebhookData.kt create mode 100644 src/main/kotlin/net/leanix/vsm/gitlab/broker/connector/domain/WebhookEventType.kt create mode 100644 src/main/kotlin/net/leanix/vsm/gitlab/broker/connector/json/GitlabParseUtil.kt create mode 100644 src/main/kotlin/net/leanix/vsm/gitlab/broker/connector/rest/GitlabWebhookController.kt create mode 100644 src/main/kotlin/net/leanix/vsm/gitlab/broker/shared/exception/Exceptions.kt delete mode 100644 src/main/kotlin/net/leanix/vsm/gitlab/broker/shared/exception/VsmException.kt create mode 100644 src/test/kotlin/net/leanix/vsm/gitlab/broker/connector/json/GitlabParseUtilTest.kt create mode 100644 src/test/resources/webhook_calls/merge_request_merged.json create mode 100644 src/test/resources/webhook_calls/merge_request_opened.json create mode 100644 src/test/resources/webhook_calls/project_created.json diff --git a/build.gradle.kts b/build.gradle.kts index 0bd84d6..d505f20 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -26,8 +26,6 @@ val springCloudVersion: String by extra("2022.0.3") dependencies { implementation("org.springframework.boot:spring-boot-starter-actuator") - implementation("org.springframework.boot:spring-boot-starter-oauth2-client") - implementation("org.springframework.boot:spring-boot-starter-security") implementation("org.springframework.boot:spring-boot-starter-validation") implementation("org.springframework.cloud:spring-cloud-starter-openfeign") implementation("org.springframework.boot:spring-boot-starter-web") @@ -37,7 +35,6 @@ dependencies { implementation("io.github.oshai:kotlin-logging-jvm:5.1.0") testImplementation("org.springframework.boot:spring-boot-starter-test") testImplementation("org.springframework.cloud:spring-cloud-starter-contract-stub-runner") - testImplementation("org.springframework.security:spring-security-test") testImplementation("org.awaitility:awaitility-kotlin:4.2.0") testImplementation("com.ninja-squad:springmockk:4.0.2") diff --git a/src/main/kotlin/net/leanix/vsm/gitlab/broker/connector/adapter/graphql/GitlabGraphqlProvider.kt b/src/main/kotlin/net/leanix/vsm/gitlab/broker/connector/adapter/graphql/GitlabGraphqlProvider.kt index 1ae81ef..8c08721 100644 --- a/src/main/kotlin/net/leanix/vsm/gitlab/broker/connector/adapter/graphql/GitlabGraphqlProvider.kt +++ b/src/main/kotlin/net/leanix/vsm/gitlab/broker/connector/adapter/graphql/GitlabGraphqlProvider.kt @@ -11,8 +11,8 @@ import net.leanix.vsm.gitlab.broker.connector.adapter.graphql.parser.LanguagePar import net.leanix.vsm.gitlab.broker.connector.domain.GitLabAssignment import net.leanix.vsm.gitlab.broker.connector.domain.GitlabProvider import net.leanix.vsm.gitlab.broker.connector.domain.Repository -import net.leanix.vsm.gitlab.broker.shared.exception.VsmException -import net.leanix.vsm.gitlab.broker.shared.exception.VsmException.GraphqlException +import net.leanix.vsm.gitlab.broker.shared.exception.GraphqlException +import net.leanix.vsm.gitlab.broker.shared.exception.NoRepositoriesFound import net.leanix.vsm.gitlab.broker.shared.properties.GitLabOnPremProperties import org.springframework.http.HttpHeaders import org.springframework.stereotype.Component @@ -83,7 +83,7 @@ class GitlabGraphqlProvider(private val gitLabOnPremProperties: GitLabOnPremProp } } else { logger.info { "Zero repositories found" } - throw VsmException.NoRepositoriesFound() + throw NoRepositoriesFound() } } diff --git a/src/main/kotlin/net/leanix/vsm/gitlab/broker/connector/application/RepositoryService.kt b/src/main/kotlin/net/leanix/vsm/gitlab/broker/connector/application/RepositoryService.kt index 48ef51c..52b7c2a 100644 --- a/src/main/kotlin/net/leanix/vsm/gitlab/broker/connector/application/RepositoryService.kt +++ b/src/main/kotlin/net/leanix/vsm/gitlab/broker/connector/application/RepositoryService.kt @@ -7,7 +7,7 @@ import net.leanix.vsm.gitlab.broker.connector.domain.GitlabProvider import net.leanix.vsm.gitlab.broker.connector.domain.Repository import net.leanix.vsm.gitlab.broker.connector.domain.RepositoryProvider import net.leanix.vsm.gitlab.broker.logs.domain.LogStatus -import net.leanix.vsm.gitlab.broker.shared.exception.VsmException +import net.leanix.vsm.gitlab.broker.shared.exception.NoRepositoriesFound import org.springframework.stereotype.Service @Service @@ -45,7 +45,7 @@ class RepositoryService( private fun handleExceptions(exception: Throwable, assignment: GitLabAssignment) { when (exception) { - is VsmException.NoRepositoriesFound -> { + is NoRepositoriesFound -> { logFailedMessages("vsm.repos.not_found", arrayOf(assignment.connectorConfiguration.orgName), assignment) } } diff --git a/src/main/kotlin/net/leanix/vsm/gitlab/broker/connector/application/WebhookConsumerServiceImpl.kt b/src/main/kotlin/net/leanix/vsm/gitlab/broker/connector/application/WebhookConsumerServiceImpl.kt new file mode 100644 index 0000000..62a1b37 --- /dev/null +++ b/src/main/kotlin/net/leanix/vsm/gitlab/broker/connector/application/WebhookConsumerServiceImpl.kt @@ -0,0 +1,45 @@ +package net.leanix.vsm.gitlab.broker.connector.application + +import com.fasterxml.jackson.databind.DeserializationFeature +import com.fasterxml.jackson.databind.ObjectMapper +import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper +import com.fasterxml.jackson.module.kotlin.readValue +import net.leanix.vsm.gitlab.broker.connector.domain.MergeRequest +import net.leanix.vsm.gitlab.broker.connector.domain.ProjectCreated +import net.leanix.vsm.gitlab.broker.connector.domain.WebhookConsumerService +import net.leanix.vsm.gitlab.broker.connector.domain.WebhookEventType +import net.leanix.vsm.gitlab.broker.connector.json.computeWebhookEventType +import net.leanix.vsm.gitlab.broker.shared.exception.GitlabTokenException +import org.springframework.beans.factory.annotation.Value +import org.springframework.stereotype.Service + +@Service +class WebhookConsumerServiceImpl( + @Value("\${leanix.gitlab.leanix-id}") private val leanixId: String +) : WebhookConsumerService { + + val mapper: ObjectMapper = jacksonObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) + override fun consumeWebhookEvent(payloadToken: String?, payload: String) { + + // validate token + if (payloadToken?.equals(leanixId) == true) { + throw GitlabTokenException(payloadToken) + } + + // figure out event type + when (computeWebhookEventType(payload)) { + WebhookEventType.REPOSITORY -> processProjectCreated(payload) + WebhookEventType.MERGE_REQUEST -> println() + } + } + + private fun processProjectCreated(payload: String) { + val project = mapper.readValue(payload) + println(project) + } + + private fun processMergeRequest(payload: String) { + val mergeRequest = mapper.readValue(payload) + println(mergeRequest) + } +} \ No newline at end of file diff --git a/src/main/kotlin/net/leanix/vsm/gitlab/broker/connector/domain/WebhookConsumerService.kt b/src/main/kotlin/net/leanix/vsm/gitlab/broker/connector/domain/WebhookConsumerService.kt new file mode 100644 index 0000000..750c29b --- /dev/null +++ b/src/main/kotlin/net/leanix/vsm/gitlab/broker/connector/domain/WebhookConsumerService.kt @@ -0,0 +1,5 @@ +package net.leanix.vsm.gitlab.broker.connector.domain + +interface WebhookConsumerService { + fun consumeWebhookEvent(payloadToken: String?, payload: String) +} \ No newline at end of file diff --git a/src/main/kotlin/net/leanix/vsm/gitlab/broker/connector/domain/WebhookData.kt b/src/main/kotlin/net/leanix/vsm/gitlab/broker/connector/domain/WebhookData.kt new file mode 100644 index 0000000..9826912 --- /dev/null +++ b/src/main/kotlin/net/leanix/vsm/gitlab/broker/connector/domain/WebhookData.kt @@ -0,0 +1,52 @@ +package net.leanix.vsm.gitlab.broker.connector.domain + +import com.fasterxml.jackson.annotation.JsonProperty +import java.util.Date + +data class ProjectCreated( + @JsonProperty("project_id") + val id: Int, + val eventName: String, + val name: String, + val path: String, + @JsonProperty("path_with_namespace") + val pathWithNamespace: String, + @JsonProperty("project_visibility") + val projectVisibility: String, +) + +data class MergeRequest( + val project: Project, + @JsonProperty("object_attributes") + val objectAttributes: ObjectAttributes, +) + +data class Project( + val id: Int, + val name: String, + @JsonProperty("web_url") + val webURL: String, + val namespace: String, + @JsonProperty("path_with_namespace") + val pathWithNamespace: String, + @JsonProperty("default_branch") + val defaultBranch: String, +) + +data class ObjectAttributes( + val description: String, + val created_at: Date, + val source_branch: String, + val target_branch: String, + val title: String, + val updated_at: String, + val last_commit: GitlabCommit, + val state: String, + val action: String, +) + +data class GitlabCommit( + val id: String, + val message: String, + val title: String, +) diff --git a/src/main/kotlin/net/leanix/vsm/gitlab/broker/connector/domain/WebhookEventType.kt b/src/main/kotlin/net/leanix/vsm/gitlab/broker/connector/domain/WebhookEventType.kt new file mode 100644 index 0000000..053a446 --- /dev/null +++ b/src/main/kotlin/net/leanix/vsm/gitlab/broker/connector/domain/WebhookEventType.kt @@ -0,0 +1,6 @@ +package net.leanix.vsm.gitlab.broker.connector.domain + +enum class WebhookEventType { + REPOSITORY, + MERGE_REQUEST +} \ No newline at end of file diff --git a/src/main/kotlin/net/leanix/vsm/gitlab/broker/connector/json/GitlabParseUtil.kt b/src/main/kotlin/net/leanix/vsm/gitlab/broker/connector/json/GitlabParseUtil.kt new file mode 100644 index 0000000..0e7edd2 --- /dev/null +++ b/src/main/kotlin/net/leanix/vsm/gitlab/broker/connector/json/GitlabParseUtil.kt @@ -0,0 +1,22 @@ +package net.leanix.vsm.gitlab.broker.connector.json + +import com.fasterxml.jackson.databind.DeserializationFeature +import com.fasterxml.jackson.databind.ObjectMapper +import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper +import net.leanix.vsm.gitlab.broker.connector.domain.WebhookEventType +import net.leanix.vsm.gitlab.broker.shared.exception.GitlabPayloadNotSupportedException + +val mapper: ObjectMapper = jacksonObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) + +fun computeWebhookEventType(payload: String): WebhookEventType { + val node = mapper.readTree(payload) + + return if (node.at("/event_name").asText() == "project_create") WebhookEventType.REPOSITORY + else if ( + node.at("/event_type").asText() == "merge_request" + && node.at("/object_attributes/action").asText() == "merge" + && node.path("/project/default_branch").asText() + == node.path("/object_attributes/target_branch").asText() + ) WebhookEventType.MERGE_REQUEST + else throw GitlabPayloadNotSupportedException() +} \ No newline at end of file diff --git a/src/main/kotlin/net/leanix/vsm/gitlab/broker/connector/rest/GitlabWebhookController.kt b/src/main/kotlin/net/leanix/vsm/gitlab/broker/connector/rest/GitlabWebhookController.kt new file mode 100644 index 0000000..b6bf633 --- /dev/null +++ b/src/main/kotlin/net/leanix/vsm/gitlab/broker/connector/rest/GitlabWebhookController.kt @@ -0,0 +1,49 @@ +package net.leanix.vsm.gitlab.broker.connector.rest + +import net.leanix.vsm.gitlab.broker.connector.domain.WebhookConsumerService +import net.leanix.vsm.gitlab.broker.webhook.adapter.feign.LEANIX_WEBHOOK_PATH +import org.slf4j.LoggerFactory +import org.springframework.http.HttpStatus +import org.springframework.web.bind.annotation.GetMapping +import org.springframework.web.bind.annotation.PostMapping +import org.springframework.web.bind.annotation.RequestBody +import org.springframework.web.bind.annotation.RequestHeader +import org.springframework.web.bind.annotation.RequestMapping +import org.springframework.web.bind.annotation.ResponseStatus +import org.springframework.web.bind.annotation.RestController + +@RestController +@RequestMapping(LEANIX_WEBHOOK_PATH) +class GitlabWebhookController( + private val webhookService: WebhookConsumerService +) { + + private val logger = LoggerFactory.getLogger(this::class.java) + + @PostMapping + @ResponseStatus(HttpStatus.ACCEPTED) + fun webhook( + @RequestHeader("X-Gitlab-Instance", required = false) instance: String?, + @RequestHeader("X-Gitlab-Webhook-UUID", required = false) webhookUUID: String?, + @RequestHeader("X-Gitlab-Event", required = false) event: String?, + @RequestHeader("X-Gitlab-Event-UUID", required = false) eventUUID: String?, + @RequestHeader("X-Gitlab-Token", required = false) payloadToken: String?, + @RequestBody payload: String + ) { + logger.info("instance: $instance") + logger.info("webhookUUID: $webhookUUID") + logger.info("event: $event") + logger.info("eventUUID: $eventUUID") + logger.info("payloadToken: $payloadToken") + logger.info("payload: $payload") + + runCatching { + webhookService.consumeWebhookEvent(payloadToken, payload) + }.onFailure { + logger.error("Error consuming github event", it) + } + } + + @GetMapping + fun health() = "OK" +} \ No newline at end of file diff --git a/src/main/kotlin/net/leanix/vsm/gitlab/broker/connector/runner/InitialStateRunner.kt b/src/main/kotlin/net/leanix/vsm/gitlab/broker/connector/runner/InitialStateRunner.kt index 5725def..9618e57 100644 --- a/src/main/kotlin/net/leanix/vsm/gitlab/broker/connector/runner/InitialStateRunner.kt +++ b/src/main/kotlin/net/leanix/vsm/gitlab/broker/connector/runner/InitialStateRunner.kt @@ -20,7 +20,7 @@ class InitialStateRunner( override fun run(args: ApplicationArguments?) { logger.info { "Started to get initial state" } - fetchAssignments() +// fetchAssignments() setupWebhook() } diff --git a/src/main/kotlin/net/leanix/vsm/gitlab/broker/shared/exception/Exceptions.kt b/src/main/kotlin/net/leanix/vsm/gitlab/broker/shared/exception/Exceptions.kt new file mode 100644 index 0000000..753a69d --- /dev/null +++ b/src/main/kotlin/net/leanix/vsm/gitlab/broker/shared/exception/Exceptions.kt @@ -0,0 +1,10 @@ +package net.leanix.vsm.gitlab.broker.shared.exception + +sealed class VsmException(message: String? = null) : RuntimeException(message) + +class NoRepositoriesFound : VsmException() + +class GraphqlException(message: String?) : VsmException(message) +class GitlabTokenException(token: String?) : VsmException(message = "Invalid gitlab payload token: $token") +class GitlabPayloadNotSupportedException() : + VsmException(message = "Payload is neither for project creation nor for merge request being merged") diff --git a/src/main/kotlin/net/leanix/vsm/gitlab/broker/shared/exception/VsmException.kt b/src/main/kotlin/net/leanix/vsm/gitlab/broker/shared/exception/VsmException.kt deleted file mode 100644 index 00bb197..0000000 --- a/src/main/kotlin/net/leanix/vsm/gitlab/broker/shared/exception/VsmException.kt +++ /dev/null @@ -1,8 +0,0 @@ -package net.leanix.vsm.gitlab.broker.shared.exception - -sealed class VsmException(message: String? = null) : RuntimeException(message) { - - class NoRepositoriesFound : VsmException() - - class GraphqlException(message: String?) : VsmException(message) -} diff --git a/src/test/kotlin/net/leanix/vsm/gitlab/broker/connector/json/GitlabParseUtilTest.kt b/src/test/kotlin/net/leanix/vsm/gitlab/broker/connector/json/GitlabParseUtilTest.kt new file mode 100644 index 0000000..057ff0e --- /dev/null +++ b/src/test/kotlin/net/leanix/vsm/gitlab/broker/connector/json/GitlabParseUtilTest.kt @@ -0,0 +1,43 @@ +package net.leanix.vsm.gitlab.broker.connector.json + +import net.leanix.vsm.gitlab.broker.connector.domain.WebhookEventType +import net.leanix.vsm.gitlab.broker.shared.exception.GitlabPayloadNotSupportedException +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertThrows + +class GitlabParseUtilTest { + + @Test + fun `should return webhook event type REPOSITORY when event_name=project_create in payload`() { + val payload = this::class.java.getResource("/webhook_calls/project_created.json")!!.readText() + + val result = computeWebhookEventType(payload) + + assertEquals(WebhookEventType.REPOSITORY, result) + } + + @Test + fun `should return webhook event type MERGE_REQUEST when object_kind=merge_request and action=merged in payload`() { + val payload = this::class.java.getResource("/webhook_calls/merge_request_merged.json")!!.readText() + + val result = computeWebhookEventType(payload) + + assertEquals(WebhookEventType.MERGE_REQUEST, result) + } + + @Test + fun `should throw GitlabPayloadNotSupportedException when object_kind=merge_request and action!=merged in payload`() { + val payload = this::class.java.getResource("/webhook_calls/merge_request_opened.json")!!.readText() + + assertThrows { computeWebhookEventType(payload) } + } + + @Test + fun `should throw GitlabPayloadNotSupportedException when payload has no supported fields`() { + + assertThrows { + computeWebhookEventType("{ \"dummy_key\": \"dummy value\" }") + } + } +} diff --git a/src/test/resources/webhook_calls/merge_request_merged.json b/src/test/resources/webhook_calls/merge_request_merged.json new file mode 100644 index 0000000..7b298bb --- /dev/null +++ b/src/test/resources/webhook_calls/merge_request_merged.json @@ -0,0 +1,145 @@ +{ + "object_kind": "merge_request", + "event_type": "merge_request", + "user": { + "id": 8, + "name": "Ahmed Ali", + "username": "ahmed-ali-55", + "avatar_url": "https://secure.gravatar.com/avatar/cd5bd633e516139a5de35eac1c27d362?s=80&d=identicon", + "email": "[REDACTED]" + }, + "project": { + "id": 19, + "name": "ahmed-test", + "description": null, + "web_url": "https://cider-gitlab.westeurope.cloudapp.azure.com/ahmed-ali-55/ahmed-test", + "avatar_url": null, + "git_ssh_url": "git@cider-gitlab.westeurope.cloudapp.azure.com:ahmed-ali-55/ahmed-test.git", + "git_http_url": "https://cider-gitlab.westeurope.cloudapp.azure.com/ahmed-ali-55/ahmed-test.git", + "namespace": "Ahmed Ali", + "visibility_level": 0, + "path_with_namespace": "ahmed-ali-55/ahmed-test", + "default_branch": "main", + "ci_config_path": null, + "homepage": "https://cider-gitlab.westeurope.cloudapp.azure.com/ahmed-ali-55/ahmed-test", + "url": "git@cider-gitlab.westeurope.cloudapp.azure.com:ahmed-ali-55/ahmed-test.git", + "ssh_url": "git@cider-gitlab.westeurope.cloudapp.azure.com:ahmed-ali-55/ahmed-test.git", + "http_url": "https://cider-gitlab.westeurope.cloudapp.azure.com/ahmed-ali-55/ahmed-test.git" + }, + "object_attributes": { + "assignee_id": null, + "author_id": 8, + "created_at": "2023-08-28 12:48:17 UTC", + "description": "", + "head_pipeline_id": null, + "id": 37, + "iid": 3, + "last_edited_at": null, + "last_edited_by_id": null, + "merge_commit_sha": "128317429f9286c8ad819abc0580043ac5c78910", + "merge_error": null, + "merge_params": { + "force_remove_source_branch": "1" + }, + "merge_status": "can_be_merged", + "merge_user_id": null, + "merge_when_pipeline_succeeds": false, + "milestone_id": null, + "source_branch": "feature/readme-update-2", + "source_project_id": 19, + "state_id": 3, + "target_branch": "main", + "target_project_id": 19, + "time_estimate": 0, + "title": "Feature/readme update 2", + "updated_at": "2023-08-28 12:48:28 UTC", + "updated_by_id": null, + "url": "https://cider-gitlab.westeurope.cloudapp.azure.com/ahmed-ali-55/ahmed-test/-/merge_requests/3", + "source": { + "id": 19, + "name": "ahmed-test", + "description": null, + "web_url": "https://cider-gitlab.westeurope.cloudapp.azure.com/ahmed-ali-55/ahmed-test", + "avatar_url": null, + "git_ssh_url": "git@cider-gitlab.westeurope.cloudapp.azure.com:ahmed-ali-55/ahmed-test.git", + "git_http_url": "https://cider-gitlab.westeurope.cloudapp.azure.com/ahmed-ali-55/ahmed-test.git", + "namespace": "Ahmed Ali", + "visibility_level": 0, + "path_with_namespace": "ahmed-ali-55/ahmed-test", + "default_branch": "main", + "ci_config_path": null, + "homepage": "https://cider-gitlab.westeurope.cloudapp.azure.com/ahmed-ali-55/ahmed-test", + "url": "git@cider-gitlab.westeurope.cloudapp.azure.com:ahmed-ali-55/ahmed-test.git", + "ssh_url": "git@cider-gitlab.westeurope.cloudapp.azure.com:ahmed-ali-55/ahmed-test.git", + "http_url": "https://cider-gitlab.westeurope.cloudapp.azure.com/ahmed-ali-55/ahmed-test.git" + }, + "target": { + "id": 19, + "name": "ahmed-test", + "description": null, + "web_url": "https://cider-gitlab.westeurope.cloudapp.azure.com/ahmed-ali-55/ahmed-test", + "avatar_url": null, + "git_ssh_url": "git@cider-gitlab.westeurope.cloudapp.azure.com:ahmed-ali-55/ahmed-test.git", + "git_http_url": "https://cider-gitlab.westeurope.cloudapp.azure.com/ahmed-ali-55/ahmed-test.git", + "namespace": "Ahmed Ali", + "visibility_level": 0, + "path_with_namespace": "ahmed-ali-55/ahmed-test", + "default_branch": "main", + "ci_config_path": null, + "homepage": "https://cider-gitlab.westeurope.cloudapp.azure.com/ahmed-ali-55/ahmed-test", + "url": "git@cider-gitlab.westeurope.cloudapp.azure.com:ahmed-ali-55/ahmed-test.git", + "ssh_url": "git@cider-gitlab.westeurope.cloudapp.azure.com:ahmed-ali-55/ahmed-test.git", + "http_url": "https://cider-gitlab.westeurope.cloudapp.azure.com/ahmed-ali-55/ahmed-test.git" + }, + "last_commit": { + "id": "040a8b73ef3daed874c74a31d136f0af362ffa3e", + "message": "Merge branch 'feature/readme-update-3' into 'feature/readme-update-2'\n\nUpdate README.md\n\nSee merge request ahmed-ali-55/ahmed-test!2", + "title": "Merge branch 'feature/readme-update-3' into 'feature/readme-update-2'", + "timestamp": "2023-08-28T10:55:01+00:00", + "url": "https://cider-gitlab.westeurope.cloudapp.azure.com/ahmed-ali-55/ahmed-test/-/commit/040a8b73ef3daed874c74a31d136f0af362ffa3e", + "author": { + "name": "Ahmed Ali", + "email": "ahmed.ali@leanix.net" + } + }, + "work_in_progress": false, + "total_time_spent": 0, + "time_change": 0, + "human_total_time_spent": null, + "human_time_change": null, + "human_time_estimate": null, + "assignee_ids": [ + + ], + "reviewer_ids": [ + + ], + "labels": [ + + ], + "state": "merged", + "blocking_discussions_resolved": true, + "first_contribution": false, + "detailed_merge_status": "not_open", + "action": "merge" + }, + "labels": [ + + ], + "changes": { + "state_id": { + "previous": 4, + "current": 3 + }, + "updated_at": { + "previous": "2023-08-28 12:48:28 UTC", + "current": "2023-08-28 12:48:28 UTC" + } + }, + "repository": { + "name": "ahmed-test", + "url": "git@cider-gitlab.westeurope.cloudapp.azure.com:ahmed-ali-55/ahmed-test.git", + "description": null, + "homepage": "https://cider-gitlab.westeurope.cloudapp.azure.com/ahmed-ali-55/ahmed-test" + } +} \ No newline at end of file diff --git a/src/test/resources/webhook_calls/merge_request_opened.json b/src/test/resources/webhook_calls/merge_request_opened.json new file mode 100644 index 0000000..fb23d74 --- /dev/null +++ b/src/test/resources/webhook_calls/merge_request_opened.json @@ -0,0 +1,145 @@ +{ + "object_kind": "merge_request", + "event_type": "merge_request", + "user": { + "id": 8, + "name": "Ahmed Ali", + "username": "ahmed-ali-55", + "avatar_url": "https://secure.gravatar.com/avatar/cd5bd633e516139a5de35eac1c27d362?s=80&d=identicon", + "email": "[REDACTED]" + }, + "project": { + "id": 19, + "name": "ahmed-test", + "description": null, + "web_url": "https://cider-gitlab.westeurope.cloudapp.azure.com/ahmed-ali-55/ahmed-test", + "avatar_url": null, + "git_ssh_url": "git@cider-gitlab.westeurope.cloudapp.azure.com:ahmed-ali-55/ahmed-test.git", + "git_http_url": "https://cider-gitlab.westeurope.cloudapp.azure.com/ahmed-ali-55/ahmed-test.git", + "namespace": "Ahmed Ali", + "visibility_level": 0, + "path_with_namespace": "ahmed-ali-55/ahmed-test", + "default_branch": "main", + "ci_config_path": null, + "homepage": "https://cider-gitlab.westeurope.cloudapp.azure.com/ahmed-ali-55/ahmed-test", + "url": "git@cider-gitlab.westeurope.cloudapp.azure.com:ahmed-ali-55/ahmed-test.git", + "ssh_url": "git@cider-gitlab.westeurope.cloudapp.azure.com:ahmed-ali-55/ahmed-test.git", + "http_url": "https://cider-gitlab.westeurope.cloudapp.azure.com/ahmed-ali-55/ahmed-test.git" + }, + "object_attributes": { + "assignee_id": null, + "author_id": 8, + "created_at": "2023-08-28 12:48:17 UTC", + "description": "", + "head_pipeline_id": null, + "id": 37, + "iid": 3, + "last_edited_at": null, + "last_edited_by_id": null, + "merge_commit_sha": "128317429f9286c8ad819abc0580043ac5c78910", + "merge_error": null, + "merge_params": { + "force_remove_source_branch": "1" + }, + "merge_status": "can_be_merged", + "merge_user_id": null, + "merge_when_pipeline_succeeds": false, + "milestone_id": null, + "source_branch": "feature/readme-update-2", + "source_project_id": 19, + "state_id": 3, + "target_branch": "main", + "target_project_id": 19, + "time_estimate": 0, + "title": "Feature/readme update 2", + "updated_at": "2023-08-28 12:48:28 UTC", + "updated_by_id": null, + "url": "https://cider-gitlab.westeurope.cloudapp.azure.com/ahmed-ali-55/ahmed-test/-/merge_requests/3", + "source": { + "id": 19, + "name": "ahmed-test", + "description": null, + "web_url": "https://cider-gitlab.westeurope.cloudapp.azure.com/ahmed-ali-55/ahmed-test", + "avatar_url": null, + "git_ssh_url": "git@cider-gitlab.westeurope.cloudapp.azure.com:ahmed-ali-55/ahmed-test.git", + "git_http_url": "https://cider-gitlab.westeurope.cloudapp.azure.com/ahmed-ali-55/ahmed-test.git", + "namespace": "Ahmed Ali", + "visibility_level": 0, + "path_with_namespace": "ahmed-ali-55/ahmed-test", + "default_branch": "main", + "ci_config_path": null, + "homepage": "https://cider-gitlab.westeurope.cloudapp.azure.com/ahmed-ali-55/ahmed-test", + "url": "git@cider-gitlab.westeurope.cloudapp.azure.com:ahmed-ali-55/ahmed-test.git", + "ssh_url": "git@cider-gitlab.westeurope.cloudapp.azure.com:ahmed-ali-55/ahmed-test.git", + "http_url": "https://cider-gitlab.westeurope.cloudapp.azure.com/ahmed-ali-55/ahmed-test.git" + }, + "target": { + "id": 19, + "name": "ahmed-test", + "description": null, + "web_url": "https://cider-gitlab.westeurope.cloudapp.azure.com/ahmed-ali-55/ahmed-test", + "avatar_url": null, + "git_ssh_url": "git@cider-gitlab.westeurope.cloudapp.azure.com:ahmed-ali-55/ahmed-test.git", + "git_http_url": "https://cider-gitlab.westeurope.cloudapp.azure.com/ahmed-ali-55/ahmed-test.git", + "namespace": "Ahmed Ali", + "visibility_level": 0, + "path_with_namespace": "ahmed-ali-55/ahmed-test", + "default_branch": "main", + "ci_config_path": null, + "homepage": "https://cider-gitlab.westeurope.cloudapp.azure.com/ahmed-ali-55/ahmed-test", + "url": "git@cider-gitlab.westeurope.cloudapp.azure.com:ahmed-ali-55/ahmed-test.git", + "ssh_url": "git@cider-gitlab.westeurope.cloudapp.azure.com:ahmed-ali-55/ahmed-test.git", + "http_url": "https://cider-gitlab.westeurope.cloudapp.azure.com/ahmed-ali-55/ahmed-test.git" + }, + "last_commit": { + "id": "040a8b73ef3daed874c74a31d136f0af362ffa3e", + "message": "Merge branch 'feature/readme-update-3' into 'feature/readme-update-2'\n\nUpdate README.md\n\nSee merge request ahmed-ali-55/ahmed-test!2", + "title": "Merge branch 'feature/readme-update-3' into 'feature/readme-update-2'", + "timestamp": "2023-08-28T10:55:01+00:00", + "url": "https://cider-gitlab.westeurope.cloudapp.azure.com/ahmed-ali-55/ahmed-test/-/commit/040a8b73ef3daed874c74a31d136f0af362ffa3e", + "author": { + "name": "Ahmed Ali", + "email": "ahmed.ali@leanix.net" + } + }, + "work_in_progress": false, + "total_time_spent": 0, + "time_change": 0, + "human_total_time_spent": null, + "human_time_change": null, + "human_time_estimate": null, + "assignee_ids": [ + + ], + "reviewer_ids": [ + + ], + "labels": [ + + ], + "state": "merged", + "blocking_discussions_resolved": true, + "first_contribution": false, + "detailed_merge_status": "not_open", + "action": "open" + }, + "labels": [ + + ], + "changes": { + "state_id": { + "previous": 4, + "current": 3 + }, + "updated_at": { + "previous": "2023-08-28 12:48:28 UTC", + "current": "2023-08-28 12:48:28 UTC" + } + }, + "repository": { + "name": "ahmed-test", + "url": "git@cider-gitlab.westeurope.cloudapp.azure.com:ahmed-ali-55/ahmed-test.git", + "description": null, + "homepage": "https://cider-gitlab.westeurope.cloudapp.azure.com/ahmed-ali-55/ahmed-test" + } +} \ No newline at end of file diff --git a/src/test/resources/webhook_calls/project_created.json b/src/test/resources/webhook_calls/project_created.json new file mode 100644 index 0000000..eccfd8f --- /dev/null +++ b/src/test/resources/webhook_calls/project_created.json @@ -0,0 +1,18 @@ +{ + "event_name": "project_create", + "created_at": "2023-08-28T12:52:25Z", + "updated_at": "2023-08-28T12:52:25Z", + "name": "ahmed-test-2", + "path": "ahmed-test-2", + "path_with_namespace": "ahmed-ali-55/ahmed-test-2", + "project_id": 21, + "owner_name": "Ahmed Ali", + "owner_email": "[REDACTED]", + "owners": [ + { + "name": "Ahmed Ali", + "email": "[REDACTED]" + } + ], + "project_visibility": "private" +} \ No newline at end of file