From 080f83ed2c8660bda6bbd4dfc2230448ead61536 Mon Sep 17 00:00:00 2001 From: Brutus5000 Date: Sat, 23 Feb 2019 14:25:00 +0100 Subject: [PATCH] Invoke Webhook after Deployment (if defined) --- .travis.yml | 2 +- .../api/data/domain/FeaturedMod.java | 6 +++ .../LegacyFeaturedModDeploymentTask.java | 21 +++++++++- src/main/resources/config/application.yml | 2 +- .../LegacyFeaturedModDeploymentTaskTest.java | 39 ++++++++++++++++++- 5 files changed, 65 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index 740f9e3b7..e7b215188 100644 --- a/.travis.yml +++ b/.travis.yml @@ -19,7 +19,7 @@ before_install: install: - git clone https://github.com/FAForever/faf-stack.git faf-stack && pushd faf-stack - && git checkout a1ef34cb64343225d6793e7af1d8fa0c93a7b3e6 + && git checkout 22bd4a3b8766106c2203cc3a0aa1eae155e72240 && cp -r config.template config && ./scripts/init-db.sh && popd diff --git a/src/main/java/com/faforever/api/data/domain/FeaturedMod.java b/src/main/java/com/faforever/api/data/domain/FeaturedMod.java index 259379529..5dfb65498 100644 --- a/src/main/java/com/faforever/api/data/domain/FeaturedMod.java +++ b/src/main/java/com/faforever/api/data/domain/FeaturedMod.java @@ -30,6 +30,7 @@ public class FeaturedMod { private Boolean allowOverride; private String fileExtension; private String bireusUrl; + private String deploymentWebhook; @Id @Column(name = "id") @@ -82,6 +83,11 @@ public String getFileExtension() { return fileExtension; } + @Column(name = "deployment_webhook ") + public String getDeploymentWebhook() { + return deploymentWebhook; + } + @Transient @ComputedAttribute // Enriched by FeaturedModEnricher diff --git a/src/main/java/com/faforever/api/deployment/LegacyFeaturedModDeploymentTask.java b/src/main/java/com/faforever/api/deployment/LegacyFeaturedModDeploymentTask.java index 688f85323..b697232b7 100644 --- a/src/main/java/com/faforever/api/deployment/LegacyFeaturedModDeploymentTask.java +++ b/src/main/java/com/faforever/api/deployment/LegacyFeaturedModDeploymentTask.java @@ -19,6 +19,8 @@ import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Component; import org.springframework.util.Assert; +import org.springframework.web.client.RestClientException; +import org.springframework.web.client.RestTemplate; import javax.transaction.Transactional; import javax.transaction.Transactional.TxType; @@ -62,6 +64,7 @@ public class LegacyFeaturedModDeploymentTask implements Runnable { private final GitWrapper gitWrapper; private final FeaturedModService featuredModService; private final FafApiProperties apiProperties; + private final RestTemplate restTemplate; @Setter private FeaturedMod featuredMod; @@ -69,10 +72,11 @@ public class LegacyFeaturedModDeploymentTask implements Runnable { @Setter private Consumer statusDescriptionListener; - public LegacyFeaturedModDeploymentTask(GitWrapper gitWrapper, FeaturedModService featuredModService, FafApiProperties apiProperties) { + public LegacyFeaturedModDeploymentTask(GitWrapper gitWrapper, FeaturedModService featuredModService, FafApiProperties apiProperties, RestTemplate restTemplate) { this.gitWrapper = gitWrapper; this.featuredModService = featuredModService; this.apiProperties = apiProperties; + this.restTemplate = restTemplate; } @Override @@ -112,10 +116,25 @@ public void run() { files.forEach(this::finalizeFile); updateDatabase(files, version, modName); + invokeDeploymentWebhook(featuredMod); log.info("Deployment of '{}' version '{}' was successful", modName, version); } + void invokeDeploymentWebhook(FeaturedMod featuredMod) { + if (featuredMod.getDeploymentWebhook() == null) { + log.debug("No deployment webhook configured."); + return; + } + + log.debug("Invoking deployment webhook on: {}", featuredMod.getDeploymentWebhook()); + try { + restTemplate.getForObject(featuredMod.getDeploymentWebhook(), String.class); + } catch (RestClientException e) { + log.error("Invoking webhook failed on: {}", featuredMod.getDeploymentWebhook(), e); + } + } + /** * Creates a ForgedAlliance.exe which contains the specified version number, if the file is specified for the current * featured mod. diff --git a/src/main/resources/config/application.yml b/src/main/resources/config/application.yml index eb1e66496..62f727662 100644 --- a/src/main/resources/config/application.yml +++ b/src/main/resources/config/application.yml @@ -9,7 +9,7 @@ faf-api: challonge: key: ${CHALLONGE_KEY:} database: - schema-version: ${DATABASE_SCHEMA_VERSION:62} + schema-version: ${DATABASE_SCHEMA_VERSION:64} mautic: base-url: ${MAUTIC_BASE_URL:false} client-id: ${MAUTIC_CLIENT_ID:false} diff --git a/src/test/java/com/faforever/api/deployment/LegacyFeaturedModDeploymentTaskTest.java b/src/test/java/com/faforever/api/deployment/LegacyFeaturedModDeploymentTaskTest.java index aa9e1b76b..ff6b5b951 100644 --- a/src/test/java/com/faforever/api/deployment/LegacyFeaturedModDeploymentTaskTest.java +++ b/src/test/java/com/faforever/api/deployment/LegacyFeaturedModDeploymentTaskTest.java @@ -16,6 +16,8 @@ import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.junit.MockitoJUnitRunner; +import org.springframework.web.client.RestClientException; +import org.springframework.web.client.RestTemplate; import java.io.IOException; import java.io.RandomAccessFile; @@ -34,6 +36,7 @@ import static org.mockito.Matchers.eq; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; @RunWith(MockitoJUnitRunner.class) @@ -48,6 +51,9 @@ public class LegacyFeaturedModDeploymentTaskTest { private GitWrapper gitWrapper; @Mock private FeaturedModService featuredModService; + @Mock + private RestTemplate restTemplate; + private FafApiProperties properties; @Before @@ -57,7 +63,7 @@ public void setUp() throws Exception { deployment.setRepositoriesDirectory(repositoriesFolder.getRoot().getAbsolutePath()); deployment.setFeaturedModsTargetDirectory(targetFolder.getRoot().getAbsolutePath()); - instance = new LegacyFeaturedModDeploymentTask(gitWrapper, featuredModService, properties); + instance = new LegacyFeaturedModDeploymentTask(gitWrapper, featuredModService, properties, restTemplate); } @Test(expected = IllegalStateException.class) @@ -106,7 +112,8 @@ public void testRun() throws Exception { .setFileExtension("nx3") .setTechnicalName("faf") .setAllowOverride(true) - .setGitUrl("git@example.com/FAForever/faf")); + .setGitUrl("git@example.com/FAForever/faf") + .setDeploymentWebhook("someUrl")); Mockito.doAnswer(invocation -> { Path repoFolder = invocation.getArgument(0); @@ -137,6 +144,7 @@ public void testRun() throws Exception { ArgumentCaptor> filesCaptor = ArgumentCaptor.forClass(List.class); verify(featuredModService).save(eq("faf"), eq((short) 1337), filesCaptor.capture()); + verify(restTemplate).getForObject("someUrl", String.class); List files = filesCaptor.getValue(); files.sort(Comparator.comparing(FeaturedModFile::getFileId)); @@ -155,6 +163,33 @@ public void testRun() throws Exception { assertThat(Files.exists(targetFolder.getRoot().toPath().resolve("updates_faf_files/ForgedAlliance.1337.exe")), is(true)); } + @Test + public void testInvokeDeploymentWebhookSkipped() { + instance.invokeDeploymentWebhook(new FeaturedMod()); + verifyNoMoreInteractions(restTemplate); + } + + @Test + public void testInvokeDeploymentWebhookInvokedSuccess() { + String someUrl = "someUrl"; + instance.invokeDeploymentWebhook(new FeaturedMod().setDeploymentWebhook(someUrl)); + + verify(restTemplate).getForObject(someUrl, String.class); + verifyNoMoreInteractions(restTemplate); + } + + @Test + public void testInvokeDeploymentWebhookResilience() { + String someUrl = "someUrl"; + + when(restTemplate.getForObject(anyString(), eq(String.class))).thenThrow(new RestClientException("error")); + + instance.invokeDeploymentWebhook(new FeaturedMod().setDeploymentWebhook(someUrl)); + + verify(restTemplate).getForObject(someUrl, String.class); + verifyNoMoreInteractions(restTemplate); + } + private void createDummyExe(Path file) throws IOException { try (RandomAccessFile randomAccessFile = new RandomAccessFile(file.toFile(), "rw")) { randomAccessFile.setLength(12_444_928);