diff --git a/src/main/java/com/faforever/api/config/FafApiProperties.java b/src/main/java/com/faforever/api/config/FafApiProperties.java index 475b13ccf..1c440c1c6 100644 --- a/src/main/java/com/faforever/api/config/FafApiProperties.java +++ b/src/main/java/com/faforever/api/config/FafApiProperties.java @@ -6,8 +6,6 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.time.Duration; -import java.util.ArrayList; -import java.util.List; @Data @ConfigurationProperties(prefix = "faf-api", ignoreUnknownFields = false) @@ -134,16 +132,6 @@ public static class Deployment { private String repositoriesDirectory; private String filesDirectoryFormat = "updates_%s_files"; private String forgedAllianceExePath; - private List configurations = new ArrayList<>(); - - @Data - public static class DeploymentConfiguration { - private String repositoryUrl; - private String branch; - private String modName; - private String modFilesExtension; - private boolean replaceExisting; - } } @Data 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 c16b63ab0..a0676de19 100644 --- a/src/main/java/com/faforever/api/data/domain/FeaturedMod.java +++ b/src/main/java/com/faforever/api/data/domain/FeaturedMod.java @@ -21,6 +21,9 @@ public class FeaturedMod { private int order; private String gitUrl; private String gitBranch; + private String fileExtension; + /** Whether overriding an existing version is allowed. */ + private boolean allowOverride; @Id @Column(name = "id") @@ -62,4 +65,14 @@ public String getGitUrl() { public String getGitBranch() { return gitBranch; } + + @Column(name = "file_extension") + public String getFileExtension() { + return fileExtension; + } + + @Column(name = "allow_override") + public boolean isAllowOverride() { + return allowOverride; + } } diff --git a/src/main/java/com/faforever/api/deployment/GitHubDeploymentService.java b/src/main/java/com/faforever/api/deployment/GitHubDeploymentService.java index a197546cc..2e87d81bd 100644 --- a/src/main/java/com/faforever/api/deployment/GitHubDeploymentService.java +++ b/src/main/java/com/faforever/api/deployment/GitHubDeploymentService.java @@ -1,7 +1,8 @@ package com.faforever.api.deployment; import com.faforever.api.config.FafApiProperties; -import com.faforever.api.config.FafApiProperties.Deployment.DeploymentConfiguration; +import com.faforever.api.data.domain.FeaturedMod; +import com.faforever.api.featuredmods.FeaturedModService; import com.fasterxml.jackson.databind.ObjectMapper; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; @@ -21,24 +22,26 @@ public class GitHubDeploymentService { private final ApplicationContext applicationContext; private final FafApiProperties fafApiProperties; private final ObjectMapper objectMapper; + private final FeaturedModService featuredModService; - public GitHubDeploymentService(ApplicationContext applicationContext, FafApiProperties fafApiProperties, ObjectMapper objectMapper) { + public GitHubDeploymentService(ApplicationContext applicationContext, FafApiProperties fafApiProperties, + ObjectMapper objectMapper, FeaturedModService featuredModService) { this.applicationContext = applicationContext; this.fafApiProperties = fafApiProperties; this.objectMapper = objectMapper; + this.featuredModService = featuredModService; } @SneakyThrows - public void createDeploymentIfEligible(Push push) { + void createDeploymentIfEligible(Push push) { String ref = push.getRef(); - Optional optional = fafApiProperties.getDeployment().getConfigurations().stream() - .filter(configuration -> - push.getRepository().gitHttpTransportUrl().equals(configuration.getRepositoryUrl()) - && push.getRef().replace("refs/heads/", "").equals(configuration.getBranch())) - .findFirst(); + String httpUrl = push.getRepository().gitHttpTransportUrl(); + String branch = push.getRef().replace("refs/heads/", ""); + + Optional optional = featuredModService.findByGitUrlAndGitBranch(httpUrl, branch); if (!optional.isPresent()) { - log.warn("No configuration present for repository '{}' and ref '{}'", push.getRepository().gitHttpTransportUrl(), push.getRef()); + log.warn("No configuration present for repository '{}' and branch '{}'", httpUrl, branch); return; } @@ -53,7 +56,7 @@ public void createDeploymentIfEligible(Push push) { @Async @SneakyThrows - public void deploy(GHDeployment deployment) { + void deploy(GHDeployment deployment) { String environment = deployment.getEnvironment(); if (!fafApiProperties.getGitHub().getDeploymentEnvironment().equals(environment)) { log.warn("Ignoring deployment for environment: {}", environment); @@ -61,7 +64,7 @@ public void deploy(GHDeployment deployment) { } applicationContext.getBean(LegacyFeaturedModDeploymentTask.class) - .setConfiguration(objectMapper.readValue(deployment.getPayload(), DeploymentConfiguration.class)) + .setFeaturedMod(objectMapper.readValue(deployment.getPayload(), FeaturedMod.class)) .run(); } } diff --git a/src/main/java/com/faforever/api/deployment/LegacyFeaturedModDeploymentTask.java b/src/main/java/com/faforever/api/deployment/LegacyFeaturedModDeploymentTask.java index 4c2365a40..1a8469c71 100644 --- a/src/main/java/com/faforever/api/deployment/LegacyFeaturedModDeploymentTask.java +++ b/src/main/java/com/faforever/api/deployment/LegacyFeaturedModDeploymentTask.java @@ -2,7 +2,7 @@ import com.faforever.api.config.FafApiProperties; import com.faforever.api.config.FafApiProperties.Deployment; -import com.faforever.api.config.FafApiProperties.Deployment.DeploymentConfiguration; +import com.faforever.api.data.domain.FeaturedMod; import com.faforever.api.deployment.git.GitWrapper; import com.faforever.api.featuredmods.FeaturedModFile; import com.faforever.api.featuredmods.FeaturedModService; @@ -62,7 +62,7 @@ public class LegacyFeaturedModDeploymentTask implements Runnable { private final FafApiProperties apiProperties; @Setter - private DeploymentConfiguration configuration; + private FeaturedMod featuredMod; public LegacyFeaturedModDeploymentTask(GitWrapper gitWrapper, FeaturedModService featuredModService, FafApiProperties apiProperties) { this.gitWrapper = gitWrapper; @@ -73,14 +73,14 @@ public LegacyFeaturedModDeploymentTask(GitWrapper gitWrapper, FeaturedModService @Override @SneakyThrows public void run() { - Assert.state(configuration != null, "Configuration must be set"); - String modName = configuration.getModName(); + Assert.state(featuredMod != null, "Configuration must be set"); + String modName = featuredMod.getTechnicalName(); Assert.state(VALID_MOD_NAMES.contains(modName), "Unsupported mod: " + modName); - String repositoryUrl = configuration.getRepositoryUrl(); - String branch = configuration.getBranch(); - boolean replaceExisting = configuration.isReplaceExisting(); - String modFilesExtension = configuration.getModFilesExtension(); + String repositoryUrl = featuredMod.getGitUrl(); + String branch = featuredMod.getGitBranch(); + boolean replaceExisting = featuredMod.isAllowOverride(); + String modFilesExtension = featuredMod.getFileExtension(); Map fileIds = featuredModService.getFileIds(modName); log.info("Starting deployment of '{}' from '{}', branch '{}', replaceExisting '{}', modFilesExtension '{}'", @@ -193,17 +193,17 @@ private StagedFile renameToFinalFile(StagedFile file) { } /** - * Creates a ZIP file with the file ending configured in {@link #configuration}. The content of the ZIP file is the + * Creates a ZIP file with the file ending configured in {@link #featuredMod}. The content of the ZIP file is the * content of the directory. If no file ID is available, an empty optional is returned. */ @SneakyThrows private Optional packDirectory(Path directory, Short version, Path targetFolder, Map fileIds) { String directoryName = directory.getFileName().toString(); - Path targetNxtFile = targetFolder.resolve(String.format("%s.%d.%s", directoryName, version, configuration.getModFilesExtension())); + Path targetNxtFile = targetFolder.resolve(String.format("%s.%d.%s", directoryName, version, featuredMod.getFileExtension())); Path tmpNxtFile = toTmpFile(targetNxtFile); // E.g. "effects.nx2" - String clientFileName = String.format("%s.%s", directoryName, configuration.getModFilesExtension()); + String clientFileName = String.format("%s.%s", directoryName, featuredMod.getFileExtension()); Short fileId = fileIds.get(clientFileName); if (fileId == null) { log.debug("Skipping folder '{}' because there's no file ID available", directoryName); diff --git a/src/main/java/com/faforever/api/featuredmods/FeaturedModRepository.java b/src/main/java/com/faforever/api/featuredmods/FeaturedModRepository.java index e6424ff6c..721bfd173 100644 --- a/src/main/java/com/faforever/api/featuredmods/FeaturedModRepository.java +++ b/src/main/java/com/faforever/api/featuredmods/FeaturedModRepository.java @@ -2,6 +2,11 @@ import com.faforever.api.data.domain.FeaturedMod; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; +import java.util.Optional; + +@Repository public interface FeaturedModRepository extends JpaRepository { + Optional findByGitUrlAndGitBranch(String url, String branch); } diff --git a/src/main/java/com/faforever/api/featuredmods/FeaturedModService.java b/src/main/java/com/faforever/api/featuredmods/FeaturedModService.java index a2d04e62c..25211d340 100644 --- a/src/main/java/com/faforever/api/featuredmods/FeaturedModService.java +++ b/src/main/java/com/faforever/api/featuredmods/FeaturedModService.java @@ -8,6 +8,7 @@ import java.util.List; import java.util.Map; +import java.util.Optional; @Service public class FeaturedModService { @@ -40,4 +41,8 @@ public void save(String modName, short version, List featuredMo public Map getFileIds(String modName) { return legacyFeaturedModFileRepository.getFileIds(modName); } + + public Optional findByGitUrlAndGitBranch(String url, String branch) { + return featuredModRepository.findByGitUrlAndGitBranch(url, branch); + } } diff --git a/src/main/resources/config/application-dev.yml b/src/main/resources/config/application-dev.yml index a05c6261e..48993f831 100644 --- a/src/main/resources/config/application-dev.yml +++ b/src/main/resources/config/application-dev.yml @@ -24,23 +24,6 @@ faf-api: forged-alliance-exe-path: ${FORGED_ALLIANCE_EXE_PATH} repositories-directory: ${REPOSITORIES_DIRECTORY:build/cache/repos} featured-mods-target-directory: ${FEATURED_MODS_TARGET_DIRECTORY:build/cache/deployment} - # TODO make this runtime configuration - configurations: - - repositoryUrl: https://github.com/FAForever/fa.git - branch: deploy/faf - modName: faf - modFilesExtension: nx2 - replaceExisting: false - - repositoryUrl: https://github.com/FAForever/fa.git - branch: deploy/fafbeta - modName: fafbeta - modFilesExtension: nx4 - replaceExisting: true - - repositoryUrl: https://github.com/FAForever/fa.git - branch: deploy/fafdevelop - modName: fafdevelop - modFilesExtension: nx5 - replaceExisting: true clan: website-url-format: ${CLAN_WEBSITE_URL_FORMAT:http://clans.test.faforever.com/clan/%s} diff --git a/src/main/resources/config/application-prod.yml b/src/main/resources/config/application-prod.yml index 799ed1568..f593eae7b 100644 --- a/src/main/resources/config/application-prod.yml +++ b/src/main/resources/config/application-prod.yml @@ -23,28 +23,6 @@ faf-api: forged-alliance-exe-path: ${FORGED_ALLIANCE_EXE_PATH} repositories-directory: ${REPOSITORIES_DIRECTORY} featured-mods-target-directory: ${FEATURED_MODS_TARGET_DIRECTORY} - # TODO make this runtime configuration - configurations: - - repositoryUrl: https://github.com/FAForever/fa.git - branch: deploy/faf - modName: faf - modFilesExtension: nx2 - replaceExisting: false - - repositoryUrl: https://github.com/FAForever/fa.git - branch: deploy/fafbeta - modName: fafbeta - modFilesExtension: nx4 - replaceExisting: true - - repositoryUrl: https://github.com/FAForever/fa.git - branch: deploy/fafdevelop - modName: fafdevelop - modFilesExtension: nx5 - replaceExisting: true - - repositoryUrl: https://github.com/FAForever/faf-phantomx.git - branch: master - modName: phantomx - modFilesExtension: phx - replaceExisting: false registration: activation-url-format: ${ACTIVATION_URL_FORMAT} mail: diff --git a/src/test/java/com/faforever/api/deployment/GitHubDeploymentServiceTest.java b/src/test/java/com/faforever/api/deployment/GitHubDeploymentServiceTest.java index 8c9179d1b..5807c29d9 100644 --- a/src/test/java/com/faforever/api/deployment/GitHubDeploymentServiceTest.java +++ b/src/test/java/com/faforever/api/deployment/GitHubDeploymentServiceTest.java @@ -1,7 +1,8 @@ package com.faforever.api.deployment; import com.faforever.api.config.FafApiProperties; -import com.faforever.api.config.FafApiProperties.Deployment.DeploymentConfiguration; +import com.faforever.api.data.domain.FeaturedMod; +import com.faforever.api.featuredmods.FeaturedModService; import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.Before; import org.junit.Test; @@ -14,7 +15,7 @@ import org.mockito.junit.MockitoJUnitRunner; import org.springframework.context.ApplicationContext; -import java.util.Collections; +import java.util.Optional; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyString; @@ -28,6 +29,7 @@ public class GitHubDeploymentServiceTest { private static final String EXAMPLE_REPO_URL = "https://example.com/repo.git"; private static final String ENVIRONMENT = "junit"; + private static final String EXAMPLE_BRANCH = "master"; private GitHubDeploymentService instance; private FafApiProperties apiProperties; @@ -36,11 +38,13 @@ public class GitHubDeploymentServiceTest { private ApplicationContext applicationContext; @Mock private ObjectMapper objectMapper; + @Mock + private FeaturedModService featuredModService; @Before public void setUp() throws Exception { apiProperties = new FafApiProperties(); - instance = new GitHubDeploymentService(applicationContext, apiProperties, objectMapper); + instance = new GitHubDeploymentService(applicationContext, apiProperties, objectMapper, featuredModService); } @Test @@ -50,6 +54,7 @@ public void createDeploymentIfEligibleNoConfigurationAvailable() throws Exceptio GHRepository repository = mock(GHRepository.class); when(repository.gitHttpTransportUrl()).thenReturn(EXAMPLE_REPO_URL); when(push.getRepository()).thenReturn(repository); + when(push.getRef()).thenReturn("refs/heads/master"); instance.createDeploymentIfEligible(push); @@ -70,18 +75,18 @@ public void createDeploymentIfEligible() throws Exception { when(deploymentBuilder.payload(anyString())).thenReturn(deploymentBuilder); when(repository.createDeployment("refs/heads/master")).thenReturn(deploymentBuilder); - when(objectMapper.writeValueAsString(any(DeploymentConfiguration.class))).thenReturn(""); + when(featuredModService.findByGitUrlAndGitBranch(EXAMPLE_REPO_URL, EXAMPLE_BRANCH)) + .thenReturn(Optional.of(new FeaturedMod() + .setGitBranch(EXAMPLE_BRANCH) + .setFileExtension("nx2") + .setTechnicalName("faf") + .setGitUrl(EXAMPLE_REPO_URL))); + + when(objectMapper.writeValueAsString(any(FeaturedMod.class))).thenReturn(""); when(push.getRepository()).thenReturn(repository); apiProperties.getGitHub().setDeploymentEnvironment(ENVIRONMENT); - apiProperties.getDeployment().setConfigurations(Collections.singletonList( - new DeploymentConfiguration() - .setBranch("master") - .setModFilesExtension(".nx2") - .setModName("faf") - .setRepositoryUrl(EXAMPLE_REPO_URL) - )); instance.createDeploymentIfEligible(push); @@ -108,7 +113,7 @@ public void deployEnvironmentMatch() throws Exception { when(deployment.getEnvironment()).thenReturn(ENVIRONMENT); LegacyFeaturedModDeploymentTask task = mock(LegacyFeaturedModDeploymentTask.class); - when(task.setConfiguration(any())).thenReturn(task); + when(task.setFeaturedMod(any())).thenReturn(task); when(applicationContext.getBean(LegacyFeaturedModDeploymentTask.class)).thenReturn(task); instance.deploy(deployment); diff --git a/src/test/java/com/faforever/api/deployment/LegacyFeaturedModDeploymentTaskTest.java b/src/test/java/com/faforever/api/deployment/LegacyFeaturedModDeploymentTaskTest.java index bcf83f424..b7a28bb3b 100644 --- a/src/test/java/com/faforever/api/deployment/LegacyFeaturedModDeploymentTaskTest.java +++ b/src/test/java/com/faforever/api/deployment/LegacyFeaturedModDeploymentTaskTest.java @@ -2,7 +2,7 @@ import com.faforever.api.config.FafApiProperties; import com.faforever.api.config.FafApiProperties.Deployment; -import com.faforever.api.config.FafApiProperties.Deployment.DeploymentConfiguration; +import com.faforever.api.data.domain.FeaturedMod; import com.faforever.api.deployment.git.GitWrapper; import com.faforever.api.featuredmods.FeaturedModFile; import com.faforever.api.featuredmods.FeaturedModService; @@ -67,19 +67,18 @@ public void testRunWithoutConfigurationThrowsException() throws Exception { @Test public void testRunNoFileIds() throws Exception { - instance.setConfiguration(new DeploymentConfiguration() - .setBranch("branch") - .setModFilesExtension("nx3") - .setModName("faf") - .setReplaceExisting(true) - .setRepositoryUrl("git@example.com/FAForever/faf")); + instance.setFeaturedMod(new FeaturedMod() + .setGitBranch("branch") + .setFileExtension("nx2") + .setTechnicalName("faf") + .setGitUrl("https://example.com/FAForever/faf")); Mockito.doAnswer(invocation -> { Path repoFolder = invocation.getArgument(0); Files.createDirectories(repoFolder.resolve("someDir")); Files.copy( - LegacyFeaturedModDeploymentTaskTest.class.getResourceAsStream("/featured_mod/mod_info.lua"), - repoFolder.resolve("mod_info.lua") + LegacyFeaturedModDeploymentTaskTest.class.getResourceAsStream("/featured_mod/mod_info.lua"), + repoFolder.resolve("mod_info.lua") ); return null; }).when(gitWrapper).checkoutRef(any(), any()); @@ -98,29 +97,28 @@ public void testRunNoFileIds() throws Exception { @Test @SuppressWarnings("unchecked") public void testRun() throws Exception { - instance.setConfiguration(new DeploymentConfiguration() - .setBranch("branch") - .setModFilesExtension("nx3") - .setModName("faf") - .setReplaceExisting(true) - .setRepositoryUrl("git@example.com/FAForever/faf")); + instance.setFeaturedMod(new FeaturedMod() + .setGitBranch("branch") + .setFileExtension("nx3") + .setTechnicalName("faf") + .setGitUrl("https://example.com/FAForever/faf")); Mockito.doAnswer(invocation -> { Path repoFolder = invocation.getArgument(0); Files.createDirectories(repoFolder.resolve("someDir")); Files.copy( - LegacyFeaturedModDeploymentTaskTest.class.getResourceAsStream("/featured_mod/mod_info.lua"), - repoFolder.resolve("mod_info.lua") + LegacyFeaturedModDeploymentTaskTest.class.getResourceAsStream("/featured_mod/mod_info.lua"), + repoFolder.resolve("mod_info.lua") ); Files.copy(LegacyFeaturedModDeploymentTaskTest.class.getResourceAsStream("/featured_mod/someDir/someFile"), - repoFolder.resolve("someDir/someFile") + repoFolder.resolve("someDir/someFile") ); return null; }).when(gitWrapper).checkoutRef(any(), any()); when(featuredModService.getFileIds("faf")).thenReturn(ImmutableMap.of( - "ForgedAlliance.exe", (short) 1, - "someDir.nx3", (short) 2 + "ForgedAlliance.exe", (short) 1, + "someDir.nx3", (short) 2 )); Path dummyExe = repositoriesFolder.getRoot().toPath().resolve("TemplateForgedAlliance.exe");