From c740a17e447472d345e75c6b1170647d0bc6a3e0 Mon Sep 17 00:00:00 2001 From: Dan Van Atta Date: Mon, 4 Dec 2023 17:36:37 -0800 Subject: [PATCH] Run maps server as its own server (#12180) * Run maps server as its own server This update does a few thing: - The majority of the update, splits off the Maps server code from Lobby & starts up the maps server on its own. Auth needs to be reworked still. - adds a class called 'ClientIdentifiers' that we can use consistently to send all needed HTTP headers. Updates Maps HTTP Clients to accept and use ClientIdentifiers to create those headers. So, we now more consistently send all needed headers (for all maps related APIs at least) * Add missing 'shadowJar' dependency --- .docker/docker-compose.yml | 8 ++ .docker/nginx/default.conf | 9 ++ build.gradle | 1 + game-app/game-core/build.gradle | 2 + .../map/listing/MapListingFetcher.java | 11 +- .../main/java/org/triplea/util/Version.java | 7 ++ game-app/game-headed/build.gradle | 2 + .../moderator/toolbox/ToolBoxWindow.java | 9 +- .../moderator/toolbox/tabs/TabFactory.java | 17 +-- .../moderator/toolbox/tabs/maps/MapsTab.java | 2 +- .../toolbox/tabs/maps/MapsTabModel.java | 6 +- .../triplea/ui/menubar/LobbyMenu.java | 18 ++- .../triplea/game/client/HeadedGameRunner.java | 5 +- .../toolbox/ModeratorToolboxClient.java | 6 - .../http/client/lib/ClientIdentifiers.java | 28 +++++ .../http/client/lib/HttpClientHeaders.java | 33 ------ .../error/report/ErrorReportClient.java | 9 +- servers/game-support/server/configuration.yml | 2 - .../reporting/ErrorReportController.java | 4 +- .../ErrorReportControllerIntegrationTest.java | 6 +- servers/maps/client/build.gradle | 9 ++ .../client/maps}/admin/MapTagAdminClient.java | 10 +- .../client/maps}/admin/MapTagMetaData.java | 2 +- .../maps}/admin/UpdateMapTagRequest.java | 2 +- .../client/maps/listing/MapDownloadItem.java | 0 .../http/client/maps/listing/MapTag.java | 0 .../http/client/maps/listing/MapsClient.java | 7 +- .../src/test/resources/logback-test.xml | 11 ++ servers/maps/server/Dockerfile | 6 + servers/maps/server/build.gradle | 47 +++++++- servers/maps/server/configuration.yml | 55 ++++++++++ .../server/src/main/java/configuration.yml | 29 +++++ .../triplea}/maps/MapTagAdminController.java | 14 +-- .../org/triplea}/maps/MapsController.java | 2 +- .../triplea/maps/MapsServerApplication.java | 75 +++++++++++++ .../org/triplea/maps/MapsServerConfig.java | 61 +++++++++++ .../indexing/MapsIndexingObjectFactory.java | 44 +++----- .../triplea/maps/tags/MapTagAdminModule.java | 4 +- .../indexing/MapIndexingIntegrationTest.java | 13 ++- .../maps/tags/MapTagAdminModuleTest.java | 4 +- .../common}/IllegalArgumentMapper.java | 4 +- .../spitfire/server/HttpController.java | 0 settings.gradle | 3 + .../dropwizard-server/build.gradle | 1 - .../dropwizard-server/configuration.yml | 34 +----- .../server/SpitfireServerApplication.java | 23 +--- .../spitfire/server/SpitfireServerConfig.java | 30 +---- .../server/SpitfireDatabaseTestSupport.java | 2 - .../maps/MapTagAdminControllerTest.java | 103 ------------------ .../server/maps/MapsControllerTest.java | 48 -------- 50 files changed, 460 insertions(+), 368 deletions(-) create mode 100644 lib/http-client-lib/src/main/java/org/triplea/http/client/lib/ClientIdentifiers.java delete mode 100644 lib/http-client-lib/src/main/java/org/triplea/http/client/lib/HttpClientHeaders.java rename {http-clients/lobby-client/src/main/java/org/triplea/http/client/maps/tag => servers/maps/client/src/main/java/org/triplea/http/client/maps}/admin/MapTagAdminClient.java (68%) rename {http-clients/lobby-client/src/main/java/org/triplea/http/client/maps/tag => servers/maps/client/src/main/java/org/triplea/http/client/maps}/admin/MapTagMetaData.java (89%) rename {http-clients/lobby-client/src/main/java/org/triplea/http/client/maps/tag => servers/maps/client/src/main/java/org/triplea/http/client/maps}/admin/UpdateMapTagRequest.java (87%) rename {http-clients/lobby-client => servers/maps/client}/src/main/java/org/triplea/http/client/maps/listing/MapDownloadItem.java (100%) rename {http-clients/lobby-client => servers/maps/client}/src/main/java/org/triplea/http/client/maps/listing/MapTag.java (100%) rename {http-clients/lobby-client => servers/maps/client}/src/main/java/org/triplea/http/client/maps/listing/MapsClient.java (71%) create mode 100644 servers/maps/client/src/test/resources/logback-test.xml create mode 100644 servers/maps/server/Dockerfile create mode 100644 servers/maps/server/configuration.yml create mode 100644 servers/maps/server/src/main/java/configuration.yml rename {spitfire-server/dropwizard-server/src/main/java/org/triplea/spitfire/server => servers/maps/server/src/main/java/org/triplea}/maps/MapTagAdminController.java (78%) rename {spitfire-server/dropwizard-server/src/main/java/org/triplea/spitfire/server => servers/maps/server/src/main/java/org/triplea}/maps/MapsController.java (96%) create mode 100644 servers/maps/server/src/main/java/org/triplea/maps/MapsServerApplication.java create mode 100644 servers/maps/server/src/main/java/org/triplea/maps/MapsServerConfig.java rename {spitfire-server/dropwizard-server/src/main/java/org/triplea/spitfire/server => servers/server-lib/src/main/java/org/triplea/dropwizard/common}/IllegalArgumentMapper.java (79%) rename {spitfire-server/dropwizard-server => servers/server-lib}/src/main/java/org/triplea/spitfire/server/HttpController.java (100%) delete mode 100644 spitfire-server/dropwizard-server/src/test/java/org/triplea/spitfire/server/maps/MapTagAdminControllerTest.java delete mode 100644 spitfire-server/dropwizard-server/src/test/java/org/triplea/spitfire/server/maps/MapsControllerTest.java diff --git a/.docker/docker-compose.yml b/.docker/docker-compose.yml index 44636220840..9f290992f4d 100644 --- a/.docker/docker-compose.yml +++ b/.docker/docker-compose.yml @@ -24,6 +24,14 @@ services: - DB_URL=database:5432/error_report depends_on: - database + maps-server: + build: + context: ../servers/maps/server/ + dockerfile: Dockerfile + environment: + - DB_URL=database:5432/maps + depends_on: + - database database: image: postgres:10 environment: diff --git a/.docker/nginx/default.conf b/.docker/nginx/default.conf index fd88a8093fd..b37b111ebca 100644 --- a/.docker/nginx/default.conf +++ b/.docker/nginx/default.conf @@ -45,4 +45,13 @@ server { proxy_set_header X-Forwarded-Proto $scheme; proxy_read_timeout 90; } + + location /maps { + proxy_pass http://maps-server:8080; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_read_timeout 90; + } } diff --git a/build.gradle b/build.gradle index dc50b5dac77..73af24f1ddf 100644 --- a/build.gradle +++ b/build.gradle @@ -236,5 +236,6 @@ subprojects { // compose builds need WAR files for packaging, so we must run the corresponding package (shadowJar) tasks composeBuild.dependsOn ":servers:game-support:server:shadowJar" + composeBuild.dependsOn ":servers:maps:server:shadowJar" composeBuild.dependsOn ":spitfire-server:dropwizard-server:shadowJar" } diff --git a/game-app/game-core/build.gradle b/game-app/game-core/build.gradle index 0c44e0fc21c..4c336e83693 100644 --- a/game-app/game-core/build.gradle +++ b/game-app/game-core/build.gradle @@ -18,10 +18,12 @@ dependencies { implementation project(":game-app:map-data") implementation project(":game-app:game-relay-server") implementation project(":http-clients:lobby-client") + implementation project(":lib:http-client-lib") implementation project(":lib:java-extras") implementation project(":lib:swing-lib") implementation project(":lib:websocket-client") implementation project(":lib:xml-reader") + implementation project(":servers:maps:client") testImplementation "org.awaitility:awaitility:$awaitilityVersion" testImplementation "org.sonatype.goodies:goodies-prefs:$sonatypeGoodiesPrefsVersion" testImplementation project(":lib:swing-lib-test-support") diff --git a/game-app/game-core/src/main/java/games/strategy/engine/framework/map/listing/MapListingFetcher.java b/game-app/game-core/src/main/java/games/strategy/engine/framework/map/listing/MapListingFetcher.java index dd5de5f2f54..5175bae5798 100644 --- a/game-app/game-core/src/main/java/games/strategy/engine/framework/map/listing/MapListingFetcher.java +++ b/game-app/game-core/src/main/java/games/strategy/engine/framework/map/listing/MapListingFetcher.java @@ -5,6 +5,9 @@ import java.util.List; import lombok.experimental.UtilityClass; import lombok.extern.slf4j.Slf4j; +import org.triplea.config.product.ProductVersionReader; +import org.triplea.domain.data.SystemIdLoader; +import org.triplea.http.client.lib.ClientIdentifiers; import org.triplea.http.client.maps.listing.MapDownloadItem; import org.triplea.http.client.maps.listing.MapsClient; @@ -16,7 +19,13 @@ public class MapListingFetcher { public static List getMapDownloadList() { final var serverUri = ClientSetting.lobbyUri.getValueOrThrow(); try { - return MapsClient.newClient(serverUri).fetchMapListing(); + return MapsClient.newClient( + serverUri, + ClientIdentifiers.builder() + .applicationVersion(ProductVersionReader.getCurrentVersion().toMajorMinorString()) + .systemId(SystemIdLoader.load().getValue()) + .build()) + .fetchMapListing(); } catch (FeignException e) { log.warn( "Failed to download the list of available maps from TripleA servers.\n" diff --git a/game-app/game-core/src/main/java/org/triplea/util/Version.java b/game-app/game-core/src/main/java/org/triplea/util/Version.java index f15146b8561..d39517d32db 100644 --- a/game-app/game-core/src/main/java/org/triplea/util/Version.java +++ b/game-app/game-core/src/main/java/org/triplea/util/Version.java @@ -94,4 +94,11 @@ public boolean isCompatibleWithMapMinimumEngineVersion(final Version mapMinimumE return major > mapMinimumEngineVersion.major || (major == mapMinimumEngineVersion.major && minor >= mapMinimumEngineVersion.minor); } + + /** + * @return String with 'major.minor' format. + */ + public String toMajorMinorString() { + return major + "." + minor; + } } diff --git a/game-app/game-headed/build.gradle b/game-app/game-headed/build.gradle index 2ce4aa66173..89c137182e0 100644 --- a/game-app/game-headed/build.gradle +++ b/game-app/game-headed/build.gradle @@ -22,9 +22,11 @@ dependencies { implementation project(":game-app:map-data") implementation project(":http-clients:lobby-client") implementation project(":lib:feign-common") + implementation project(":lib:http-client-lib") implementation project(":lib:java-extras") implementation project(":lib:swing-lib") implementation project(":lib:websocket-client") + implementation project(":servers:maps:client") testImplementation "org.sonatype.goodies:goodies-prefs:$sonatypeGoodiesPrefsVersion" testImplementation project(":lib:test-common") } diff --git a/game-app/game-headed/src/main/java/games/strategy/engine/lobby/moderator/toolbox/ToolBoxWindow.java b/game-app/game-headed/src/main/java/games/strategy/engine/lobby/moderator/toolbox/ToolBoxWindow.java index 510210f9d64..52595009c76 100644 --- a/game-app/game-headed/src/main/java/games/strategy/engine/lobby/moderator/toolbox/ToolBoxWindow.java +++ b/game-app/game-headed/src/main/java/games/strategy/engine/lobby/moderator/toolbox/ToolBoxWindow.java @@ -5,6 +5,8 @@ import java.awt.Component; import lombok.experimental.UtilityClass; import org.triplea.http.client.lobby.moderator.toolbox.ModeratorToolboxClient; +import org.triplea.http.client.maps.admin.MapTagAdminClient; +import org.triplea.http.client.maps.listing.MapsClient; import org.triplea.swing.JFrameBuilder; import org.triplea.swing.SwingAction; import org.triplea.swing.jpanel.JPanelBuilder; @@ -18,7 +20,10 @@ public final class ToolBoxWindow { /** Shows the moderator toolbox UI window. */ public static void showWindow( - final Component parent, final ModeratorToolboxClient moderatorToolboxClient) { + final Component parent, + final ModeratorToolboxClient moderatorToolboxClient, + final MapsClient mapsClient, + final MapTagAdminClient mapTagAdminClient) { SwingAction.invokeNowOrLater( () -> JFrameBuilder.builder() @@ -36,6 +41,8 @@ public static void showWindow( TabFactory.builder() .frame(frame) .moderatorToolboxClient(moderatorToolboxClient) + .mapsClient(mapsClient) + .mapTagAdminClient(mapTagAdminClient) .build() .buildTabs()) .build()) diff --git a/game-app/game-headed/src/main/java/games/strategy/engine/lobby/moderator/toolbox/tabs/TabFactory.java b/game-app/game-headed/src/main/java/games/strategy/engine/lobby/moderator/toolbox/tabs/TabFactory.java index 57e0ea5eaa4..80066af589b 100644 --- a/game-app/game-headed/src/main/java/games/strategy/engine/lobby/moderator/toolbox/tabs/TabFactory.java +++ b/game-app/game-headed/src/main/java/games/strategy/engine/lobby/moderator/toolbox/tabs/TabFactory.java @@ -14,6 +14,8 @@ import javax.swing.JTabbedPane; import lombok.Builder; import org.triplea.http.client.lobby.moderator.toolbox.ModeratorToolboxClient; +import org.triplea.http.client.maps.admin.MapTagAdminClient; +import org.triplea.http.client.maps.listing.MapsClient; import org.triplea.swing.JTabbedPaneBuilder; /** Factory class to construct the 'tabs' that go in the moderator toolbox tabbed window. */ @@ -21,6 +23,8 @@ public final class TabFactory { @Nonnull private final JFrame frame; @Nonnull private final ModeratorToolboxClient moderatorToolboxClient; + @Nonnull private final MapsClient mapsClient; + @Nonnull private final MapTagAdminClient mapTagAdminClient; public JTabbedPane buildTabs() { return JTabbedPaneBuilder.builder() @@ -64,18 +68,15 @@ private Component buildModeratorsTab() { private Component buildMapsTab() { return MapsTab.builder() .parentWindowHeight(frame.getWidth()) - .mapsTabModel(buildMapsTabModel()) + .mapsTabModel( + MapsTabModel.builder() + .mapsClient(mapsClient) + .mapTagAdminClient(mapTagAdminClient) + .build()) .build() .get(); } - private MapsTabModel buildMapsTabModel() { - return MapsTabModel.builder() - .mapsClient(moderatorToolboxClient.getMapsClient()) - .mapTagAdminClient(moderatorToolboxClient.getMapTagAdminClient()) - .build(); - } - private Component buildEventLogTab() { return new EventLogTab(moderatorToolboxClient.getToolboxEventLogClient()).get(); } diff --git a/game-app/game-headed/src/main/java/games/strategy/engine/lobby/moderator/toolbox/tabs/maps/MapsTab.java b/game-app/game-headed/src/main/java/games/strategy/engine/lobby/moderator/toolbox/tabs/maps/MapsTab.java index 916e3a962c9..e2be69dee5a 100644 --- a/game-app/game-headed/src/main/java/games/strategy/engine/lobby/moderator/toolbox/tabs/maps/MapsTab.java +++ b/game-app/game-headed/src/main/java/games/strategy/engine/lobby/moderator/toolbox/tabs/maps/MapsTab.java @@ -15,8 +15,8 @@ import javax.swing.SwingConstants; import javax.swing.SwingUtilities; import lombok.Builder; +import org.triplea.http.client.maps.admin.MapTagMetaData; import org.triplea.http.client.maps.listing.MapDownloadItem; -import org.triplea.http.client.maps.tag.admin.MapTagMetaData; import org.triplea.java.ThreadRunner; import org.triplea.swing.JComboBoxBuilder; import org.triplea.swing.JSplitPaneBuilder; diff --git a/game-app/game-headed/src/main/java/games/strategy/engine/lobby/moderator/toolbox/tabs/maps/MapsTabModel.java b/game-app/game-headed/src/main/java/games/strategy/engine/lobby/moderator/toolbox/tabs/maps/MapsTabModel.java index c4787223611..ebac6213a0b 100644 --- a/game-app/game-headed/src/main/java/games/strategy/engine/lobby/moderator/toolbox/tabs/maps/MapsTabModel.java +++ b/game-app/game-headed/src/main/java/games/strategy/engine/lobby/moderator/toolbox/tabs/maps/MapsTabModel.java @@ -9,11 +9,11 @@ import lombok.Setter; import lombok.extern.slf4j.Slf4j; import org.triplea.http.client.GenericServerResponse; +import org.triplea.http.client.maps.admin.MapTagAdminClient; +import org.triplea.http.client.maps.admin.MapTagMetaData; +import org.triplea.http.client.maps.admin.UpdateMapTagRequest; import org.triplea.http.client.maps.listing.MapDownloadItem; import org.triplea.http.client.maps.listing.MapsClient; -import org.triplea.http.client.maps.tag.admin.MapTagAdminClient; -import org.triplea.http.client.maps.tag.admin.MapTagMetaData; -import org.triplea.http.client.maps.tag.admin.UpdateMapTagRequest; @Slf4j public class MapsTabModel { diff --git a/game-app/game-headed/src/main/java/games/strategy/triplea/ui/menubar/LobbyMenu.java b/game-app/game-headed/src/main/java/games/strategy/triplea/ui/menubar/LobbyMenu.java index c2c752508b5..5c5ac7d6821 100644 --- a/game-app/game-headed/src/main/java/games/strategy/triplea/ui/menubar/LobbyMenu.java +++ b/game-app/game-headed/src/main/java/games/strategy/triplea/ui/menubar/LobbyMenu.java @@ -10,6 +10,11 @@ import games.strategy.triplea.settings.ClientSetting; import games.strategy.triplea.ui.MacOsIntegration; import javax.swing.JMenuBar; +import org.triplea.config.product.ProductVersionReader; +import org.triplea.domain.data.SystemIdLoader; +import org.triplea.http.client.lib.ClientIdentifiers; +import org.triplea.http.client.maps.admin.MapTagAdminClient; +import org.triplea.http.client.maps.listing.MapsClient; import org.triplea.http.client.web.socket.client.connections.PlayerToLobbyConnection; import org.triplea.sound.SoundOptions; import org.triplea.swing.JMenuBuilder; @@ -51,6 +56,12 @@ public LobbyMenu( } if (loginResult.isModerator()) { + ClientIdentifiers clientIdentifiers = + ClientIdentifiers.builder() + .applicationVersion(ProductVersionReader.getCurrentVersion().toMajorMinorString()) + .systemId(SystemIdLoader.load().getValue()) + .apiKey(loginResult.getApiKey().getValue()) + .build(); add( new JMenuBuilder("Admin", 'M') .addMenuItem( @@ -58,7 +69,12 @@ public LobbyMenu( 'T', () -> ToolBoxWindow.showWindow( - lobbyFrame, playerToLobbyConnection.getHttpModeratorToolboxClient())) + lobbyFrame, + playerToLobbyConnection.getHttpModeratorToolboxClient(), + MapsClient.newClient( + ClientSetting.lobbyUri.getValueOrThrow(), clientIdentifiers), + MapTagAdminClient.newClient( + ClientSetting.lobbyUri.getValueOrThrow(), clientIdentifiers))) .build()); } diff --git a/game-app/game-headed/src/main/java/org/triplea/game/client/HeadedGameRunner.java b/game-app/game-headed/src/main/java/org/triplea/game/client/HeadedGameRunner.java index 154716a5776..fdec9f3210b 100644 --- a/game-app/game-headed/src/main/java/org/triplea/game/client/HeadedGameRunner.java +++ b/game-app/game-headed/src/main/java/org/triplea/game/client/HeadedGameRunner.java @@ -101,10 +101,7 @@ public static void main(final String[] args) { LobbyHttpClientConfig.setConfig( LobbyHttpClientConfig.builder() - .clientVersion( - ProductVersionReader.getCurrentVersion().getMajor() - + "." - + ProductVersionReader.getCurrentVersion().getMinor()) + .clientVersion(ProductVersionReader.getCurrentVersion().toMajorMinorString()) .systemId(SystemIdLoader.load().getValue()) .build()); diff --git a/http-clients/lobby-client/src/main/java/org/triplea/http/client/lobby/moderator/toolbox/ModeratorToolboxClient.java b/http-clients/lobby-client/src/main/java/org/triplea/http/client/lobby/moderator/toolbox/ModeratorToolboxClient.java index bd38ad91b76..3b8c1b4bfa6 100644 --- a/http-clients/lobby-client/src/main/java/org/triplea/http/client/lobby/moderator/toolbox/ModeratorToolboxClient.java +++ b/http-clients/lobby-client/src/main/java/org/triplea/http/client/lobby/moderator/toolbox/ModeratorToolboxClient.java @@ -9,8 +9,6 @@ import org.triplea.http.client.lobby.moderator.toolbox.log.ToolboxEventLogClient; import org.triplea.http.client.lobby.moderator.toolbox.management.ToolboxModeratorManagementClient; import org.triplea.http.client.lobby.moderator.toolbox.words.ToolboxBadWordsClient; -import org.triplea.http.client.maps.listing.MapsClient; -import org.triplea.http.client.maps.tag.admin.MapTagAdminClient; @Getter public class ModeratorToolboxClient { @@ -21,8 +19,6 @@ public class ModeratorToolboxClient { private final ToolboxModeratorManagementClient toolboxModeratorManagementClient; private final ToolboxBadWordsClient toolboxBadWordsClient; private final ToolboxEventLogClient toolboxEventLogClient; - private final MapsClient mapsClient; - private final MapTagAdminClient mapTagAdminClient; private ModeratorToolboxClient(final URI lobbyUri, final ApiKey apiKey) { toolboxAccessLogClient = ToolboxAccessLogClient.newClient(lobbyUri, apiKey); @@ -31,8 +27,6 @@ private ModeratorToolboxClient(final URI lobbyUri, final ApiKey apiKey) { toolboxModeratorManagementClient = ToolboxModeratorManagementClient.newClient(lobbyUri, apiKey); toolboxBadWordsClient = ToolboxBadWordsClient.newClient(lobbyUri, apiKey); toolboxEventLogClient = ToolboxEventLogClient.newClient(lobbyUri, apiKey); - mapsClient = MapsClient.newClient(lobbyUri); - mapTagAdminClient = MapTagAdminClient.newClient(lobbyUri, apiKey); } public static ModeratorToolboxClient newClient(final URI lobbyUri, final ApiKey apiKey) { diff --git a/lib/http-client-lib/src/main/java/org/triplea/http/client/lib/ClientIdentifiers.java b/lib/http-client-lib/src/main/java/org/triplea/http/client/lib/ClientIdentifiers.java new file mode 100644 index 00000000000..2a9a12b990e --- /dev/null +++ b/lib/http-client-lib/src/main/java/org/triplea/http/client/lib/ClientIdentifiers.java @@ -0,0 +1,28 @@ +package org.triplea.http.client.lib; + +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import lombok.Builder; + +@Builder +public class ClientIdentifiers { + public static final String VERSION_HEADER = "Triplea-Version"; + private static final String SYSTEM_ID_HEADER = "System-Id"; + + @Nonnull private final String applicationVersion; + @Nonnull private final String systemId; + @Nullable private final String apiKey; + + /** Creates headers containing 'System-Id' only. */ + public Map createHeaders() { + final Map headerMap = new HashMap<>(); + headerMap.put(VERSION_HEADER, applicationVersion); + headerMap.put(SYSTEM_ID_HEADER, systemId); + Optional.ofNullable(apiKey) + .ifPresent(apiKey -> headerMap.put("Authorization", "Bearer " + apiKey)); + return headerMap; + } +} diff --git a/lib/http-client-lib/src/main/java/org/triplea/http/client/lib/HttpClientHeaders.java b/lib/http-client-lib/src/main/java/org/triplea/http/client/lib/HttpClientHeaders.java deleted file mode 100644 index a7956d52cea..00000000000 --- a/lib/http-client-lib/src/main/java/org/triplea/http/client/lib/HttpClientHeaders.java +++ /dev/null @@ -1,33 +0,0 @@ -package org.triplea.http.client.lib; - -import java.util.HashMap; -import java.util.Map; -import javax.annotation.Nonnull; -import lombok.Builder; -import org.triplea.domain.data.SystemIdLoader; - -/** Small class to encapsulate api key and create http Authorization header. */ -@Builder -public class HttpClientHeaders { - public static final String VERSION_HEADER = "Triplea-Version"; - public static final String SYSTEM_ID_HEADER = "System-Id"; - - @Nonnull private final String clientVersion; - private final String apiKey; - private static final String systemId = SystemIdLoader.load().getValue(); - - public static Map defaultHeadersWithClientVersion(String clientVersion) { - return builder().clientVersion(clientVersion).build().createHeaders(); - } - - /** Creates headers containing 'System-Id' only. */ - public Map createHeaders() { - final Map headerMap = new HashMap<>(); - headerMap.put(VERSION_HEADER, clientVersion); - headerMap.put(SYSTEM_ID_HEADER, systemId); - if (apiKey != null) { - headerMap.put("Authorization", "Bearer " + apiKey); - } - return headerMap; - } -} diff --git a/servers/game-support/client/src/main/java/org/triplea/http/client/error/report/ErrorReportClient.java b/servers/game-support/client/src/main/java/org/triplea/http/client/error/report/ErrorReportClient.java index 4e49ccb7347..d1aed83d477 100644 --- a/servers/game-support/client/src/main/java/org/triplea/http/client/error/report/ErrorReportClient.java +++ b/servers/game-support/client/src/main/java/org/triplea/http/client/error/report/ErrorReportClient.java @@ -4,7 +4,7 @@ import feign.RequestLine; import java.net.URI; import org.triplea.http.client.HttpClient; -import org.triplea.http.client.lib.HttpClientHeaders; +import org.triplea.http.client.lib.ClientIdentifiers; /** Http client to upload error reports to the http lobby server. */ public interface ErrorReportClient { @@ -13,11 +13,8 @@ public interface ErrorReportClient { int MAX_REPORTS_PER_DAY = 5; /** Creates an error report uploader clients, sends error reports and gets a response back. */ - static ErrorReportClient newClient(URI uri, String clientVersion) { - return HttpClient.newClient( - ErrorReportClient.class, - uri, - HttpClientHeaders.defaultHeadersWithClientVersion(clientVersion)); + static ErrorReportClient newClient(URI uri, ClientIdentifiers clientIdentifiers) { + return HttpClient.newClient(ErrorReportClient.class, uri, clientIdentifiers.createHeaders()); } /** diff --git a/servers/game-support/server/configuration.yml b/servers/game-support/server/configuration.yml index 137defc64ee..b5f4e8a22f9 100644 --- a/servers/game-support/server/configuration.yml +++ b/servers/game-support/server/configuration.yml @@ -2,14 +2,12 @@ githubApiToken: ${GITHUB_API_TOKEN:-} githubWebServiceUrl: https://api.github.com githubGameOrg: triplea-game githubGameRepo: triplea -githubMapsOrgName: triplea-maps # When disabled, API calls to github to create error reports will not # be made and instead a hardcoded value returned. errorReportToGithubEnabled: ${ERROR_REPORT_TO_GITHUB_ENABLED:-false} - database: driverClass: org.postgresql.Driver user: ${DATABASE_USER:-error_report_user} diff --git a/servers/game-support/server/src/main/java/org/triplea/server/error/reporting/ErrorReportController.java b/servers/game-support/server/src/main/java/org/triplea/server/error/reporting/ErrorReportController.java index dea2cad2036..4524d96a554 100644 --- a/servers/game-support/server/src/main/java/org/triplea/server/error/reporting/ErrorReportController.java +++ b/servers/game-support/server/src/main/java/org/triplea/server/error/reporting/ErrorReportController.java @@ -18,7 +18,7 @@ import org.triplea.http.client.error.report.ErrorReportRequest; import org.triplea.http.client.error.report.ErrorReportResponse; import org.triplea.http.client.github.GithubApiClient; -import org.triplea.http.client.lib.HttpClientHeaders; +import org.triplea.http.client.lib.ClientIdentifiers; import org.triplea.server.error.reporting.upload.CanUploadErrorReportStrategy; import org.triplea.server.error.reporting.upload.CreateIssueParams; import org.triplea.server.error.reporting.upload.ErrorReportModule; @@ -71,7 +71,7 @@ public ErrorReportResponse uploadErrorReport( return errorReportIngestion.createErrorReport( CreateIssueParams.builder() .ip(IpAddressExtractor.extractIpAddress(request)) - .systemId(request.getHeader(HttpClientHeaders.VERSION_HEADER)) + .systemId(request.getHeader(ClientIdentifiers.VERSION_HEADER)) .errorReportRequest(errorReport) .build()); } diff --git a/servers/game-support/server/src/test/java/org/triplea/modules/error/reporting/ErrorReportControllerIntegrationTest.java b/servers/game-support/server/src/test/java/org/triplea/modules/error/reporting/ErrorReportControllerIntegrationTest.java index 31ec6d0a0db..00a7a5dd6dd 100644 --- a/servers/game-support/server/src/test/java/org/triplea/modules/error/reporting/ErrorReportControllerIntegrationTest.java +++ b/servers/game-support/server/src/test/java/org/triplea/modules/error/reporting/ErrorReportControllerIntegrationTest.java @@ -11,6 +11,7 @@ import org.triplea.http.client.error.report.ErrorReportClient; import org.triplea.http.client.error.report.ErrorReportRequest; import org.triplea.http.client.error.report.ErrorReportResponse; +import org.triplea.http.client.lib.ClientIdentifiers; import org.triplea.test.common.RequiresDatabase; @ExtendWith(ErrorReportServerTestExtension.class) @@ -19,7 +20,10 @@ class ErrorReportControllerIntegrationTest { private final ErrorReportClient client; ErrorReportControllerIntegrationTest(final URI localhost) { - client = ErrorReportClient.newClient(localhost, "0.0"); + client = + ErrorReportClient.newClient( + localhost, + ClientIdentifiers.builder().applicationVersion("0.0").systemId("system").build()); } @Test diff --git a/servers/maps/client/build.gradle b/servers/maps/client/build.gradle index e69de29bb2d..8ab4f017750 100644 --- a/servers/maps/client/build.gradle +++ b/servers/maps/client/build.gradle @@ -0,0 +1,9 @@ +dependencies { + implementation "io.github.openfeign:feign-core:$feignCoreVersion" + implementation "io.github.openfeign:feign-gson:$feignGsonVersion" + implementation project(":lib:feign-common") + implementation project(":lib:http-client-lib") + implementation project(":lib:java-extras") + testImplementation "ru.lanwen.wiremock:wiremock-junit5:$wireMockJunit5Version" + testImplementation project(":lib:test-common") +} diff --git a/http-clients/lobby-client/src/main/java/org/triplea/http/client/maps/tag/admin/MapTagAdminClient.java b/servers/maps/client/src/main/java/org/triplea/http/client/maps/admin/MapTagAdminClient.java similarity index 68% rename from http-clients/lobby-client/src/main/java/org/triplea/http/client/maps/tag/admin/MapTagAdminClient.java rename to servers/maps/client/src/main/java/org/triplea/http/client/maps/admin/MapTagAdminClient.java index 9d2792a455f..1a65fa41ca5 100644 --- a/http-clients/lobby-client/src/main/java/org/triplea/http/client/maps/tag/admin/MapTagAdminClient.java +++ b/servers/maps/client/src/main/java/org/triplea/http/client/maps/admin/MapTagAdminClient.java @@ -1,21 +1,21 @@ -package org.triplea.http.client.maps.tag.admin; +package org.triplea.http.client.maps.admin; import feign.RequestLine; import java.net.URI; import java.util.List; -import org.triplea.domain.data.ApiKey; import org.triplea.http.client.GenericServerResponse; import org.triplea.http.client.HttpClient; -import org.triplea.http.client.lobby.AuthenticationHeaders; +import org.triplea.http.client.lib.ClientIdentifiers; /** Http client for 'map tag' administrative functionality. EG: updating a maps tag value. */ public interface MapTagAdminClient { String GET_MAP_TAGS_META_DATA_PATH = "/maps/list-tags"; String UPDATE_MAP_TAG_PATH = "/maps/update-tag"; - static MapTagAdminClient newClient(final URI mapsServerUri, final ApiKey apiKey) { + static MapTagAdminClient newClient( + final URI mapsServerUri, final ClientIdentifiers clientIdentifiers) { return HttpClient.newClient( - MapTagAdminClient.class, mapsServerUri, new AuthenticationHeaders(apiKey).createHeaders()); + MapTagAdminClient.class, mapsServerUri, clientIdentifiers.createHeaders()); } @RequestLine("GET " + MapTagAdminClient.GET_MAP_TAGS_META_DATA_PATH) diff --git a/http-clients/lobby-client/src/main/java/org/triplea/http/client/maps/tag/admin/MapTagMetaData.java b/servers/maps/client/src/main/java/org/triplea/http/client/maps/admin/MapTagMetaData.java similarity index 89% rename from http-clients/lobby-client/src/main/java/org/triplea/http/client/maps/tag/admin/MapTagMetaData.java rename to servers/maps/client/src/main/java/org/triplea/http/client/maps/admin/MapTagMetaData.java index cfc2feab3bc..743df1f3d10 100644 --- a/http-clients/lobby-client/src/main/java/org/triplea/http/client/maps/tag/admin/MapTagMetaData.java +++ b/servers/maps/client/src/main/java/org/triplea/http/client/maps/admin/MapTagMetaData.java @@ -1,4 +1,4 @@ -package org.triplea.http.client.maps.tag.admin; +package org.triplea.http.client.maps.admin; import java.util.List; import javax.annotation.Nonnull; diff --git a/http-clients/lobby-client/src/main/java/org/triplea/http/client/maps/tag/admin/UpdateMapTagRequest.java b/servers/maps/client/src/main/java/org/triplea/http/client/maps/admin/UpdateMapTagRequest.java similarity index 87% rename from http-clients/lobby-client/src/main/java/org/triplea/http/client/maps/tag/admin/UpdateMapTagRequest.java rename to servers/maps/client/src/main/java/org/triplea/http/client/maps/admin/UpdateMapTagRequest.java index 990d3073c18..11d3cfb1662 100644 --- a/http-clients/lobby-client/src/main/java/org/triplea/http/client/maps/tag/admin/UpdateMapTagRequest.java +++ b/servers/maps/client/src/main/java/org/triplea/http/client/maps/admin/UpdateMapTagRequest.java @@ -1,4 +1,4 @@ -package org.triplea.http.client.maps.tag.admin; +package org.triplea.http.client.maps.admin; import lombok.AllArgsConstructor; import lombok.Builder; diff --git a/http-clients/lobby-client/src/main/java/org/triplea/http/client/maps/listing/MapDownloadItem.java b/servers/maps/client/src/main/java/org/triplea/http/client/maps/listing/MapDownloadItem.java similarity index 100% rename from http-clients/lobby-client/src/main/java/org/triplea/http/client/maps/listing/MapDownloadItem.java rename to servers/maps/client/src/main/java/org/triplea/http/client/maps/listing/MapDownloadItem.java diff --git a/http-clients/lobby-client/src/main/java/org/triplea/http/client/maps/listing/MapTag.java b/servers/maps/client/src/main/java/org/triplea/http/client/maps/listing/MapTag.java similarity index 100% rename from http-clients/lobby-client/src/main/java/org/triplea/http/client/maps/listing/MapTag.java rename to servers/maps/client/src/main/java/org/triplea/http/client/maps/listing/MapTag.java diff --git a/http-clients/lobby-client/src/main/java/org/triplea/http/client/maps/listing/MapsClient.java b/servers/maps/client/src/main/java/org/triplea/http/client/maps/listing/MapsClient.java similarity index 71% rename from http-clients/lobby-client/src/main/java/org/triplea/http/client/maps/listing/MapsClient.java rename to servers/maps/client/src/main/java/org/triplea/http/client/maps/listing/MapsClient.java index f52357d27a1..93150be758d 100644 --- a/http-clients/lobby-client/src/main/java/org/triplea/http/client/maps/listing/MapsClient.java +++ b/servers/maps/client/src/main/java/org/triplea/http/client/maps/listing/MapsClient.java @@ -5,7 +5,7 @@ import java.net.URI; import java.util.List; import org.triplea.http.client.HttpClient; -import org.triplea.http.client.lobby.AuthenticationHeaders; +import org.triplea.http.client.lib.ClientIdentifiers; /** * Http client to communicate with the maps server and get a listing of maps available for download. @@ -13,9 +13,8 @@ public interface MapsClient { String MAPS_LISTING_PATH = "/maps/listing"; - static MapsClient newClient(URI mapsServerUri) { - return HttpClient.newClient( - MapsClient.class, mapsServerUri, AuthenticationHeaders.systemIdHeaders()); + static MapsClient newClient(URI mapsServerUri, ClientIdentifiers clientIdentifiers) { + return HttpClient.newClient(MapsClient.class, mapsServerUri, clientIdentifiers.createHeaders()); } /** diff --git a/servers/maps/client/src/test/resources/logback-test.xml b/servers/maps/client/src/test/resources/logback-test.xml new file mode 100644 index 00000000000..2222e345e83 --- /dev/null +++ b/servers/maps/client/src/test/resources/logback-test.xml @@ -0,0 +1,11 @@ + + + + %d [%thread] %logger{36} %-5level: %msg%n + + + + + + + diff --git a/servers/maps/server/Dockerfile b/servers/maps/server/Dockerfile new file mode 100644 index 00000000000..d6412e74f26 --- /dev/null +++ b/servers/maps/server/Dockerfile @@ -0,0 +1,6 @@ +FROM openjdk:11-jre-slim-buster + +EXPOSE 8080 +ADD configuration.yml / +ADD build/libs/maps-server.jar / +CMD java -jar maps-server.jar server /configuration.yml diff --git a/servers/maps/server/build.gradle b/servers/maps/server/build.gradle index 833b6bb8bc0..82a629d5373 100644 --- a/servers/maps/server/build.gradle +++ b/servers/maps/server/build.gradle @@ -1,14 +1,59 @@ +plugins { + id 'application' + id 'com.github.johnrengelman.shadow' version '7.1.2' +} + +archivesBaseName = "maps-server" +mainClassName = 'org.triplea.maps.MapsServerApplication' + +ext { + releasesDir = file("$buildDir/releases") +} + +jar { + manifest { + attributes 'Main-Class': mainClassName + } +} + +task portableInstaller(type: Zip, group: 'release', dependsOn: shadowJar) { + from file('configuration.yml') + + from(shadowJar.outputs) { + into 'bin' + } +} + +task release(group: 'release', dependsOn: portableInstaller) { + doLast { + publishArtifacts(portableInstaller.outputs.files) + } +} + +shadowJar { + archiveClassifier.set '' + // mergeServiceFiles is needed by dropwizard + // Without this configuration parsing breaks and is unable to find connector type 'http' for + // the following YAML snippet: server: {applicationConnectors: [{type: http, port: 8080}] + mergeServiceFiles() +} + + dependencies { implementation "io.dropwizard:dropwizard-core:$dropwizardVersion" implementation "io.dropwizard:dropwizard-jdbi3:$dropwizardVersion" implementation "org.jdbi:jdbi3-core:$jdbiVersion" implementation "org.jdbi:jdbi3-sqlobject:$jdbiVersion" + implementation project(':http-clients:github-client') - implementation project(':http-clients:lobby-client') + implementation project(':lib:feign-common') implementation project(':lib:java-extras') + implementation project(':servers:maps:client') implementation project(':servers:server-lib') implementation project(':spitfire-server:database') + runtimeOnly "org.postgresql:postgresql:$postgresqlVersion" + testImplementation "com.github.database-rider:rider-junit5:$databaseRiderVersion" testImplementation "io.dropwizard:dropwizard-testing:$dropwizardVersion" testImplementation "uk.co.datumedge:hamcrest-json:$hamcrestJsonVersion" diff --git a/servers/maps/server/configuration.yml b/servers/maps/server/configuration.yml new file mode 100644 index 00000000000..92b59c744b3 --- /dev/null +++ b/servers/maps/server/configuration.yml @@ -0,0 +1,55 @@ +githubApiToken: ${GITHUB_API_TOKEN:-} +githubWebServiceUrl: https://api.github.com +githubMapsOrgName: triplea-maps + + +# Whether to print out SQL statements as executed, useful for debugging. +logSqlStatements: false + +database: + driverClass: org.postgresql.Driver + user: ${DATABASE_USER:-lobby_user} + password: ${DATABASE_PASSWORD:-lobby} + url: jdbc:postgresql://${DB_URL:-localhost:5432/lobby_db} + properties: + charSet: UTF-8 + # the maximum amount of time to wait on an empty pool before throwing an exception + maxWaitForConnection: 1s + + # the SQL query to run when validating a connection's liveness + validationQuery: select 1 + + # the minimum number of connections to keep open + minSize: 8 + + # the maximum number of connections to keep open + maxSize: 32 + + # whether or not idle connections should be validated + checkConnectionWhileIdle: false + + # the amount of time to sleep between runs of the idle connection validation, abandoned cleaner and idle pool resizing + evictionInterval: 10s + + # the minimum amount of time an connection must sit idle in the pool before it is eligible for eviction + minIdleTime: 1 minute + + +logging: + # The default level of all loggers. Can be OFF, ERROR, WARN, INFO, DEBUG, TRACE, or ALL. + level: INFO + loggers: + # Set this to DEBUG to troubleshoot HTTP 400 "Unable to process JSON" errors. + io.dropwizard.jersey.jackson.JsonProcessingExceptionMapper: INFO + +server: + applicationConnectors: + - type: http + port: ${HTTP_PORT:-8080} + # useForwardedHeaders is important for when behind a reverse proxy (NGINX) + # Without this 'getRemoteAddr' will return the IP of the reverse proxy server. + # By default when building locally useForwardedPorts should be 'false', but + # for all other environments that do have a NGINX server, the value should be + # set to true. + useForwardedHeaders: ${USE_FORWARDED_HEADERS:-false} + adminConnectors: [] diff --git a/servers/maps/server/src/main/java/configuration.yml b/servers/maps/server/src/main/java/configuration.yml new file mode 100644 index 00000000000..9cd8553b1dc --- /dev/null +++ b/servers/maps/server/src/main/java/configuration.yml @@ -0,0 +1,29 @@ +githubApiToken: ${GITHUB_API_TOKEN:-} +githubWebServiceUrl: https://api.github.com +githubMapsOrgName: triplea-maps + + +# If map indexing is enabled, it will begin shortly after server startup. +# If disabled no map indexing will occur. +mapIndexingEnabled: ${MAP_INDEXING_ENABLED:-false} + +# How often between map indexing runs. On each map indexing run we will +# index all maps. If the previous map indexing run is still going +# we will then have multiple indexing jobs running at the same time. +# To avoid overlapping indexing jobs, this value needs to be greater than: +# (number of maps) * (processing time) * (indexingTaskDelaySeconds / 60) +mapIndexingPeriodMinutes: ${MAP_INDEXING_PERIOD_MINUTES:-300} + +# Time period in seconds between indexing each individual map. This must +# be configured to avoid github API rate limiting. +# Eg: +# 1 -> one indexing task per second -> 3600 requests per hour. +# 5 -> one indexing task every 5 seconds -> 720 requests per hour. +# 60 -> one indexing task per minute -> 60 requests per hour. +# 120 -> one indexing task every other minute -> 30 requests per hour. +# Unauthenticated Github API requests are limited to 60 request per hour. +# Authenticated Github API requests are limited to 1000 requests per hour. +indexingTaskDelaySeconds: ${MAP_INDEXING_DELAY_SECONDS:-120} + +# Whether to print out SQL statements as executed, useful for debugging. +logSqlStatements: false diff --git a/spitfire-server/dropwizard-server/src/main/java/org/triplea/spitfire/server/maps/MapTagAdminController.java b/servers/maps/server/src/main/java/org/triplea/maps/MapTagAdminController.java similarity index 78% rename from spitfire-server/dropwizard-server/src/main/java/org/triplea/spitfire/server/maps/MapTagAdminController.java rename to servers/maps/server/src/main/java/org/triplea/maps/MapTagAdminController.java index 48ed2acd1e2..b1497936e91 100644 --- a/spitfire-server/dropwizard-server/src/main/java/org/triplea/spitfire/server/maps/MapTagAdminController.java +++ b/servers/maps/server/src/main/java/org/triplea/maps/MapTagAdminController.java @@ -1,17 +1,15 @@ -package org.triplea.spitfire.server.maps; +package org.triplea.maps; import java.util.List; -import javax.annotation.security.RolesAllowed; import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.Path; import lombok.AllArgsConstructor; import org.jdbi.v3.core.Jdbi; -import org.triplea.db.dao.user.role.UserRole; import org.triplea.http.client.GenericServerResponse; -import org.triplea.http.client.maps.tag.admin.MapTagAdminClient; -import org.triplea.http.client.maps.tag.admin.MapTagMetaData; -import org.triplea.http.client.maps.tag.admin.UpdateMapTagRequest; +import org.triplea.http.client.maps.admin.MapTagAdminClient; +import org.triplea.http.client.maps.admin.MapTagMetaData; +import org.triplea.http.client.maps.admin.UpdateMapTagRequest; import org.triplea.maps.tags.MapTagAdminModule; import org.triplea.maps.tags.UpdateMapTagResult; import org.triplea.spitfire.server.HttpController; @@ -30,7 +28,7 @@ public static MapTagAdminController build(final Jdbi jdbi) { */ @GET @Path(MapTagAdminClient.GET_MAP_TAGS_META_DATA_PATH) - @RolesAllowed(UserRole.MODERATOR) + // @RolesAllowed(UserRole.MODERATOR) public List fetchAvailableMapTags() { return mapTagAdminModule.fetchMapTags(); } @@ -41,7 +39,7 @@ public List fetchAvailableMapTags() { */ @POST @Path(MapTagAdminClient.UPDATE_MAP_TAG_PATH) - @RolesAllowed(UserRole.MODERATOR) + // @RolesAllowed(UserRole.MODERATOR) public GenericServerResponse updateMapTag(final UpdateMapTagRequest updateMapTagRequest) { final UpdateMapTagResult result = mapTagAdminModule.updateMapTag(updateMapTagRequest); diff --git a/spitfire-server/dropwizard-server/src/main/java/org/triplea/spitfire/server/maps/MapsController.java b/servers/maps/server/src/main/java/org/triplea/maps/MapsController.java similarity index 96% rename from spitfire-server/dropwizard-server/src/main/java/org/triplea/spitfire/server/maps/MapsController.java rename to servers/maps/server/src/main/java/org/triplea/maps/MapsController.java index 87ac9ed6cc6..dea3eb959b4 100644 --- a/spitfire-server/dropwizard-server/src/main/java/org/triplea/spitfire/server/maps/MapsController.java +++ b/servers/maps/server/src/main/java/org/triplea/maps/MapsController.java @@ -1,4 +1,4 @@ -package org.triplea.spitfire.server.maps; +package org.triplea.maps; import java.util.List; import java.util.function.Supplier; diff --git a/servers/maps/server/src/main/java/org/triplea/maps/MapsServerApplication.java b/servers/maps/server/src/main/java/org/triplea/maps/MapsServerApplication.java new file mode 100644 index 00000000000..a8da9abeca3 --- /dev/null +++ b/servers/maps/server/src/main/java/org/triplea/maps/MapsServerApplication.java @@ -0,0 +1,75 @@ +package org.triplea.maps; + +import io.dropwizard.Application; +import io.dropwizard.jdbi3.JdbiFactory; +import io.dropwizard.setup.Bootstrap; +import io.dropwizard.setup.Environment; +import java.util.List; +import lombok.extern.slf4j.Slf4j; +import org.jdbi.v3.core.Jdbi; +import org.triplea.dropwizard.common.IllegalArgumentMapper; +import org.triplea.dropwizard.common.JdbiLogging; +import org.triplea.dropwizard.common.ServerConfiguration; +import org.triplea.maps.indexing.MapsIndexingObjectFactory; + +/** + * Main entry-point for launching drop wizard HTTP server. This class is responsible for configuring + * any Jersey plugins, registering resources (controllers) and injecting those resources with + * configuration properties from 'AppConfig'. + */ +@Slf4j +public class MapsServerApplication extends Application { + + private static final String[] DEFAULT_ARGS = new String[] {"server", "configuration.yml"}; + + private ServerConfiguration serverConfiguration; + + /** + * Main entry-point method, launches the drop-wizard http server. If no args are passed then will + * use default values suitable for local development. + */ + public static void main(final String[] args) throws Exception { + final MapsServerApplication application = new MapsServerApplication(); + // if no args are provided then we will use default values. + application.run(args.length == 0 ? DEFAULT_ARGS : args); + } + + @Override + public void initialize(final Bootstrap bootstrap) { + serverConfiguration = + ServerConfiguration.build(bootstrap) + .enableEnvironmentVariablesInConfig() + .enableBetterJdbiExceptions(); + } + + @Override + public void run(final MapsServerConfig configuration, final Environment environment) { + final Jdbi jdbi = + new JdbiFactory() + .build(environment, configuration.getDatabase(), "postgresql-connection-pool"); + + MapsModuleRowMappers.rowMappers().forEach(jdbi::registerRowMapper); + + if (configuration.isLogSqlStatements()) { + JdbiLogging.registerSqlLogger(jdbi); + } + + if (configuration.isMapIndexingEnabled()) { + environment + .lifecycle() + .manage(MapsIndexingObjectFactory.buildMapsIndexingSchedule(configuration, jdbi)); + log.info( + "Map indexing is enabled to run every:" + + " {} minutes with one map indexing request every {} seconds", + configuration.getMapIndexingPeriodMinutes(), + configuration.getIndexingTaskDelaySeconds()); + } else { + log.info("Map indexing is disabled"); + } + + serverConfiguration.registerExceptionMappers(environment, List.of(new IllegalArgumentMapper())); + + List.of(MapsController.build(jdbi), MapTagAdminController.build(jdbi)) + .forEach(controller -> environment.jersey().register(controller)); + } +} diff --git a/servers/maps/server/src/main/java/org/triplea/maps/MapsServerConfig.java b/servers/maps/server/src/main/java/org/triplea/maps/MapsServerConfig.java new file mode 100644 index 00000000000..d2b3aac2a45 --- /dev/null +++ b/servers/maps/server/src/main/java/org/triplea/maps/MapsServerConfig.java @@ -0,0 +1,61 @@ +package org.triplea.maps; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.dropwizard.Configuration; +import io.dropwizard.db.DataSourceFactory; +import java.net.URI; +import javax.validation.Valid; +import javax.validation.constraints.NotNull; +import lombok.Getter; +import lombok.Setter; +import org.triplea.http.client.github.GithubApiClient; + +/** + * This configuration class represents the configuration values in the server YML configuration. An + * instance of this class is created by DropWizard on launch and then is passed to the application + * class. Values can be injected into the application by using environment variables in the server + * YML configuration file. + */ +public class MapsServerConfig extends Configuration { + + @Valid @NotNull @JsonProperty @Getter + private final DataSourceFactory database = new DataSourceFactory(); + + @Getter(onMethod_ = {@JsonProperty}) + @Setter(onMethod_ = {@JsonProperty}) + private String githubWebServiceUrl; + + /** Webservice token, should be an API token for the TripleA builder bot account. */ + @Getter(onMethod_ = {@JsonProperty}) + @Setter(onMethod_ = {@JsonProperty}) + private String githubApiToken; + + @Getter(onMethod_ = {@JsonProperty}) + @Setter(onMethod_ = {@JsonProperty}) + private String githubMapsOrgName; + + @Getter(onMethod_ = {@JsonProperty}) + @Setter(onMethod_ = {@JsonProperty}) + private boolean mapIndexingEnabled; + + @Getter(onMethod_ = {@JsonProperty}) + @Setter(onMethod_ = {@JsonProperty}) + private int mapIndexingPeriodMinutes; + + @Getter(onMethod_ = {@JsonProperty}) + @Setter(onMethod_ = {@JsonProperty}) + private int indexingTaskDelaySeconds; + + @Getter(onMethod_ = {@JsonProperty}) + @Setter(onMethod_ = {@JsonProperty}) + private boolean logSqlStatements; + + public GithubApiClient createGithubApiClient() { + return GithubApiClient.builder() + .stubbingModeEnabled(false) + .authToken(githubApiToken) + .uri(URI.create(githubWebServiceUrl)) + .org(githubMapsOrgName) + .build(); + } +} diff --git a/servers/maps/server/src/main/java/org/triplea/maps/indexing/MapsIndexingObjectFactory.java b/servers/maps/server/src/main/java/org/triplea/maps/indexing/MapsIndexingObjectFactory.java index 327af4735e6..e35914ebd25 100644 --- a/servers/maps/server/src/main/java/org/triplea/maps/indexing/MapsIndexingObjectFactory.java +++ b/servers/maps/server/src/main/java/org/triplea/maps/indexing/MapsIndexingObjectFactory.java @@ -1,8 +1,6 @@ package org.triplea.maps.indexing; -import com.google.common.annotations.VisibleForTesting; import io.dropwizard.lifecycle.Managed; -import java.net.URI; import java.time.Duration; import java.time.Instant; import java.util.function.BiPredicate; @@ -10,7 +8,7 @@ import org.jdbi.v3.core.Jdbi; import org.triplea.http.client.github.GithubApiClient; import org.triplea.http.client.github.MapRepoListing; -import org.triplea.maps.MapsModuleConfig; +import org.triplea.maps.MapsServerConfig; import org.triplea.maps.indexing.tasks.CommitDateFetcher; import org.triplea.maps.indexing.tasks.DownloadSizeFetcher; import org.triplea.maps.indexing.tasks.MapDescriptionReader; @@ -25,34 +23,24 @@ public class MapsIndexingObjectFactory { * 'start()' method must be called for map indexing to begin. */ public static Managed buildMapsIndexingSchedule( - final MapsModuleConfig configuration, final Jdbi jdbi) { + final MapsServerConfig configuration, final Jdbi jdbi) { + + var githubApiClient = configuration.createGithubApiClient(); return ScheduledTask.builder() .taskName("Map-Indexing") .delay(Duration.ofSeconds(10)) .period(Duration.ofMinutes(configuration.getMapIndexingPeriodMinutes())) - .task(mapIndexingTaskRunner(configuration, jdbi)) - .build(); - } - - MapIndexingTaskRunner mapIndexingTaskRunner( - final MapsModuleConfig configuration, final Jdbi jdbi) { - var githubApiClient = configuration.createMapsRepoGithubApiClient(); - - return MapIndexingTaskRunner.builder() - .githubApiClient(githubApiClient) - .mapIndexer(mapIndexingTask(githubApiClient, skipMapIndexingCheck(jdbi))) - .mapIndexDao(jdbi.onDemand(MapIndexDao.class)) - .indexingTaskDelaySeconds(configuration.getIndexingTaskDelaySeconds()) - .build(); - } - - @VisibleForTesting - GithubApiClient githubApiClient(String org, String webserviceUrl, String apiToken) { - return GithubApiClient.builder() - .org(org) - .uri(URI.create(webserviceUrl)) - .authToken(apiToken) + .task( + MapIndexingTaskRunner.builder() + .githubApiClient(githubApiClient) + .mapIndexer( + mapIndexingTask( + githubApiClient, + new SkipMapIndexingCheck(jdbi.onDemand(MapIndexDao.class)))) + .mapIndexDao(jdbi.onDemand(MapIndexDao.class)) + .indexingTaskDelaySeconds(configuration.getIndexingTaskDelaySeconds()) + .build()) .build(); } @@ -67,8 +55,4 @@ MapIndexingTask mapIndexingTask( .downloadSizeFetcher(new DownloadSizeFetcher()) .build(); } - - BiPredicate skipMapIndexingCheck(final Jdbi jdbi) { - return new SkipMapIndexingCheck(jdbi.onDemand(MapIndexDao.class)); - } } diff --git a/servers/maps/server/src/main/java/org/triplea/maps/tags/MapTagAdminModule.java b/servers/maps/server/src/main/java/org/triplea/maps/tags/MapTagAdminModule.java index 0b66ac7c5ce..47c54532836 100644 --- a/servers/maps/server/src/main/java/org/triplea/maps/tags/MapTagAdminModule.java +++ b/servers/maps/server/src/main/java/org/triplea/maps/tags/MapTagAdminModule.java @@ -11,8 +11,8 @@ import lombok.AllArgsConstructor; import lombok.Getter; import org.jdbi.v3.core.Jdbi; -import org.triplea.http.client.maps.tag.admin.MapTagMetaData; -import org.triplea.http.client.maps.tag.admin.UpdateMapTagRequest; +import org.triplea.http.client.maps.admin.MapTagMetaData; +import org.triplea.http.client.maps.admin.UpdateMapTagRequest; @AllArgsConstructor public class MapTagAdminModule { diff --git a/servers/maps/server/src/test/java/org/triplea/maps/indexing/MapIndexingIntegrationTest.java b/servers/maps/server/src/test/java/org/triplea/maps/indexing/MapIndexingIntegrationTest.java index 0a8c0cb46e4..09887fcb988 100644 --- a/servers/maps/server/src/test/java/org/triplea/maps/indexing/MapIndexingIntegrationTest.java +++ b/servers/maps/server/src/test/java/org/triplea/maps/indexing/MapIndexingIntegrationTest.java @@ -5,25 +5,28 @@ import static org.hamcrest.core.IsNull.notNullValue; import static org.hamcrest.core.StringContains.containsString; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.triplea.http.client.github.MapRepoListing; +import org.triplea.maps.MapsServerConfig; +import org.triplea.test.common.RequiresDatabase; /** * Test that does a live indexing (goes over network to github) of 'triplea-maps/test-map'. We'll * build an indexer and then run indexing on the test map. The test map will be in a known state and * we'll then verify the returned indexing results are as expected. */ -@Disabled +@RequiresDatabase public class MapIndexingIntegrationTest { @Test void runIndexingOnTestMap() { + MapsServerConfig mapsServerConfig = new MapsServerConfig(); + mapsServerConfig.setGithubMapsOrgName("triplea-maps"); + mapsServerConfig.setGithubWebServiceUrl("https://api.github.com"); + final MapIndexingTask mapIndexingTaskRunner = MapsIndexingObjectFactory.mapIndexingTask( - MapsIndexingObjectFactory.githubApiClient( - "triplea-maps", "https://api.github.com", null), - (repo, repoLastCommitDate) -> false); + mapsServerConfig.createGithubApiClient(), (repo, repoLastCommitDate) -> false); final MapIndexingResult result = mapIndexingTaskRunner diff --git a/servers/maps/server/src/test/java/org/triplea/maps/tags/MapTagAdminModuleTest.java b/servers/maps/server/src/test/java/org/triplea/maps/tags/MapTagAdminModuleTest.java index 9d6259f2c6e..e45315c047e 100644 --- a/servers/maps/server/src/test/java/org/triplea/maps/tags/MapTagAdminModuleTest.java +++ b/servers/maps/server/src/test/java/org/triplea/maps/tags/MapTagAdminModuleTest.java @@ -14,8 +14,8 @@ import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; -import org.triplea.http.client.maps.tag.admin.MapTagMetaData; -import org.triplea.http.client.maps.tag.admin.UpdateMapTagRequest; +import org.triplea.http.client.maps.admin.MapTagMetaData; +import org.triplea.http.client.maps.admin.UpdateMapTagRequest; @ExtendWith(MockitoExtension.class) class MapTagAdminModuleTest { diff --git a/spitfire-server/dropwizard-server/src/main/java/org/triplea/spitfire/server/IllegalArgumentMapper.java b/servers/server-lib/src/main/java/org/triplea/dropwizard/common/IllegalArgumentMapper.java similarity index 79% rename from spitfire-server/dropwizard-server/src/main/java/org/triplea/spitfire/server/IllegalArgumentMapper.java rename to servers/server-lib/src/main/java/org/triplea/dropwizard/common/IllegalArgumentMapper.java index b70775b296c..5766657e3b1 100644 --- a/spitfire-server/dropwizard-server/src/main/java/org/triplea/spitfire/server/IllegalArgumentMapper.java +++ b/servers/server-lib/src/main/java/org/triplea/dropwizard/common/IllegalArgumentMapper.java @@ -1,4 +1,4 @@ -package org.triplea.spitfire.server; +package org.triplea.dropwizard.common; import javax.ws.rs.core.Response; import javax.ws.rs.ext.ExceptionMapper; @@ -7,7 +7,7 @@ * This class is used to convert IllegalArgumentExceptions thrown by http endpoint controllers to * return HTTP status 400 codes. Without this, those errors would be 500s. */ -class IllegalArgumentMapper implements ExceptionMapper { +public class IllegalArgumentMapper implements ExceptionMapper { @Override public Response toResponse(final IllegalArgumentException exception) { return Response.status(Response.Status.BAD_REQUEST) diff --git a/spitfire-server/dropwizard-server/src/main/java/org/triplea/spitfire/server/HttpController.java b/servers/server-lib/src/main/java/org/triplea/spitfire/server/HttpController.java similarity index 100% rename from spitfire-server/dropwizard-server/src/main/java/org/triplea/spitfire/server/HttpController.java rename to servers/server-lib/src/main/java/org/triplea/spitfire/server/HttpController.java diff --git a/settings.gradle b/settings.gradle index e8d1e4efb12..c7dad67f727 100644 --- a/settings.gradle +++ b/settings.gradle @@ -20,6 +20,7 @@ include 'lib:websocket-server' include 'lib:xml-reader' include 'servers:game-support:client' include 'servers:game-support:server' +include 'servers:maps:client' include 'servers:maps:server' include 'servers:server-lib' include 'servers:server-test-support' @@ -27,4 +28,6 @@ include 'spitfire-server:database' include 'spitfire-server:database-test-support' include 'spitfire-server:dropwizard-server' include 'spitfire-server:latest-version-module' +include 'spitfire-server:lib:scheduled-tasks' include 'spitfire-server:lobby-module' +include 'spitfire-server:maps-module' diff --git a/spitfire-server/dropwizard-server/build.gradle b/spitfire-server/dropwizard-server/build.gradle index bde7133998c..93368e53974 100644 --- a/spitfire-server/dropwizard-server/build.gradle +++ b/spitfire-server/dropwizard-server/build.gradle @@ -57,7 +57,6 @@ dependencies { implementation project(':lib:java-extras') implementation project(':lib:websocket-client') implementation project(':lib:websocket-server') - implementation project(':servers:maps:server') implementation project(':servers:server-lib') implementation project(':spitfire-server:latest-version-module') implementation project(':spitfire-server:lobby-module') diff --git a/spitfire-server/dropwizard-server/configuration.yml b/spitfire-server/dropwizard-server/configuration.yml index 9ee5610ebbc..f6f08b64aa8 100644 --- a/spitfire-server/dropwizard-server/configuration.yml +++ b/spitfire-server/dropwizard-server/configuration.yml @@ -1,40 +1,12 @@ githubApiToken: ${GITHUB_API_TOKEN:-} githubWebServiceUrl: https://api.github.com githubGameOrg: triplea-game -githubGameRepo: triplea -githubMapsOrgName: triplea-maps latestVersionFetcherEnabled: ${LATEST_VERSION_FETCHER_ENABLED:-true} -# If map indexing is enabled, it will begin shortly after server startup. -# If disabled no map indexing will occur. -mapIndexingEnabled: ${MAP_INDEXING_ENABLED:-false} - -# How often between map indexing runs. On each map indexing run we will -# index all maps. If the previous map indexing run is still going -# we will then have multiple indexing jobs running at the same time. -# To avoid overlapping indexing jobs, this value needs to be greater than: -# (number of maps) * (processing time) * (indexingTaskDelaySeconds / 60) -mapIndexingPeriodMinutes: ${MAP_INDEXING_PERIOD_MINUTES:-300} - -# Time period in seconds between indexing each individual map. This must -# be configured to avoid github API rate limiting. -# Eg: -# 1 -> one indexing task per second -> 3600 requests per hour. -# 5 -> one indexing task every 5 seconds -> 720 requests per hour. -# 60 -> one indexing task per minute -> 60 requests per hour. -# 120 -> one indexing task every other minute -> 30 requests per hour. -# Unauthenticated Github API requests are limited to 60 request per hour. -# Authenticated Github API requests are limited to 1000 requests per hour. -indexingTaskDelaySeconds: ${MAP_INDEXING_DELAY_SECONDS:-120} - # this is to help guarantee that we do not accidentally use test configuration in prod. gameHostConnectivityCheckEnabled: ${GAME_HOST_CONNECTIVITY_CHECK_ENABLED:-false} -# When disabled, API calls to github to create error reports will not -# be made and instead a hardcoded value returned. -errorReportToGithubEnabled: ${ERROR_REPORT_TO_GITHUB_ENABLED:-false} - # Whether to print out SQL statements as executed, useful for debugging. logSqlStatements: false @@ -79,9 +51,5 @@ server: - type: http port: ${HTTP_PORT:-8080} # useForwardedHeaders is important for when behind a reverse proxy (NGINX) - # Without this 'getRemoteAddr' will return the IP of the reverse proxy server. - # By default when building locally useForwardedPorts should be 'false', but - # for all other environments that do have a NGINX server, the value should be - # set to true. - useForwardedHeaders: ${USE_FORWARDED_HEADERS:-false} + useForwardedHeaders: true adminConnectors: [] diff --git a/spitfire-server/dropwizard-server/src/main/java/org/triplea/spitfire/server/SpitfireServerApplication.java b/spitfire-server/dropwizard-server/src/main/java/org/triplea/spitfire/server/SpitfireServerApplication.java index 1c0ebd6653e..309dbed57bb 100644 --- a/spitfire-server/dropwizard-server/src/main/java/org/triplea/spitfire/server/SpitfireServerApplication.java +++ b/spitfire-server/dropwizard-server/src/main/java/org/triplea/spitfire/server/SpitfireServerApplication.java @@ -11,12 +11,11 @@ import org.jdbi.v3.core.Jdbi; import org.triplea.db.LobbyModuleRowMappers; import org.triplea.dropwizard.common.AuthenticationConfiguration; +import org.triplea.dropwizard.common.IllegalArgumentMapper; import org.triplea.dropwizard.common.JdbiLogging; import org.triplea.dropwizard.common.ServerConfiguration; import org.triplea.dropwizard.common.ServerConfiguration.WebsocketConfig; import org.triplea.http.client.web.socket.WebsocketPaths; -import org.triplea.maps.MapsModuleRowMappers; -import org.triplea.maps.indexing.MapsIndexingObjectFactory; import org.triplea.modules.chat.ChatMessagingService; import org.triplea.modules.chat.Chatters; import org.triplea.modules.game.listing.GameListing; @@ -45,8 +44,6 @@ import org.triplea.spitfire.server.controllers.user.account.LoginController; import org.triplea.spitfire.server.controllers.user.account.PlayerInfoController; import org.triplea.spitfire.server.controllers.user.account.UpdateAccountController; -import org.triplea.spitfire.server.maps.MapTagAdminController; -import org.triplea.spitfire.server.maps.MapsController; import org.triplea.web.socket.GameConnectionWebSocket; import org.triplea.web.socket.GenericWebSocket; import org.triplea.web.socket.PlayerConnectionWebSocket; @@ -93,26 +90,12 @@ public void run(final SpitfireServerConfig configuration, final Environment envi new JdbiFactory() .build(environment, configuration.getDatabase(), "postgresql-connection-pool"); - MapsModuleRowMappers.rowMappers().forEach(jdbi::registerRowMapper); LobbyModuleRowMappers.rowMappers().forEach(jdbi::registerRowMapper); if (configuration.isLogSqlStatements()) { JdbiLogging.registerSqlLogger(jdbi); } - if (configuration.isMapIndexingEnabled()) { - environment - .lifecycle() - .manage(MapsIndexingObjectFactory.buildMapsIndexingSchedule(configuration, jdbi)); - log.info( - "Map indexing is enabled to run every:" - + " {} minutes with one map indexing request every {} seconds", - configuration.getMapIndexingPeriodMinutes(), - configuration.getIndexingTaskDelaySeconds()); - } else { - log.info("Map indexing is disabled"); - } - final LatestVersionModule latestVersionModule = new LatestVersionModule(); if (configuration.isLatestVersionFetcherEnabled()) { log.info("Latest Engine Version Fetching running every 30 minutes"); @@ -178,10 +161,6 @@ public void run(final SpitfireServerConfig configuration, final Environment envi PlayersInGameController.build(gameListing), RemoteActionsController.build(jdbi, gameConnectionMessagingBus), UpdateAccountController.build(jdbi), - - // maps module controllers - MapsController.build(jdbi), - MapTagAdminController.build(jdbi), LatestVersionController.build(latestVersionModule)) .forEach(controller -> environment.jersey().register(controller)); } diff --git a/spitfire-server/dropwizard-server/src/main/java/org/triplea/spitfire/server/SpitfireServerConfig.java b/spitfire-server/dropwizard-server/src/main/java/org/triplea/spitfire/server/SpitfireServerConfig.java index b14e18ecaf4..492dc836dd7 100644 --- a/spitfire-server/dropwizard-server/src/main/java/org/triplea/spitfire/server/SpitfireServerConfig.java +++ b/spitfire-server/dropwizard-server/src/main/java/org/triplea/spitfire/server/SpitfireServerConfig.java @@ -9,7 +9,6 @@ import lombok.Getter; import lombok.Setter; import org.triplea.http.client.github.GithubApiClient; -import org.triplea.maps.MapsModuleConfig; import org.triplea.modules.LobbyModuleConfig; import org.triplea.modules.latest.version.LatestVersionModuleConfig; @@ -20,7 +19,8 @@ * YML configuration file. */ public class SpitfireServerConfig extends Configuration - implements LobbyModuleConfig, MapsModuleConfig, LatestVersionModuleConfig { + implements LobbyModuleConfig, LatestVersionModuleConfig { + /** * Flag that indicates if we are running in production. This can be used to verify we do not have * any magic stubbing and to do any additional configuration checks to be really sure production @@ -48,22 +48,6 @@ public class SpitfireServerConfig extends Configuration @Setter(onMethod_ = {@JsonProperty}) private String githubApiToken; - @Getter(onMethod_ = {@JsonProperty}) - @Setter(onMethod_ = {@JsonProperty}) - private String githubMapsOrgName; - - @Getter(onMethod_ = {@JsonProperty}) - @Setter(onMethod_ = {@JsonProperty}) - private boolean mapIndexingEnabled; - - @Getter(onMethod_ = {@JsonProperty, @Override}) - @Setter(onMethod_ = {@JsonProperty}) - private int mapIndexingPeriodMinutes; - - @Getter(onMethod_ = {@JsonProperty, @Override}) - @Setter(onMethod_ = {@JsonProperty}) - private int indexingTaskDelaySeconds; - @Getter(onMethod_ = {@JsonProperty}) @Setter(onMethod_ = {@JsonProperty}) private boolean errorReportToGithubEnabled; @@ -90,14 +74,4 @@ public GithubApiClient createGamesRepoGithubApiClient() { .repo(githubGameRepo) .build(); } - - @Override - public GithubApiClient createMapsRepoGithubApiClient() { - return GithubApiClient.builder() - .stubbingModeEnabled(!errorReportToGithubEnabled) - .authToken(githubApiToken) - .uri(URI.create(githubWebServiceUrl)) - .org(githubMapsOrgName) - .build(); - } } diff --git a/spitfire-server/dropwizard-server/src/test/java/org/triplea/spitfire/server/SpitfireDatabaseTestSupport.java b/spitfire-server/dropwizard-server/src/test/java/org/triplea/spitfire/server/SpitfireDatabaseTestSupport.java index cd770b9df6a..35909892be7 100644 --- a/spitfire-server/dropwizard-server/src/test/java/org/triplea/spitfire/server/SpitfireDatabaseTestSupport.java +++ b/spitfire-server/dropwizard-server/src/test/java/org/triplea/spitfire/server/SpitfireDatabaseTestSupport.java @@ -5,7 +5,6 @@ import java.util.List; import org.jdbi.v3.core.mapper.RowMapperFactory; import org.triplea.db.LobbyModuleRowMappers; -import org.triplea.maps.MapsModuleRowMappers; import org.triplea.spitfire.database.DatabaseTestSupport; public class SpitfireDatabaseTestSupport extends DatabaseTestSupport { @@ -13,7 +12,6 @@ public class SpitfireDatabaseTestSupport extends DatabaseTestSupport { @Override protected Collection rowMappers() { final List rowMappers = new ArrayList<>(); - rowMappers.addAll(MapsModuleRowMappers.rowMappers()); rowMappers.addAll(LobbyModuleRowMappers.rowMappers()); return rowMappers; } diff --git a/spitfire-server/dropwizard-server/src/test/java/org/triplea/spitfire/server/maps/MapTagAdminControllerTest.java b/spitfire-server/dropwizard-server/src/test/java/org/triplea/spitfire/server/maps/MapTagAdminControllerTest.java deleted file mode 100644 index 431da8568d3..00000000000 --- a/spitfire-server/dropwizard-server/src/test/java/org/triplea/spitfire/server/maps/MapTagAdminControllerTest.java +++ /dev/null @@ -1,103 +0,0 @@ -package org.triplea.spitfire.server.maps; - -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.collection.IsCollectionWithSize.hasSize; -import static org.hamcrest.collection.IsEmptyCollection.empty; -import static org.hamcrest.core.Is.is; -import static org.hamcrest.core.IsNot.not; -import static org.hamcrest.core.IsNull.notNullValue; - -import java.net.URI; -import java.util.List; -import org.junit.jupiter.api.Test; -import org.triplea.http.client.GenericServerResponse; -import org.triplea.http.client.maps.listing.MapsClient; -import org.triplea.http.client.maps.tag.admin.MapTagAdminClient; -import org.triplea.http.client.maps.tag.admin.MapTagMetaData; -import org.triplea.http.client.maps.tag.admin.UpdateMapTagRequest; -import org.triplea.spitfire.server.ControllerIntegrationTest; - -class MapTagAdminControllerTest extends ControllerIntegrationTest { - private final URI localhost; - private final MapTagAdminClient client; - - MapTagAdminControllerTest(final URI localhost) { - this.localhost = localhost; - this.client = MapTagAdminClient.newClient(localhost, ControllerIntegrationTest.MODERATOR); - } - - @Test - void requiresAuthentication() { - assertNotAuthorized( - ControllerIntegrationTest.NOT_MODERATORS, - apiKey -> MapTagAdminClient.newClient(localhost, apiKey), - MapTagAdminClient::fetchAllowedMapTagValues, - client -> - client.updateMapTag( - UpdateMapTagRequest.builder() - .tagName("tag") - .mapName("map") - .newTagValue("value") - .build())); - } - - @Test - void fetchMapTagMetaData() { - final List mapTagMetaData = client.fetchAllowedMapTagValues(); - - assertThat(mapTagMetaData, hasSize(2)); - for (final MapTagMetaData item : mapTagMetaData) { - assertThat(item.getTagName(), is(notNullValue())); - assertThat(item.getAllowedValues(), is(not(empty()))); - assertThat(item.getDisplayOrder() > 0, is(true)); - } - } - - /** - * In this test we:
- * - fetch a map listing
- * - update a tag value of the first map listing
- * - fetch map listing & verify tag value is updated
- */ - @Test - void updateMapTagValue() { - assertThat( - "Verify an initial state in database", getMapTagValue("map-name", "Rating"), is("2")); - - final GenericServerResponse serverResponse = - client.updateMapTag( - UpdateMapTagRequest.builder() - .mapName("map-name") - .tagName("Rating") - .newTagValue("1") - .build()); - assertThat( - "expecting tag to be updated successfully: " + serverResponse, - serverResponse.isSuccess(), - is(true)); - - assertThat( - "Verify tag value is now updated compared to the initial database state", - getMapTagValue("map-name", "Rating"), - is("1")); - } - - @SuppressWarnings("SameParameterValue") - private String getMapTagValue(final String mapName, final String tagName) { - // Get all maps listing - final var mapListing = MapsClient.newClient(localhost).fetchMapListing(); - - // find specific map from listing - final var map = - mapListing.stream() - .filter(m -> m.getMapName().equals(mapName)) - .findFirst() - .orElseThrow( - () -> - new IllegalStateException( - "Unable to find map: " + mapName + ", in: " + mapListing)); - - // return tag value - return map.getTagValue(tagName); - } -} diff --git a/spitfire-server/dropwizard-server/src/test/java/org/triplea/spitfire/server/maps/MapsControllerTest.java b/spitfire-server/dropwizard-server/src/test/java/org/triplea/spitfire/server/maps/MapsControllerTest.java deleted file mode 100644 index 8e9c0f2fa3d..00000000000 --- a/spitfire-server/dropwizard-server/src/test/java/org/triplea/spitfire/server/maps/MapsControllerTest.java +++ /dev/null @@ -1,48 +0,0 @@ -package org.triplea.spitfire.server.maps; - -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.collection.IsCollectionWithSize.hasSize; -import static org.hamcrest.core.Is.is; -import static org.hamcrest.core.IsNull.notNullValue; - -import java.net.URI; -import org.junit.jupiter.api.Test; -import org.triplea.http.client.maps.listing.MapsClient; -import org.triplea.spitfire.server.ControllerIntegrationTest; - -class MapsControllerTest extends ControllerIntegrationTest { - private final MapsClient client; - - MapsControllerTest(final URI localhost) { - this.client = MapsClient.newClient(localhost); - } - - /** Invoke the maps listing endpoint and verify response data is present. */ - @Test - void fetchMapDownloads() { - final var result = client.fetchMapListing(); - - assertThat(result, hasSize(2)); - for (int i = 0; i < 2; i++) { - assertThat(result.get(i).getDescription(), is(notNullValue())); - assertThat(result.get(i).getMapName(), is(notNullValue())); - assertThat(result.get(i).getDownloadUrl(), is(notNullValue())); - assertThat(result.get(i).getLastCommitDateEpochMilli(), is(notNullValue())); - assertThat(result.get(i).getPreviewImageUrl(), is(notNullValue())); - } - assertThat(result.get(0).getMapTags(), hasSize(2)); - assertThat( - "Verify tags are sorted by display order", - result.get(0).getMapTags().get(0).getDisplayOrder() - < result.get(0).getMapTags().get(1).getDisplayOrder(), - is(true)); - - assertThat(result.get(1).getMapTags(), hasSize(1)); - assertThat(result.get(1).getMapTags().get(0).getName(), is(notNullValue())); - assertThat(result.get(1).getMapTags().get(0).getValue(), is(notNullValue())); - assertThat( - "Display order should always be a non-negative value", - result.get(1).getMapTags().get(0).getDisplayOrder() >= 0, - is(true)); - } -}