From 0673bfd70e3ad91631df5c39ca85edd564da5509 Mon Sep 17 00:00:00 2001 From: Napster Date: Thu, 1 Mar 2018 18:27:13 +0100 Subject: [PATCH 01/41] Open v3 release branch --- build.gradle | 2 +- docker-compose.yml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build.gradle b/build.gradle index c08746369..03f849539 100644 --- a/build.gradle +++ b/build.gradle @@ -109,7 +109,7 @@ subprojects { } } -version = '2.3' +version = '3.0' ext { moduleName = 'FredBoat-Root' } diff --git a/docker-compose.yml b/docker-compose.yml index 59a72975a..e7f74d44c 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -43,8 +43,8 @@ services: # versions (example: v2) receive continous non-breaking (best effort) updates via watchtower. switching between versions # (example: going from v2 to v3) usually requires manual migration. what exactly is needed is published on the # FredBoat selfhosting website and/or the selfhosters channel (see top of this file for how to get to these places) - image: fredboat/fredboat:stable-v2 - #image: fredboat/fredboat:dev-v2 + image: fredboat/fredboat:stable-v3 + #image: fredboat/fredboat:dev-v3 #build: ./FredBoat #useful alternative for developers restart: on-failure:3 From 0b4603b3e2be8021a08f9d8dfd7602a8abc8b643 Mon Sep 17 00:00:00 2001 From: Napster Date: Thu, 1 Mar 2018 16:43:16 +0100 Subject: [PATCH 02/41] Java 8 -> Java 9 --- Database/build.gradle | 1 + FredBoat/Dockerfile | 2 +- FredBoat/build.gradle | 1 - FredBoat/src/main/java/fredboat/main/Launcher.java | 12 ++++++------ build.gradle | 7 +++---- 5 files changed, 11 insertions(+), 12 deletions(-) diff --git a/Database/build.gradle b/Database/build.gradle index f61294985..7c9b3b686 100644 --- a/Database/build.gradle +++ b/Database/build.gradle @@ -14,4 +14,5 @@ dependencies { compile group: 'org.hibernate', name: 'hibernate-ehcache', version: hibernateVersion compile group: 'org.flywaydb', name: 'flyway-core', version: flywayVersion compile group: 'net.ttddyy', name: 'datasource-proxy', version: dsProxyVersion + compile group: 'javax.xml.bind', name: 'jaxb-api', version: jaxbApiVersion // required by hibernate for java 9 } diff --git a/FredBoat/Dockerfile b/FredBoat/Dockerfile index 9c62a0737..9d0d9c0d7 100644 --- a/FredBoat/Dockerfile +++ b/FredBoat/Dockerfile @@ -1,4 +1,4 @@ -FROM openjdk:8-jdk-slim +FROM openjdk:9-jdk-slim ENV ENV docker diff --git a/FredBoat/build.gradle b/FredBoat/build.gradle index 5d046be59..1951cf122 100644 --- a/FredBoat/build.gradle +++ b/FredBoat/build.gradle @@ -1,5 +1,4 @@ apply plugin: 'com.gorylenko.gradle-git-properties' -apply plugin: 'com.sedmelluq.jdaction' apply plugin: 'application' apply plugin: 'org.junit.platform.gradle.plugin' apply plugin: 'propdeps' diff --git a/FredBoat/src/main/java/fredboat/main/Launcher.java b/FredBoat/src/main/java/fredboat/main/Launcher.java index 8f34d8221..9af0ea183 100644 --- a/FredBoat/src/main/java/fredboat/main/Launcher.java +++ b/FredBoat/src/main/java/fredboat/main/Launcher.java @@ -46,7 +46,6 @@ import space.npstr.sqlsauce.DatabaseException; import java.io.IOException; -import java.util.Objects; import java.util.concurrent.ExecutorService; /** @@ -113,19 +112,20 @@ public static void main(String[] args) throws IllegalArgumentException, Database SentryDsnCommand.turnOff(); } - String javaVersionMinor = null; + int javaVersionMajor = -1; + try { - javaVersionMinor = System.getProperty("java.version").split("\\.")[1]; + javaVersionMajor = Runtime.version().major(); } catch (Exception e) { - log.error("Exception while checking if java 8", e); + log.error("Exception while checking if java 9", e); } - if (!Objects.equals(javaVersionMinor, "8")) { + if (javaVersionMajor != 9) { log.warn("\n\t\t __ ___ ___ _ _ ___ _ _ ___ \n" + "\t\t \\ \\ / /_\\ | _ \\ \\| |_ _| \\| |/ __|\n" + "\t\t \\ \\/\\/ / _ \\| / .` || || .` | (_ |\n" + "\t\t \\_/\\_/_/ \\_\\_|_\\_|\\_|___|_|\\_|\\___|\n" + "\t\t "); - log.warn("FredBoat only officially supports Java 8. You are running Java {}", System.getProperty("java.version")); + log.warn("FredBoat only officially supports Java 9. You are running Java {}", Runtime.version()); } System.setProperty("spring.main.web-application-type", "none"); //todo enable again after spark API is migrated diff --git a/build.gradle b/build.gradle index 03f849539..f2f633e39 100644 --- a/build.gradle +++ b/build.gradle @@ -20,7 +20,6 @@ subprojects { //plugin versions gradleGitVersion = '1.4.17' //do not upgrade to 1.4.20, it fails builds randomly - jdactionVersion = '1.0.2' shadowVersion = '2.0.2' springBootVersion = '2.0.0.RC1' jUnitPluginVersion = '1.0.2' @@ -37,7 +36,6 @@ subprojects { } dependencies { classpath "gradle.plugin.com.gorylenko.gradle-git-properties:gradle-git-properties:${gradleGitVersion}" - classpath "gradle.plugin.com.sedmelluq:jdaction:${jdactionVersion}" classpath "com.github.jengelman.gradle.plugins:shadow:${shadowVersion}" classpath "org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}" classpath "org.junit.platform:junit-platform-gradle-plugin:${jUnitPluginVersion}" @@ -46,8 +44,8 @@ subprojects { } apply plugin: 'java' - sourceCompatibility = 1.8 - targetCompatibility = 1.8 + sourceCompatibility = 9 + targetCompatibility = 9 compileJava.dependsOn 'clean' compileJava.options.encoding = 'UTF-8' @@ -99,6 +97,7 @@ subprojects { hibernateVersion = '5.2.13.Final' flywayVersion = '5.0.7' dsProxyVersion = '1.4.6' + jaxbApiVersion = '2.3.0' //testing deps junitVersion = '5.0.3' From e20fd9eeef19508f671dfdba2dea888c0a846786 Mon Sep 17 00:00:00 2001 From: Napster Date: Sat, 3 Mar 2018 03:35:47 +0100 Subject: [PATCH 03/41] Merge config.yaml and credentials.yaml to fredboat.yaml --- .gitignore | 4 + CONTRIBUTING.md | 2 +- FredBoat/.dockerignore | 3 +- FredBoat/Dockerfile | 3 +- FredBoat/config.yaml | 20 ----- ...als.yaml.example => fredboat.yaml.example} | 25 +++++- .../fredboat/config/property/Credentials.java | 4 +- .../fredboat/config/property/FileConfig.java | 90 +++++++++---------- .../src/main/java/fredboat/main/Launcher.java | 1 + .../test/java/fredboat/test/MockConfig.java | 2 +- docker-compose.yml | 3 +- 11 files changed, 77 insertions(+), 80 deletions(-) delete mode 100644 FredBoat/config.yaml rename FredBoat/{credentials.yaml.example => fredboat.yaml.example} (81%) diff --git a/.gitignore b/.gitignore index a80f6e9ed..e975c7b45 100644 --- a/.gitignore +++ b/.gitignore @@ -141,3 +141,7 @@ gc-*.log .gradle/* */out/* VERSION.txt +fredboat.yaml +fredboat.yml +application.yaml +application.yml diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 31a8c10a0..62e26ba90 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -115,7 +115,7 @@ Obtaining a well functioning and productive setup of the IDE may be an intimidat ### Running the bot -Add `credentials.yaml` and `config.yaml` files to the FredBoat root directory. +Add the `fredboat.yaml` file to the FredBoat root directory (symlinking recommended). To run the FredBoat bot in IntelliJ IDEA, find the little green play button in the main class `FredBoat.java` and start it from there:
Click me diff --git a/FredBoat/.dockerignore b/FredBoat/.dockerignore index fc46b7361..ba869c99e 100644 --- a/FredBoat/.dockerignore +++ b/FredBoat/.dockerignore @@ -2,5 +2,4 @@ #ignore everything except the following files, they are used in the Dockerfile to build the fredboat image !Dockerfile !FredBoat.jar -!config.yaml -!credentials.yaml.example +!fredboat.yaml.example diff --git a/FredBoat/Dockerfile b/FredBoat/Dockerfile index 9d0d9c0d7..487d45919 100644 --- a/FredBoat/Dockerfile +++ b/FredBoat/Dockerfile @@ -4,8 +4,7 @@ ENV ENV docker RUN mkdir -p /opt/FredBoat -COPY config.yaml /opt/FredBoat/config.yaml -COPY credentials.yaml.example /opt/FredBoat/credentials.yaml +COPY fredboat.yaml.example /opt/FredBoat/fredboat.yaml COPY FredBoat.jar /opt/FredBoat/FredBoat.jar EXPOSE 1356 diff --git a/FredBoat/config.yaml b/FredBoat/config.yaml deleted file mode 100644 index 0482a46f7..000000000 --- a/FredBoat/config.yaml +++ /dev/null @@ -1,20 +0,0 @@ ---- -development: true # Set this to false for selfhosting. If you leave this enabled and complain about weird - # things happening to your bot in the selfhosting chat you will be publicly taunted. - -prefix: '<<' # Default prefix used by the bot -restServerEnabled: true # Set this to false if you are running multiple FredBoat bots on the same machine -admins: [] # Add comma separated userIds and roleIds that should have access to bot admin commands. Find role ids with the ;;roleinfo command -useAutoBlacklist: true # Set to true to automatically blacklist users who frequently hit the rate limits -game: "" # Set the displayed game/status. Leave empty quote marks for the default status -continuePlayback: false # Set to true to force the player to continue playback even if left alone - -enableYouTube: true # Set to true to enable playing YouTube links -enableSoundCloud: true # Set to true to enable playing SoundCloud links -enableBandCamp: true # Set to true to enable playing BandCamp links -enableTwitch: true # Set to true to enable playing Twitch links -enableVimeo: true # Set to true to enable playing Vimeo links -enableMixer: true # Set to true to enable playing Mixer links -enableSpotify: true # Set to true to enable playing Spotify links -enableLocal: false # Set to true to enable playing local files -enableHttp: false # Set to true to enable playing direct links diff --git a/FredBoat/credentials.yaml.example b/FredBoat/fredboat.yaml.example similarity index 81% rename from FredBoat/credentials.yaml.example rename to FredBoat/fredboat.yaml.example index d5d7a6670..e991188f3 100644 --- a/FredBoat/credentials.yaml.example +++ b/FredBoat/fredboat.yaml.example @@ -1,5 +1,4 @@ --- - ################################################################ ### *** WARNING *** ################################################################ @@ -25,6 +24,30 @@ ### More information on correctly formatting yaml files: http://www.yaml.org/start.html +################################################################ +### Basic configuration +################################################################ + +development: true # Set this to false for selfhosting. If you leave this enabled and complain about weird + # things happening to your bot in the selfhosting chat you will be publicly taunted. + +prefix: '<<' # Default prefix used by the bot +restServerEnabled: true # Set this to false if you are running multiple FredBoat bots on the same machine +admins: [] # Add comma separated userIds and roleIds that should have access to bot admin commands. Find role ids with the ;;roleinfo command +useAutoBlacklist: true # Set to true to automatically blacklist users who frequently hit the rate limits +game: "" # Set the displayed game/status. Leave empty quote marks for the default status +continuePlayback: false # Set to true to force the player to continue playback even if left alone + +enableYouTube: true # Set to true to enable playing YouTube links +enableSoundCloud: true # Set to true to enable playing SoundCloud links +enableBandCamp: true # Set to true to enable playing BandCamp links +enableTwitch: true # Set to true to enable playing Twitch links +enableVimeo: true # Set to true to enable playing Vimeo links +enableMixer: true # Set to true to enable playing Mixer links +enableSpotify: true # Set to true to enable playing Spotify links +enableLocal: false # Set to true to enable playing local files +enableHttp: false # Set to true to enable playing direct links + ################################################################ ### Essential credentials diff --git a/FredBoat/src/main/java/fredboat/config/property/Credentials.java b/FredBoat/src/main/java/fredboat/config/property/Credentials.java index 881430412..40c0fddd8 100644 --- a/FredBoat/src/main/java/fredboat/config/property/Credentials.java +++ b/FredBoat/src/main/java/fredboat/config/property/Credentials.java @@ -33,7 +33,7 @@ /** * Created by napster on 19.02.18. *

- * All of these are documented in depth in the credentials.yaml.example file (to help selfhosters) + * All of these are documented in depth in the fredboat.yaml.example file (to help selfhosters) */ public interface Credentials { @@ -53,7 +53,7 @@ public interface Credentials { default String getRandomGoogleKey() { List googleKeys = getGoogleKeys(); if (googleKeys.isEmpty()) { - throw new MessagingException("No Youtube API key detected. Please read the documentation of the credentials file on how to obtain one."); + throw new MessagingException("No Youtube API key detected. Please read the documentation of the fredboat.yaml file on how to obtain one."); } return googleKeys.get((int) Math.floor(Math.random() * getGoogleKeys().size())); } diff --git a/FredBoat/src/main/java/fredboat/config/property/FileConfig.java b/FredBoat/src/main/java/fredboat/config/property/FileConfig.java index 2207fc461..2513a0205 100644 --- a/FredBoat/src/main/java/fredboat/config/property/FileConfig.java +++ b/FredBoat/src/main/java/fredboat/config/property/FileConfig.java @@ -72,10 +72,7 @@ private static FileConfig loadConfig() { long nanoTime = System.nanoTime(); FileConfig c; try { - c = new FileConfig( - loadConfigFile("credentials"), - loadConfigFile("config") - ); + c = new FileConfig(loadConfigFile("fredboat")); } catch (Exception e) { if (lastSuccessfulLoaded != null) { log.error("Reloading config file failed! Serving last successfully loaded one.", e); @@ -154,20 +151,16 @@ private static FileConfig loadConfig() { * The config is regularly reloaded, it should not be doing any blocking calls. */ @SuppressWarnings("unchecked") - private FileConfig(File credentialsFile, File configFile) { + private FileConfig(File configFile) { try { Yaml yaml = new Yaml(); - String credsFileStr = FileUtils.readFileToString(credentialsFile, "UTF-8"); String configFileStr = FileUtils.readFileToString(configFile, "UTF-8"); //remove those pesky tab characters so a potential json file is YAML conform - credsFileStr = cleanTabs(credsFileStr, "credentials.yaml"); - configFileStr = cleanTabs(configFileStr, "config.yaml"); + configFileStr = cleanTabs(configFileStr, "fredboat.yaml"); - Map creds = yaml.load(credsFileStr); Map config = yaml.load(configFileStr); //avoid null values, rather change them to empty strings - creds.keySet().forEach((String key) -> creds.putIfAbsent(key, "")); config.keySet().forEach((String key) -> config.putIfAbsent(key, "")); @@ -210,7 +203,7 @@ private FileConfig(File credentialsFile, File configFile) { //Load Credential values - Object token = creds.get("token"); + Object token = config.get("token"); if (token instanceof String) { botToken = (String) token; } else { @@ -219,10 +212,10 @@ private FileConfig(File credentialsFile, File configFile) { } if (botToken == null || botToken.isEmpty()) { throw new RuntimeException("No discord bot token provided for the started distribution " + distribution - + "\nMake sure to put a " + distribution.getId() + " token in your credentials file."); + + "\nMake sure to put a " + distribution.getId() + " token in your fredboat.yaml file."); } - Object gkeys = creds.get("googleServerKeys"); + Object gkeys = config.get("googleServerKeys"); if (gkeys instanceof List) { ((List) gkeys).forEach((Object str) -> googleKeys.add((String) str)); } else if (gkeys instanceof String) { @@ -232,20 +225,20 @@ private FileConfig(File credentialsFile, File configFile) { } // apis - malUser = (String) creds.getOrDefault("malUser", ""); - malPassword = (String) creds.getOrDefault("malPassword", ""); + malUser = (String) config.getOrDefault("malUser", ""); + malPassword = (String) config.getOrDefault("malPassword", ""); - imgurClientId = (String) creds.getOrDefault("imgurClientId", ""); + imgurClientId = (String) config.getOrDefault("imgurClientId", ""); - spotifyId = (String) creds.getOrDefault("spotifyId", ""); - spotifySecret = (String) creds.getOrDefault("spotifySecret", ""); + spotifyId = (String) config.getOrDefault("spotifyId", ""); + spotifySecret = (String) config.getOrDefault("spotifySecret", ""); - openWeatherKey = (String) creds.getOrDefault("openWeatherKey", ""); - sentryDsn = (String) creds.getOrDefault("sentryDsn", ""); + openWeatherKey = (String) config.getOrDefault("openWeatherKey", ""); + sentryDsn = (String) config.getOrDefault("sentryDsn", ""); // main database - jdbcUrl = (String) creds.getOrDefault("jdbcUrl", ""); + jdbcUrl = (String) config.getOrDefault("jdbcUrl", ""); if (jdbcUrl == null || jdbcUrl.isEmpty()) { if ("docker".equals(System.getenv("ENV"))) { log.info("No main JDBC URL found, docker environment detected. Using default docker main JDBC url"); @@ -256,10 +249,10 @@ private FileConfig(File credentialsFile, File configFile) { throw new RuntimeException(message); } } - boolean useSshTunnel = (boolean) creds.getOrDefault("useSshTunnel", false); + boolean useSshTunnel = (boolean) config.getOrDefault("useSshTunnel", false); if (useSshTunnel) { //Parse host:port - String sshHostRaw = (String) creds.getOrDefault("sshHost", "localhost:22"); + String sshHostRaw = (String) config.getOrDefault("sshHost", "localhost:22"); String sshHost = sshHostRaw.split(":")[0]; int sshPort; try { @@ -267,15 +260,15 @@ private FileConfig(File credentialsFile, File configFile) { } catch (Exception e) { sshPort = 22; } - String sshUser = (String) creds.getOrDefault("sshUser", "fredboat"); - String sshPrivateKeyFile = (String) creds.getOrDefault("sshPrivateKeyFile", "database.ppk"); - String sshKeyPassphrase = (String) creds.getOrDefault("sshKeyPassphrase", ""); - int tunnelLocalPort = (int) creds.getOrDefault("tunnelLocalPort", 9333);//9333 is a legacy port for backwards compatibility + String sshUser = (String) config.getOrDefault("sshUser", "fredboat"); + String sshPrivateKeyFile = (String) config.getOrDefault("sshPrivateKeyFile", "database.ppk"); + String sshKeyPassphrase = (String) config.getOrDefault("sshKeyPassphrase", ""); + int tunnelLocalPort = (int) config.getOrDefault("tunnelLocalPort", 9333);//9333 is a legacy port for backwards compatibility String tunnelRemotePortKey = "tunnelRemotePort"; - if (creds.containsKey("forwardToPort")) {//legacy check + if (config.containsKey("forwardToPort")) {//legacy check tunnelRemotePortKey = "forwardToPort"; } - int tunnelRemotePort = (int) creds.getOrDefault(tunnelRemotePortKey, 5432); + int tunnelRemotePort = (int) config.getOrDefault(tunnelRemotePortKey, 5432); mainSshTunnelConfig = new SshTunnel.SshDetails(sshHost, sshUser) .setKeyFile(sshPrivateKeyFile) @@ -287,7 +280,7 @@ private FileConfig(File credentialsFile, File configFile) { // cache database - cacheJdbcUrl = (String) creds.getOrDefault("cacheJdbcUrl", ""); + cacheJdbcUrl = (String) config.getOrDefault("cacheJdbcUrl", ""); if (cacheJdbcUrl == null || cacheJdbcUrl.isEmpty()) { if ("docker".equals(System.getenv("ENV"))) { log.info("No cache jdbcUrl found, docker environment detected. Using default docker cache JDBC url"); @@ -300,15 +293,14 @@ private FileConfig(File credentialsFile, File configFile) { } if (jdbcUrl.equals(cacheJdbcUrl)) { log.warn("The main and cache jdbc urls may not point to the same database due to how flyway handles migrations. " - + "Please read (an updated version of) the credentials.yaml.example on configuring the cache jdbc url. " + "The cache database will not be available in this execution of FredBoat. This may lead to a degraded performance, " + "especially in a high usage environment, or when using Spotify playlists."); cacheJdbcUrl = null; } - boolean cacheUseSshTunnel = (boolean) creds.getOrDefault("cacheUseSshTunnel", false); + boolean cacheUseSshTunnel = (boolean) config.getOrDefault("cacheUseSshTunnel", false); if (cacheUseSshTunnel) { //Parse host:port - String cacheSshHostRaw = (String) creds.getOrDefault("cacheSshHost", "localhost:22"); + String cacheSshHostRaw = (String) config.getOrDefault("cacheSshHost", "localhost:22"); String cacheSshHost = cacheSshHostRaw.split(":")[0]; int cacheSshPort; try { @@ -316,11 +308,11 @@ private FileConfig(File credentialsFile, File configFile) { } catch (Exception e) { cacheSshPort = 22; } - String cacheSshUser = (String) creds.getOrDefault("cacheSshUser", "fredboat"); - String cacheSshPrivateKeyFile = (String) creds.getOrDefault("cacheSshPrivateKeyFile", "database.ppk"); - String cacheSshKeyPassphrase = (String) creds.getOrDefault("cacheSshKeyPassphrase", ""); - int cacheTunnelLocalPort = (int) creds.getOrDefault("cacheTunnelLocalPort", 5433); - int cacheTunnelRemotePort = (int) creds.getOrDefault("cacheTunnelRemotePort", 5432); + String cacheSshUser = (String) config.getOrDefault("cacheSshUser", "fredboat"); + String cacheSshPrivateKeyFile = (String) config.getOrDefault("cacheSshPrivateKeyFile", "database.ppk"); + String cacheSshKeyPassphrase = (String) config.getOrDefault("cacheSshKeyPassphrase", ""); + int cacheTunnelLocalPort = (int) config.getOrDefault("cacheTunnelLocalPort", 5433); + int cacheTunnelRemotePort = (int) config.getOrDefault("cacheTunnelRemotePort", 5432); cacheSshTunnelConfig = new SshTunnel.SshDetails(cacheSshHost, cacheSshUser) .setKeyFile(cacheSshPrivateKeyFile) @@ -331,7 +323,7 @@ private FileConfig(File credentialsFile, File configFile) { } // misc - Object linkNodes = creds.get("lavalinkHosts"); + Object linkNodes = config.get("lavalinkHosts"); if (linkNodes != null) { if (linkNodes instanceof Map) { Map simpleNodes = (Map) linkNodes; @@ -360,27 +352,27 @@ private FileConfig(File credentialsFile, File configFile) { } } - eventLogWebhook = (String) creds.getOrDefault("eventLogWebhook", ""); - eventLogInterval = (int) creds.getOrDefault("eventLogInterval", 1); //minutes - guildStatsWebhook = (String) creds.getOrDefault("guildStatsWebhook", ""); - guildStatsInterval = (int) creds.getOrDefault("guildStatsInterval", 60); //minutes + eventLogWebhook = (String) config.getOrDefault("eventLogWebhook", ""); + eventLogInterval = (int) config.getOrDefault("eventLogInterval", 1); //minutes + guildStatsWebhook = (String) config.getOrDefault("guildStatsWebhook", ""); + guildStatsInterval = (int) config.getOrDefault("guildStatsInterval", 60); //minutes // Undocumented creds - carbonKey = (String) creds.getOrDefault("carbonKey", ""); - dikeUrl = (String) creds.getOrDefault("dikeUrl", ""); + carbonKey = (String) config.getOrDefault("carbonKey", ""); + dikeUrl = (String) config.getOrDefault("dikeUrl", ""); PlayerLimitManager.setLimit((Integer) config.getOrDefault("playerLimit", -1)); } catch (IOException e) { - log.error("Failed to read config and or credentials files into strings.", e); - throw new RuntimeException("Failed to read config and or credentials files into strings.", e); + log.error("Failed to read one or more yaml files into strings", e); + throw new RuntimeException("Failed to read one or more yaml files into strings.", e); } catch (YAMLException | ClassCastException e) { - log.error("Could not parse the credentials and/or config yaml files! They are probably misformatted. " + + log.error("Could not parse one or more yaml files! They are probably misformatted. " + "Try using an online yaml validator.", e); throw e; } catch (Exception e) { - log.error("Could not init config", e); + log.error("Could not init file config", e); throw e; } } diff --git a/FredBoat/src/main/java/fredboat/main/Launcher.java b/FredBoat/src/main/java/fredboat/main/Launcher.java index 9af0ea183..74be51106 100644 --- a/FredBoat/src/main/java/fredboat/main/Launcher.java +++ b/FredBoat/src/main/java/fredboat/main/Launcher.java @@ -128,6 +128,7 @@ public static void main(String[] args) throws IllegalArgumentException, Database log.warn("FredBoat only officially supports Java 9. You are running Java {}", Runtime.version()); } + System.setProperty("spring.config.name", "fredboat"); System.setProperty("spring.main.web-application-type", "none"); //todo enable again after spark API is migrated SpringApplication.run(Launcher.class, args); } diff --git a/FredBoat/src/test/java/fredboat/test/MockConfig.java b/FredBoat/src/test/java/fredboat/test/MockConfig.java index 556da174e..ed6b67223 100644 --- a/FredBoat/src/test/java/fredboat/test/MockConfig.java +++ b/FredBoat/src/test/java/fredboat/test/MockConfig.java @@ -56,7 +56,7 @@ public class MockConfig implements AppConfig, AudioSourcesConfig, Credentials, D public MockConfig() { try { Yaml yaml = new Yaml(); - String credsFileStr = FileUtils.readFileToString(new File("credentials.yaml"), "UTF-8"); + String credsFileStr = FileUtils.readFileToString(new File("fredboat.yaml"), "UTF-8"); Map creds = yaml.load(credsFileStr); creds.keySet().forEach((String key) -> creds.putIfAbsent(key, "")); diff --git a/docker-compose.yml b/docker-compose.yml index e7f74d44c..05e67fe69 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -55,8 +55,7 @@ services: ports: - 1356:1356 volumes: - - ./config.yaml:/opt/FredBoat/config.yaml - - ./credentials.yaml:/opt/FredBoat/credentials.yaml + - ./fredboat.yaml:/opt/FredBoat/fredboat.yaml - ./logs:/opt/FredBoat/logs - ./music_persistence:/opt/FredBoat/music_persistence # Local audio files (dev branch only currently) From 140aed8d3ffc318f974c6032ed67d48b794b7e63 Mon Sep 17 00:00:00 2001 From: Napster Date: Sat, 3 Mar 2018 21:47:52 +0100 Subject: [PATCH 04/41] Rework config to be read via spring --- .../java/fredboat/db/DatabaseManager.java | 2 +- FredBoat/fredboat.example.yaml | 186 ++++++ FredBoat/fredboat.yaml.example | 186 ------ FredBoat/src/main/java/fredboat/api/API.java | 12 +- .../audio/player/AudioConnectionFacade.java | 8 +- .../fredboat/config/ConfigConfiguration.java | 78 --- .../config/DatabaseConfiguration.java | 4 +- .../config/ShardManagerConfiguration.java | 6 +- .../fredboat/config/property/AppConfig.java | 15 +- .../config/property/AppConfigProperties.java | 120 ++++ .../AudioSourcesConfigProperties.java | 128 ++++ ...der.java => ConfigPropertiesProvider.java} | 2 +- .../property/CredentialsProperties.java | 151 +++++ .../property/DatabaseConfigProperties.java | 165 +++++ .../property/EventLoggerConfigProperties.java | 78 +++ .../fredboat/config/property/FileConfig.java | 608 ------------------ .../config/property/LavalinkConfig.java | 31 +- ...der.java => LavalinkConfigProperties.java} | 42 +- .../SpringConfigPropertiesProvider.java | 82 +++ .../src/main/java/fredboat/db/EntityIO.java | 6 +- .../main/java/fredboat/event/EventLogger.java | 12 +- .../java/fredboat/main/BotController.java | 6 +- .../src/main/java/fredboat/main/Launcher.java | 80 ++- .../main/java/fredboat/perms/PermsUtil.java | 4 +- .../fredboat/util/ratelimit/Ratelimiter.java | 4 +- .../test/java/fredboat/test/MockConfig.java | 4 +- 26 files changed, 1056 insertions(+), 964 deletions(-) create mode 100644 FredBoat/fredboat.example.yaml delete mode 100644 FredBoat/fredboat.yaml.example delete mode 100644 FredBoat/src/main/java/fredboat/config/ConfigConfiguration.java create mode 100644 FredBoat/src/main/java/fredboat/config/property/AppConfigProperties.java create mode 100644 FredBoat/src/main/java/fredboat/config/property/AudioSourcesConfigProperties.java rename FredBoat/src/main/java/fredboat/config/property/{PropertyConfigProvider.java => ConfigPropertiesProvider.java} (97%) create mode 100644 FredBoat/src/main/java/fredboat/config/property/CredentialsProperties.java create mode 100644 FredBoat/src/main/java/fredboat/config/property/DatabaseConfigProperties.java create mode 100644 FredBoat/src/main/java/fredboat/config/property/EventLoggerConfigProperties.java delete mode 100644 FredBoat/src/main/java/fredboat/config/property/FileConfig.java rename FredBoat/src/main/java/fredboat/config/property/{FilePropertyConfigProvider.java => LavalinkConfigProperties.java} (61%) create mode 100644 FredBoat/src/main/java/fredboat/config/property/SpringConfigPropertiesProvider.java diff --git a/Database/src/main/java/fredboat/db/DatabaseManager.java b/Database/src/main/java/fredboat/db/DatabaseManager.java index 23c5b2780..279a87349 100644 --- a/Database/src/main/java/fredboat/db/DatabaseManager.java +++ b/Database/src/main/java/fredboat/db/DatabaseManager.java @@ -138,7 +138,7 @@ public DatabaseWrapper getMainDbWrapper() { @Nullable //may return null if no cache db is configured public DatabaseConnection getCacheDbConn() { - if (cacheJdbc == null) { + if (cacheJdbc == null || cacheJdbc.isEmpty()) { return null; } DatabaseConnection singleton = cacheDbConn; diff --git a/FredBoat/fredboat.example.yaml b/FredBoat/fredboat.example.yaml new file mode 100644 index 000000000..74c2d07f4 --- /dev/null +++ b/FredBoat/fredboat.example.yaml @@ -0,0 +1,186 @@ +--- +################################################################ +### *** WARNING *** +################################################################ +### +### ALMOST EVERYTHING REQUESTED IN THIS FILE ARE CONFIDENTIAL CREDENTIALS +### IF YOU POST THIS FILE ONLINE (such as on GitHub) YOUR BOT COULD BE COMPROMISED +### +### +### Use a proper text editor when editing this file, for example Sublime. +### Do not use tab characters in this file, use plain spaces. +### +### Keep at least one space after a colon, like so: +### +### key: value +### +### You can wrap most values into quotation marks, except numbers and booleans: +### +### someUrl: "http://example.com" +### someToken: "123.qwe.456[DFG=" +### somePortNumber: 22 +### useSomeFeature: true +### +### More information on correctly formatting yaml files: http://www.yaml.org/start.html + + +################################################################ +### Basic configuration +################################################################ + +config: + development: true # Set this to false for selfhosting. If you leave this enabled and complain about weird + # things happening to your bot in the selfhosting chat you will be publicly taunted. + prefix: '<<' # Default prefix used by the bot + restServerEnabled: false # Set this to true to enable FredBoats legacy API. Might cause issues when running several bots together + botAdmins: [] # Add comma separated userIds and roleIds that should have access to bot admin commands. Find role ids with the ;;roleinfo command + autoBlacklist: true # Set to true to automatically blacklist users who frequently hit the rate limits + game: "" # Set the displayed game/status. Leave empty quote marks for the default status + continuePlayback: false # Set to true to force the player to continue playback even if left alone + +server: + port: 1356 # Change the port of the API FredBoat exposes +spring: + main: + web-application-type: reactive # Do not touch for now. This will enable / disable a possible future FredBoat API + + +audio-sources: + enableYouTube: true # Set to true to enable playing YouTube links + enableSoundCloud: true # Set to true to enable playing SoundCloud links + enableBandCamp: true # Set to true to enable playing BandCamp links + enableTwitch: true # Set to true to enable playing Twitch links + enableVimeo: true # Set to true to enable playing Vimeo links + enableMixer: true # Set to true to enable playing Mixer links + enableSpotify: true # Set to true to enable playing Spotify links + enableLocal: false # Set to true to enable playing local files + enableHttp: false # Set to true to enable playing direct links + + +################################################################ +### Essential credentials +################################################################ +credentials: + # Add your discord bot token below, between the quotation marks + # Find the token of your bot on https://discordapp.com/developers/applications/me + # Tutorial: https://github.com/reactiflux/discord-irc/wiki/Creating-a-discord-bot-&-getting-a-token + discordBotToken: "PutYourDiscordBotTokenHere" + + + # Used by the ;;split and ;;np commands. Must be hooked up to the Youtube Data API. + # You can add additional keys in case you are running a big bot + # How to get the key: https://developers.google.com/youtube/registering_an_application + # Add your google API key between the quotation marks + googleApiKeys: + - "PutYourGoogleAPIKeyHere" + + + +################################################################ +### Optional APIs +################################################################ + + # For the ;;mal command + # Create an account on https://myanimelist.net/ and enter its login below + malUser: "" + malPassword: "" + + + # Used to access imgur galleries for some RandomImageCommands + # Acquired from here: https://api.imgur.com/oauth2/addclient + # Choose an option that does not require an Authorization callback URL + imgurClientId: "" + + + # Used to retrieve Spotify playlists + # Get them from here: https://developer.spotify.com/my-applications + spotifyId: "" + spotifySecret: "" + + + # Used by ;;weather command. + # Get them from: http://openweathermap.org/appid + openWeatherKey: "" + + # Error aggregation service https://sentry.io/ + sentryDsn: "" + + + +event-logger: + # Webhooks to Discord channels that will post some guild stats and shard status changes + # More information on webhooks: https://support.discordapp.com/hc/en-us/articles/228383668-Intro-to-Webhooks + # Example: "https://canary.discordapp.com/api/webhooks/1234567890/QWERTZUIOPasdfghjklYXCVBNM" (no, this one will not work) + eventLogWebhook: "" # webhook url for connect / disconnect events + eventLogInterval: 1 # interval at which connect / disconnect events are posted in minutes + guildStatsWebhook: "" # webhook url for guild stats + guildStatsInterval: 60 # interval at which guild stats are posted in minutes + + + +################################################################ +### Developers and very experienced users only +################################################################ + +database: + main: + # FredBoat was written to work with PostgreSQL. + # If you are running with docker-compose then you don't need to change the jdbcUrl here. + # In PostgreSQL, role means user and vice versa. Keep that in mind when reading the following help and the provided links. + # If you are running your own PostgreSQL database, you will need to provide a role and a database belonging to that role. + # The role needs at least the permission to log in. + # All postgres databases used by FredBoat are required to have the Hstore extension enabled. + # Learn more about roles here: https://www.postgresql.org/docs/10/static/database-roles.html + # Learn more about creating databases here: https://www.postgresql.org/docs/10/static/manage-ag-createdb.html + # Learn more about the postgres jdbc url here: https://jdbc.postgresql.org/documentation/head/connect.html + # Learn more about creating extensions here: https://www.postgresql.org/docs/current/static/sql-createextension.html + # If you are using an SSH tunnel, you need to point your jdbc url to localhost and the configured tunnelLocalPort + # Example jdbc: "jdbc:postgresql://localhost:5432/fredboat?user=fredboat&password=youshallnotpass" + jdbcUrl: "" + + # Ssh tunnel for a remote database. this is useful for when you don't want to expose your database on the remote server + # and instead use ssh tunneling to access it + # If you are running with docker-compose then you don't need to change any ssh value here. + # If you are using an SSH tunnel, you need to point your jdbc url to localhost and the configured tunnelLocalPort + # Keep the sshHost an empty string for no tunnel. + tunnel: + host: "" # add the ssh port to the ip / url, usually 22, for example: "db.example.com:22" + user: "" # user on the remote machine + privateKeyFile: "" # path to an ssh private key file which is authorized to log in to the sshUser on the remote machine. learn how to create these: https://www.digitalocean.com/community/tutorials/initial-server-setup-with-ubuntu-16-04#step-four-—-add-public-key-authentication-(recommended) + keyPass: "" # optional passphrase for the ssh key file + localPort: 5432 # endpoint port of the tunnel on the machine running fredboat; makes sure these dont collide; this one needs to be used in the jdbc url + remotePort: 5432 # port of the PostgreSQL on the remote machine, 5432 by default + + cache: + # Database for caching things, see config of main database above for details about the individual values. + # If you are running with docker-compose then you don't need to change the cache jdbcUrl here. + # The main and cache databases can be two databases inside a single postgres instance. + # They CANNOT be the same database due to the way flyway migrations work. + # The main benefit is that you don't have to backup/migrate the cache database, it can just be dropped/recreated + # If you do not provide a jdbc url for the cache database, FredBoat will still work (most likely), but may have a degraded + # performance, especially in high usage environments and when using Spotify playlists. + # If you are going to use two different ssh tunnels for both database connections, make sure that the local tunnel ports don't collide + jdbcUrl: "" + tunnel: + host: "" + user: "" + privateKeyFile: "" + keyPass: "" + localPort: 5433 + remotePort: 5432 + + +# If you are running lavalink nodes this is the place to add them. +# Examples shown below, don't forget to uncomment them properly. +# More on Lavalink: https://github.com/Frederikam/Lavalink +#lavalink: +# nodes: +# - name : "local" +# host : "ws://localhost:5555" +# pass : "youshallnotpass" +# - name : "remote1" +# host : "ws://192.168.1.20:5556" +# pass : "youshallnotpass" +# - name : "remote2" +# host : "ws://lavalink.example.com:5557" +# pass : "youshallnotpass" diff --git a/FredBoat/fredboat.yaml.example b/FredBoat/fredboat.yaml.example deleted file mode 100644 index e991188f3..000000000 --- a/FredBoat/fredboat.yaml.example +++ /dev/null @@ -1,186 +0,0 @@ ---- -################################################################ -### *** WARNING *** -################################################################ -### -### ALMOST EVERYTHING REQUESTED IN THIS FILE ARE CONFIDENTIAL CREDENTIALS -### IF YOU POST THIS FILE ONLINE (such as on GitHub) YOUR BOT COULD BE COMPROMISED -### -### -### Use a proper text editor when editing this file, for example Sublime. -### Do not use tab characters in this file, use plain spaces. -### -### Keep at least one space after a colon, like so: -### -### key: value -### -### You can wrap most values into quotation marks, except numbers and booleans: -### -### someUrl: "http://example.com" -### someToken: "123.qwe.456[DFG=" -### somePortNumber: 22 -### useSomeFeature: true -### -### More information on correctly formatting yaml files: http://www.yaml.org/start.html - - -################################################################ -### Basic configuration -################################################################ - -development: true # Set this to false for selfhosting. If you leave this enabled and complain about weird - # things happening to your bot in the selfhosting chat you will be publicly taunted. - -prefix: '<<' # Default prefix used by the bot -restServerEnabled: true # Set this to false if you are running multiple FredBoat bots on the same machine -admins: [] # Add comma separated userIds and roleIds that should have access to bot admin commands. Find role ids with the ;;roleinfo command -useAutoBlacklist: true # Set to true to automatically blacklist users who frequently hit the rate limits -game: "" # Set the displayed game/status. Leave empty quote marks for the default status -continuePlayback: false # Set to true to force the player to continue playback even if left alone - -enableYouTube: true # Set to true to enable playing YouTube links -enableSoundCloud: true # Set to true to enable playing SoundCloud links -enableBandCamp: true # Set to true to enable playing BandCamp links -enableTwitch: true # Set to true to enable playing Twitch links -enableVimeo: true # Set to true to enable playing Vimeo links -enableMixer: true # Set to true to enable playing Mixer links -enableSpotify: true # Set to true to enable playing Spotify links -enableLocal: false # Set to true to enable playing local files -enableHttp: false # Set to true to enable playing direct links - - -################################################################ -### Essential credentials -################################################################ - -# Add your discord bot token below, between the quotation marks -# Find the token of your bot on https://discordapp.com/developers/applications/me -# Tutorial: https://github.com/reactiflux/discord-irc/wiki/Creating-a-discord-bot-&-getting-a-token -token: "PutYourDiscordBotTokenHere" - - -# Used by the ;;split and ;;np commands. Must be hooked up to the Youtube Data API. -# Add your google API key between the quotation marks -# How to get the key: https://developers.google.com/youtube/registering_an_application -googleServerKeys: "PutYourGoogleAPIKeyHere" - - - -################################################################ -### Optional APIs -################################################################ - -# For the ;;mal command -# Create an account on https://myanimelist.net/ and enter its login below -malUser: "" -malPassword: "" - - -# Used to access imgur galleries for some RandomImageCommands -# Acquired from here: https://api.imgur.com/oauth2/addclient -# Choose an option that does not require an Authorization callback URL -imgurClientId: "" - - -# Used to retrieve Spotify playlists -# Get them from here: https://developer.spotify.com/my-applications -spotifyId: "" -spotifySecret: "" - - -# Used by ;;weather command. -# Get them from: http://openweathermap.org/appid -openWeatherKey: "" - - - -################################################################ -### Developers and very experienced users only -################################################################ - - -# FredBoat was written to work with PostgreSQL. -# If you are running with docker-compose then you don't need to change the jdbcUrl here. -# In PostgreSQL, role means user and vice versa. Keep that in mind when reading the following help and the provided links. -# If you are running your own PostgreSQL database, you will need to provide a role and a database belonging to that role. -# The role needs at least the permission to log in. -# All postgres databases used by FredBoat are required to have the Hstore extension enabled. -# Learn more about roles here: https://www.postgresql.org/docs/10/static/database-roles.html -# Learn more about creating databases here: https://www.postgresql.org/docs/10/static/manage-ag-createdb.html -# Learn more about the postgres jdbc url here: https://jdbc.postgresql.org/documentation/head/connect.html -# Learn more about creating extensions here: https://www.postgresql.org/docs/current/static/sql-createextension.html -# If you are using an SSH tunnel, you need to point your jdbc url to localhost and the configured tunnelLocalPort -# Example jdbc: "jdbc:postgresql://localhost:5432/fredboat?user=fredboat&password=youshallnotpass" -jdbcUrl: "" - - -# Ssh tunnel for a remote database. this is useful for when you don't want to expose your database on the remote server -# and instead use ssh tunneling to access it -# If you are running with docker-compose then you don't need to change any ssh value here. -# If you are using an SSH tunnel, you need to point your jdbc url to localhost and the configured tunnelLocalPort -useSshTunnel: false -sshHost: "" # add the ssh port to the ip / url, usually 22, for example: "db.example.com:22" -sshUser: "" # user on the remote machine -sshPrivateKeyFile: "" # path to an ssh private key file which is authorized to log in to the sshUser on the remote machine. learn how to create these: https://www.digitalocean.com/community/tutorials/initial-server-setup-with-ubuntu-16-04#step-four-—-add-public-key-authentication-(recommended) -sshKeyPassphrase: "" # optional passphrase for the ssh key file -tunnelLocalPort: 5432 # endpoint port of the tunnel on the machine running fredboat; makes sure these dont collide; this one needs to be used in the jdbc url -tunnelRemotePort: 5432 # port of the PostgreSQL on the remote machine, 5432 by default - -# Database for caching things, see config of main database above for details about the individual values. -# If you are running with docker-compose then you don't need to change the cache jdbcUrl here. -# The main and cache databases can be two databases inside a single postgres instance. -# They CANNOT be the same database due to the way flyway migrations work. -# The main benefit is that you don't have to backup/migrate the cache database, it can just be dropped/recreated -# If you do not provide a jdbc url for the cache database, FredBoat will still work (most likely), but may have a degraded -# performance, especially in high usage environments and when using Spotify playlists. -# If you are going to use two different ssh tunnels for both database connections, make sure that the local tunnel ports don't collide -cacheJdbcUrl: "" - -cacheUseSshTunnel: false -cacheSshHost: "" -cacheSshUser: "" -cacheSshPrivateKeyFile: "" -cacheSshKeyPassphrase: "" -cacheTunnelLocalPort: 5433 -cacheTunnelRemotePort: 5432 - - - -# Additional google keys -# If you find yourself running a big bot and hitting youtube API ratelimits, you can add several keys via the list below. -# Remember to comment out the other "googleServerKeys" entry in this file, you can have only one of them. -# FredBoat will pick the keys by random to to access Youtube. -#googleServerKeys: ["Key1", "Key2", "Key3"] - - -# Error aggregation service https://sentry.io/ -sentryDsn: "" - - -# If you are running lavalink nodes this is the place to add them. -# Examples shown below, don't forget to uncomment them properly. -# More on Lavalink: https://github.com/Frederikam/Lavalink -#lavalinkHosts: - #- name : "local" - # host : "ws://localhost:5555" - # pass : "youshallnotpass" - #- name : "remote1" - # host : "ws://192.168.1.20:5556" - # pass : "youshallnotpass" - #- name : "remote2" - # host : "ws://lavalink.example.com:5557" - # pass : "youshallnotpass" - - -# Webhooks to Discord channels that will post some guild stats and shard status changes -# More information on webhooks: https://support.discordapp.com/hc/en-us/articles/228383668-Intro-to-Webhooks -# Example: "https://canary.discordapp.com/api/webhooks/1234567890/QWERTZUIOPasdfghjklYXCVBNM" (no, this one will not work) -eventLogWebhook: "" # webhook url for connect / disconnect events -eventLogInterval: 1 # interval at which connect / disconnect events are posted in minutes -guildStatsWebhook: "" # webhook url for guild stats -guildStatsInterval: 60 # interval at which guild stats are posted in minutes - - -# Post build tool test results into a discord channel. The token must be a discord bot token. -testToken: "" -testChannelId: "" diff --git a/FredBoat/src/main/java/fredboat/api/API.java b/FredBoat/src/main/java/fredboat/api/API.java index f5adb4f07..2798b24b1 100644 --- a/FredBoat/src/main/java/fredboat/api/API.java +++ b/FredBoat/src/main/java/fredboat/api/API.java @@ -41,21 +41,21 @@ public class API { - private static final Logger log = LoggerFactory.getLogger(API.class); + public static final int DEFAULT_PORT = 1356; - private static final int PORT = 1356; + private static final Logger log = LoggerFactory.getLogger(API.class); private API() {} - public static void start(PlayerRegistry playerRegistry, BotMetrics botMetrics, ShardProvider shardProvider) { + public static void start(PlayerRegistry playerRegistry, BotMetrics botMetrics, ShardProvider shardProvider, + int apiPort) { if (!Launcher.getBotController().getAppConfig().isRestServerEnabled()) { log.warn("Rest server is not enabled. Skipping Spark ignition!"); return; } - log.info("Igniting Spark API on port: " + PORT); - - Spark.port(PORT); + log.info("Igniting Spark API on port: " + apiPort); + Spark.port(apiPort); Spark.before((request, response) -> { log.info(request.requestMethod() + " " + request.pathInfo()); diff --git a/FredBoat/src/main/java/fredboat/audio/player/AudioConnectionFacade.java b/FredBoat/src/main/java/fredboat/audio/player/AudioConnectionFacade.java index 3cd6685d8..f8b6560eb 100644 --- a/FredBoat/src/main/java/fredboat/audio/player/AudioConnectionFacade.java +++ b/FredBoat/src/main/java/fredboat/audio/player/AudioConnectionFacade.java @@ -63,7 +63,7 @@ public AudioConnectionFacade(LavalinkConfig lavalinkConfig, Credentials credenti ShardProvider shardProvider) { this.debugConnectionListenerProvider = debugConnectionListenerProvider; this.audioPlayerManager = audioPlayerManager; - if (lavalinkConfig.getLavalinkHosts().isEmpty()) { + if (lavalinkConfig.getNodes().isEmpty()) { lavalink = null; //local playback audioPlayerManager.enableGcMonitoring(); return; @@ -76,9 +76,9 @@ public AudioConnectionFacade(LavalinkConfig lavalinkConfig, Credentials credenti ); Runtime.getRuntime().addShutdownHook(new Thread(lavalink::shutdown, "lavalink-shutdown-hook")); - List hosts = lavalinkConfig.getLavalinkHosts(); - hosts.forEach(lavalinkHost -> lavalink.addNode(lavalinkHost.getName(), lavalinkHost.getUri(), - lavalinkHost.getPassword())); + List nodes = lavalinkConfig.getNodes(); + nodes.forEach(lavalinkNode -> lavalink.addNode(lavalinkNode.getName(), lavalinkNode.getUri(), + lavalinkNode.getPassword())); new LavalinkCollector(lavalink).register(); } diff --git a/FredBoat/src/main/java/fredboat/config/ConfigConfiguration.java b/FredBoat/src/main/java/fredboat/config/ConfigConfiguration.java deleted file mode 100644 index 5eb82ccfc..000000000 --- a/FredBoat/src/main/java/fredboat/config/ConfigConfiguration.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2017-2018 Frederik Ar. Mikkelsen - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package fredboat.config; - -import fredboat.config.property.*; -import org.springframework.beans.factory.config.ConfigurableBeanFactory; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Scope; - -/** - * Created by napster on 23.02.18. - *

- * The name is not a meme, I swear. - *

- * Provide refreshing beans to access property configs - */ -@Configuration -public class ConfigConfiguration { - - @Bean - @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) - public AppConfig appConfig(PropertyConfigProvider configProvider) { - return configProvider.getAppConfig(); - } - - @Bean - @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) - public AudioSourcesConfig audioSourcesConfig(PropertyConfigProvider configProvider) { - return configProvider.getAudioSourcesConfig(); - } - - @Bean - @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) - public Credentials credentials(PropertyConfigProvider configProvider) { - return configProvider.getCredentials(); - } - - @Bean - @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) - public DatabaseConfig databaseConfig(PropertyConfigProvider configProvider) { - return configProvider.getDatabaseConfig(); - } - - @Bean - @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) - public EventLoggerConfig eventLoggerConfig(PropertyConfigProvider configProvider) { - return configProvider.getEventLoggerConfig(); - } - - @Bean - @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) - public LavalinkConfig lavalinkConfig(PropertyConfigProvider configProvider) { - return configProvider.getLavalinkConfig(); - } -} diff --git a/FredBoat/src/main/java/fredboat/config/DatabaseConfiguration.java b/FredBoat/src/main/java/fredboat/config/DatabaseConfiguration.java index 4893c46b1..9559fa1d2 100644 --- a/FredBoat/src/main/java/fredboat/config/DatabaseConfiguration.java +++ b/FredBoat/src/main/java/fredboat/config/DatabaseConfiguration.java @@ -28,7 +28,7 @@ import fredboat.agent.DBConnectionWatchdogAgent; import fredboat.agent.FredBoatAgent; import fredboat.config.property.DatabaseConfig; -import fredboat.config.property.PropertyConfigProvider; +import fredboat.config.property.ConfigPropertiesProvider; import fredboat.db.DatabaseManager; import fredboat.main.ShutdownHandler; import fredboat.shared.constant.BotConstants; @@ -116,7 +116,7 @@ public DatabaseConnection cacheDbConn(DatabaseManager databaseManager, ShutdownH } @Bean - public DatabaseManager databaseManager(PropertyConfigProvider configProvider, HibernateStatisticsCollector hibernateStats, + public DatabaseManager databaseManager(ConfigPropertiesProvider configProvider, HibernateStatisticsCollector hibernateStats, PrometheusMetricsTrackerFactory hikariStats) { //run migrations except when its the patron boat boolean migrateAndValidate = DiscordUtil.getBotId(configProvider.getCredentials()) != BotConstants.PATRON_BOT_ID; diff --git a/FredBoat/src/main/java/fredboat/config/ShardManagerConfiguration.java b/FredBoat/src/main/java/fredboat/config/ShardManagerConfiguration.java index ddc71646f..778ca6adf 100644 --- a/FredBoat/src/main/java/fredboat/config/ShardManagerConfiguration.java +++ b/FredBoat/src/main/java/fredboat/config/ShardManagerConfiguration.java @@ -26,8 +26,8 @@ import com.sedmelluq.discord.lavaplayer.jdaudp.NativeAudioSendFactory; import fredboat.audio.player.AudioConnectionFacade; +import fredboat.config.property.ConfigPropertiesProvider; import fredboat.config.property.Credentials; -import fredboat.config.property.PropertyConfigProvider; import fredboat.event.EventListenerBoat; import fredboat.event.EventLogger; import fredboat.event.MusicPersistenceHandler; @@ -68,7 +68,7 @@ public SessionController getSessionController(Credentials credentials) { } @Bean - public ShardManager buildShardManager(PropertyConfigProvider configProvider, EventListenerBoat mainEventListener, + public ShardManager buildShardManager(ConfigPropertiesProvider configProvider, EventListenerBoat mainEventListener, AudioConnectionFacade audioConnectionFacade, SessionController sessionController, EventLogger eventLogger, JdaEventsMetricsListener jdaEventsMetricsListener, ShardReviveHandler shardReviveHandler, MusicPersistenceHandler musicPersistenceHandler, @@ -76,7 +76,7 @@ public ShardManager buildShardManager(PropertyConfigProvider configProvider, Eve DefaultShardManagerBuilder builder = new DefaultShardManagerBuilder() .setToken(configProvider.getCredentials().getBotToken()) - .setGame(Game.playing(configProvider.getAppConfig().getGame())) + .setGame(Game.playing(configProvider.getAppConfig().getStatus())) .setBulkDeleteSplittingEnabled(false) .setEnableShutdownHook(false) .setAudioEnabled(true) diff --git a/FredBoat/src/main/java/fredboat/config/property/AppConfig.java b/FredBoat/src/main/java/fredboat/config/property/AppConfig.java index 0d666d7d0..232d5a390 100644 --- a/FredBoat/src/main/java/fredboat/config/property/AppConfig.java +++ b/FredBoat/src/main/java/fredboat/config/property/AppConfig.java @@ -24,6 +24,7 @@ package fredboat.config.property; +import fredboat.commandmeta.CommandInitializer; import fredboat.shared.constant.DistributionEnum; import java.util.List; @@ -55,11 +56,23 @@ default String getPrefix() { boolean isRestServerEnabled(); - List getAdminIds(); + List getAdminIds(); boolean useAutoBlacklist(); + /** + * @return empty string for default status + */ String getGame(); + default String getStatus() { + String game = getGame(); + if (game.isEmpty()) { + return "Say " + getPrefix() + CommandInitializer.HELP_COMM_NAME; + } else { + return game; + } + } + boolean getContinuePlayback(); } diff --git a/FredBoat/src/main/java/fredboat/config/property/AppConfigProperties.java b/FredBoat/src/main/java/fredboat/config/property/AppConfigProperties.java new file mode 100644 index 000000000..e9960132f --- /dev/null +++ b/FredBoat/src/main/java/fredboat/config/property/AppConfigProperties.java @@ -0,0 +1,120 @@ +/* + * MIT License + * + * Copyright (c) 2017-2018 Frederik Ar. Mikkelsen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package fredboat.config.property; + +import fredboat.shared.constant.DistributionEnum; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by napster on 03.03.18. + */ +@Component +@ConfigurationProperties(prefix = "config") +public class AppConfigProperties implements AppConfig { + + private boolean development = true; + private boolean patron = true; + + private String prefix = "<<"; + private boolean restServerEnabled = true; + private List botAdmins = new ArrayList<>(); + private boolean autoBlacklist; + private String game = ""; + private boolean continuePlayback; + + + @Override + public DistributionEnum getDistribution() { + return development ? DistributionEnum.DEVELOPMENT + : patron ? DistributionEnum.PATRON + : DistributionEnum.MUSIC; + } + + @Override + public String getPrefix() { + return prefix; + } + + @Override + public boolean isRestServerEnabled() { + return restServerEnabled; + } + + @Override + public List getAdminIds() { + return botAdmins; + } + + @Override + public boolean useAutoBlacklist() { + return autoBlacklist; + } + + @Override + public String getGame() { + return game; + } + + @Override + public boolean getContinuePlayback() { + return continuePlayback; + } + + public void setDevelopment(boolean development) { + this.development = development; + } + + public void setPatron(boolean patron) { + this.patron = patron; + } + + public void setPrefix(String prefix) { + this.prefix = prefix; + } + + public void setRestServerEnabled(boolean restServerEnabled) { + this.restServerEnabled = restServerEnabled; + } + + public void setBotAdmins(List botAdmins) { + this.botAdmins = botAdmins; + } + + public void setAutoBlacklist(boolean autoBlacklist) { + this.autoBlacklist = autoBlacklist; + } + + public void setGame(String game) { + this.game = game; + } + + public void setContinuePlayback(boolean continuePlayback) { + this.continuePlayback = continuePlayback; + } +} diff --git a/FredBoat/src/main/java/fredboat/config/property/AudioSourcesConfigProperties.java b/FredBoat/src/main/java/fredboat/config/property/AudioSourcesConfigProperties.java new file mode 100644 index 000000000..db4f21c93 --- /dev/null +++ b/FredBoat/src/main/java/fredboat/config/property/AudioSourcesConfigProperties.java @@ -0,0 +1,128 @@ +/* + * MIT License + * + * Copyright (c) 2017-2018 Frederik Ar. Mikkelsen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package fredboat.config.property; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +/** + * Created by napster on 03.03.18. + */ +@Component +@ConfigurationProperties(prefix = "audio-sources") +public class AudioSourcesConfigProperties implements AudioSourcesConfig { + + // audio managers + private boolean youtubeEnabled; + private boolean soundcloudEnabled; + private boolean bandcampEnabled; + private boolean twitchEnabled; + private boolean vimeoEnabled; + private boolean mixerEnabled; + private boolean spotifyEnabled; + private boolean localEnabled; + private boolean httpEnabled; + + @Override + public boolean isYouTubeEnabled() { + return youtubeEnabled; + } + + @Override + public boolean isSoundCloudEnabled() { + return soundcloudEnabled; + } + + @Override + public boolean isBandCampEnabled() { + return bandcampEnabled; + } + + @Override + public boolean isTwitchEnabled() { + return twitchEnabled; + } + + @Override + public boolean isVimeoEnabled() { + return vimeoEnabled; + } + + @Override + public boolean isMixerEnabled() { + return mixerEnabled; + } + + @Override + public boolean isSpotifyEnabled() { + return spotifyEnabled; + } + + @Override + public boolean isLocalEnabled() { + return localEnabled; + } + + @Override + public boolean isHttpEnabled() { + return httpEnabled; + } + + public void setYoutubeEnabled(boolean youtubeEnabled) { + this.youtubeEnabled = youtubeEnabled; + } + + public void setSoundcloudEnabled(boolean soundcloudEnabled) { + this.soundcloudEnabled = soundcloudEnabled; + } + + public void setBandcampEnabled(boolean bandcampEnabled) { + this.bandcampEnabled = bandcampEnabled; + } + + public void setTwitchEnabled(boolean twitchEnabled) { + this.twitchEnabled = twitchEnabled; + } + + public void setVimeoEnabled(boolean vimeoEnabled) { + this.vimeoEnabled = vimeoEnabled; + } + + public void setMixerEnabled(boolean mixerEnabled) { + this.mixerEnabled = mixerEnabled; + } + + public void setSpotifyEnabled(boolean spotifyEnabled) { + this.spotifyEnabled = spotifyEnabled; + } + + public void setLocalEnabled(boolean localEnabled) { + this.localEnabled = localEnabled; + } + + public void setHttpEnabled(boolean httpEnabled) { + this.httpEnabled = httpEnabled; + } +} diff --git a/FredBoat/src/main/java/fredboat/config/property/PropertyConfigProvider.java b/FredBoat/src/main/java/fredboat/config/property/ConfigPropertiesProvider.java similarity index 97% rename from FredBoat/src/main/java/fredboat/config/property/PropertyConfigProvider.java rename to FredBoat/src/main/java/fredboat/config/property/ConfigPropertiesProvider.java index a1bd51a48..5a452721e 100644 --- a/FredBoat/src/main/java/fredboat/config/property/PropertyConfigProvider.java +++ b/FredBoat/src/main/java/fredboat/config/property/ConfigPropertiesProvider.java @@ -29,7 +29,7 @@ *

* Provide access to our property based configs */ -public interface PropertyConfigProvider { +public interface ConfigPropertiesProvider { AppConfig getAppConfig(); diff --git a/FredBoat/src/main/java/fredboat/config/property/CredentialsProperties.java b/FredBoat/src/main/java/fredboat/config/property/CredentialsProperties.java new file mode 100644 index 000000000..6466a62f2 --- /dev/null +++ b/FredBoat/src/main/java/fredboat/config/property/CredentialsProperties.java @@ -0,0 +1,151 @@ +/* + * MIT License + * + * Copyright (c) 2017-2018 Frederik Ar. Mikkelsen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package fredboat.config.property; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by napster on 03.03.18. + */ +@Component +@ConfigurationProperties(prefix = "credentials") +public class CredentialsProperties implements Credentials { + + private String discordBotToken = ""; + private List googleApiKeys = new ArrayList<>(); + private String malUser = ""; + private String malPassword = ""; + private String imgurClientId = ""; + private String spotifyId = ""; + private String spotifySecret = ""; + private String openWeatherKey = ""; + private String sentryDsn = ""; + private String carbonKey = ""; + private String dikeUrl = ""; + + + @Override + public String getBotToken() { + return discordBotToken; + } + + @Override + public List getGoogleKeys() { + return googleApiKeys; + } + + @Override + public String getMalUser() { + return malUser; + } + + @Override + public String getMalPassword() { + return malPassword; + } + + @Override + public String getImgurClientId() { + return imgurClientId; + } + + @Override + public String getSpotifyId() { + return spotifyId; + } + + @Override + public String getSpotifySecret() { + return spotifySecret; + } + + @Override + public String getOpenWeatherKey() { + return openWeatherKey; + } + + @Override + public String getSentryDsn() { + return sentryDsn; + } + + @Override + public String getCarbonKey() { + return carbonKey; + } + + @Override + public String getDikeUrl() { + return dikeUrl; + } + + public void setDiscordBotToken(String discordBotToken) { + this.discordBotToken = discordBotToken; + } + + public void setGoogleApiKeys(List googleApiKeys) { + this.googleApiKeys = googleApiKeys; + } + + public void setMalUser(String malUser) { + this.malUser = malUser; + } + + public void setMalPassword(String malPassword) { + this.malPassword = malPassword; + } + + public void setImgurClientId(String imgurClientId) { + this.imgurClientId = imgurClientId; + } + + public void setSpotifyId(String spotifyId) { + this.spotifyId = spotifyId; + } + + public void setSpotifySecret(String spotifySecret) { + this.spotifySecret = spotifySecret; + } + + public void setOpenWeatherKey(String openWeatherKey) { + this.openWeatherKey = openWeatherKey; + } + + public void setSentryDsn(String sentryDsn) { + this.sentryDsn = sentryDsn; + } + + public void setCarbonKey(String carbonKey) { + this.carbonKey = carbonKey; + } + + public void setDikeUrl(String dikeUrl) { + this.dikeUrl = dikeUrl; + } +} diff --git a/FredBoat/src/main/java/fredboat/config/property/DatabaseConfigProperties.java b/FredBoat/src/main/java/fredboat/config/property/DatabaseConfigProperties.java new file mode 100644 index 000000000..694025dd0 --- /dev/null +++ b/FredBoat/src/main/java/fredboat/config/property/DatabaseConfigProperties.java @@ -0,0 +1,165 @@ +/* + * MIT License + * + * Copyright (c) 2017-2018 Frederik Ar. Mikkelsen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package fredboat.config.property; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; +import space.npstr.sqlsauce.ssh.SshTunnel; + +import javax.annotation.Nullable; + +/** + * Created by napster on 03.03.18. + */ +@Component +@ConfigurationProperties(prefix = "database") +@SuppressWarnings("unused") +public class DatabaseConfigProperties implements DatabaseConfig { + + private Db main = new Db(); + private Db cache = new Db(); + + @Override + public String getMainJdbcUrl() { + return main.getJdbcUrl(); + } + + @Nullable + @Override + public SshTunnel.SshDetails getMainSshTunnelConfig() { + return main.getTunnel().toDetails(); + } + + @Nullable + @Override + public String getCacheJdbcUrl() { + String cacheJdbcUrl = cache.getJdbcUrl(); + return !cacheJdbcUrl.isEmpty() ? cacheJdbcUrl : null; + } + + @Nullable + @Override + public SshTunnel.SshDetails getCacheSshTunnelConfig() { + return cache.getTunnel().toDetails(); + } + + public void setMain(Db main) { + this.main = main; + } + + public void setCache(Db cache) { + this.cache = cache; + } + + private static class Db { + private String jdbcUrl = ""; + private TunnelProperties tunnel = new TunnelProperties(); + + public String getJdbcUrl() { + return jdbcUrl; + } + + public void setJdbcUrl(String jdbcUrl) { + this.jdbcUrl = jdbcUrl; + } + + public TunnelProperties getTunnel() { + return tunnel; + } + + public void setTunnel(TunnelProperties tunnel) { + this.tunnel = tunnel; + } + } + + private static class TunnelProperties { + + private String host = ""; + private String user = ""; + private String privateKeyFile = ""; + private String keyPass = ""; + private int localPort = 9333; + private int remotePort = 5432; + + @Nullable + public SshTunnel.SshDetails toDetails() { + return host.isEmpty() + ? null + : new SshTunnel.SshDetails(host, user) + .setKeyFile(privateKeyFile) + .setPassphrase(keyPass) + .setLocalPort(localPort) + .setRemotePort(remotePort); + } + + public String getHost() { + return host; + } + + public void setHost(String host) { + this.host = host; + } + + public String getUser() { + return user; + } + + public void setUser(String user) { + this.user = user; + } + + public String getPrivateKeyFile() { + return privateKeyFile; + } + + public void setPrivateKeyFile(String privateKeyFile) { + this.privateKeyFile = privateKeyFile; + } + + public String getKeyPass() { + return keyPass; + } + + public void setKeyPass(String keyPass) { + this.keyPass = keyPass; + } + + public int getLocalPort() { + return localPort; + } + + public void setLocalPort(int localPort) { + this.localPort = localPort; + } + + public int getRemotePort() { + return remotePort; + } + + public void setRemotePort(int remotePort) { + this.remotePort = remotePort; + } + } +} diff --git a/FredBoat/src/main/java/fredboat/config/property/EventLoggerConfigProperties.java b/FredBoat/src/main/java/fredboat/config/property/EventLoggerConfigProperties.java new file mode 100644 index 000000000..7581c8dea --- /dev/null +++ b/FredBoat/src/main/java/fredboat/config/property/EventLoggerConfigProperties.java @@ -0,0 +1,78 @@ +/* + * MIT License + * + * Copyright (c) 2017-2018 Frederik Ar. Mikkelsen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package fredboat.config.property; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +/** + * Created by napster on 03.03.18. + */ +@Component +@ConfigurationProperties(prefix = "event-logger") +public class EventLoggerConfigProperties implements EventLoggerConfig { + + private String eventLogWebhook = ""; + private int eventLogInterval = 1; + private String guildStatsWebhook = ""; + private int guildStatsInterval = 60; + + + @Override + public String getEventLogWebhook() { + return eventLogWebhook; + } + + @Override + public int getEventLogInterval() { + return eventLogInterval; + } + + @Override + public String getGuildStatsWebhook() { + return guildStatsWebhook; + } + + @Override + public int getGuildStatsInterval() { + return guildStatsInterval; + } + + public void setEventLogWebhook(String eventLogWebhook) { + this.eventLogWebhook = eventLogWebhook; + } + + public void setEventLogInterval(int eventLogInterval) { + this.eventLogInterval = eventLogInterval; + } + + public void setGuildStatsWebhook(String guildStatsWebhook) { + this.guildStatsWebhook = guildStatsWebhook; + } + + public void setGuildStatsInterval(int guildStatsInterval) { + this.guildStatsInterval = guildStatsInterval; + } +} diff --git a/FredBoat/src/main/java/fredboat/config/property/FileConfig.java b/FredBoat/src/main/java/fredboat/config/property/FileConfig.java deleted file mode 100644 index 2513a0205..000000000 --- a/FredBoat/src/main/java/fredboat/config/property/FileConfig.java +++ /dev/null @@ -1,608 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2017-2018 Frederik Ar. Mikkelsen - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package fredboat.config.property; - -import com.google.common.base.CharMatcher; -import com.google.common.base.Suppliers; -import fredboat.audio.player.PlayerLimitManager; -import fredboat.commandmeta.CommandInitializer; -import fredboat.shared.constant.DistributionEnum; -import org.apache.commons.io.FileUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.yaml.snakeyaml.Yaml; -import org.yaml.snakeyaml.error.YAMLException; -import space.npstr.sqlsauce.ssh.SshTunnel; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.net.URI; -import java.net.URISyntaxException; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.Supplier; - -public class FileConfig implements AppConfig, AudioSourcesConfig, Credentials, EventLoggerConfig, DatabaseConfig, LavalinkConfig { - - private static final Logger log = LoggerFactory.getLogger(FileConfig.class); - - private static final Supplier configSupplier = Suppliers.memoizeWithExpiration(FileConfig::loadConfig, - 1, TimeUnit.MINUTES); - - //a fallback reference to the last sucessfulyy loaded config, in case editing the config files breaks them - @Nullable - private static FileConfig lastSuccessfulLoaded; - - //todo: trace down all callers of this and make sure they take advantage of a reloading config like - //todo not storing the values once retrieved and recreating objects on value changes where possible/feasible - public static FileConfig get() { - return FileConfig.configSupplier.get(); - } - - - private static FileConfig loadConfig() { - long nanoTime = System.nanoTime(); - FileConfig c; - try { - c = new FileConfig(loadConfigFile("fredboat")); - } catch (Exception e) { - if (lastSuccessfulLoaded != null) { - log.error("Reloading config file failed! Serving last successfully loaded one.", e); - return lastSuccessfulLoaded; - } - throw new RuntimeException("Could not load config files!", e); - } - log.debug("Loading config took {}ms", TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - nanoTime)); - lastSuccessfulLoaded = c; - return c; - } - - //FileConfig - - private DistributionEnum distribution; - private String prefix; - private boolean restServerEnabled; - private List adminIds = new ArrayList<>(); - private boolean useAutoBlacklist; - private String game; - private boolean continuePlayback; - - // audio managers - private boolean youtubeAudio; - private boolean soundcloudAudio; - private boolean bandcampAudio; - private boolean twitchAudio; - private boolean vimeoAudio; - private boolean mixerAudio; - private boolean spotifyAudio; - private boolean localAudio; - private boolean httpAudio; - - - //Credentials - - // essential - private String botToken; - private List googleKeys = new ArrayList<>(); - - // apis - private String malUser; - private String malPassword; - private String imgurClientId; - private String spotifyId; - private String spotifySecret; - private String openWeatherKey; - - // main database + SSH tunnel - @Nonnull - private String jdbcUrl; - @Nullable - private SshTunnel.SshDetails mainSshTunnelConfig; - - // cache database + SSH tunnel - @Nullable - private String cacheJdbcUrl; - @Nullable - private SshTunnel.SshDetails cacheSshTunnelConfig; - - // misc - private String sentryDsn; - private List lavalinkHosts = new ArrayList<>(); - private String eventLogWebhook; - private int eventLogInterval; - private String guildStatsWebhook; - private int guildStatsInterval; - - - // Undocumented creds - private String carbonKey; - private String dikeUrl; - - - /** - * The config is regularly reloaded, it should not be doing any blocking calls. - */ - @SuppressWarnings("unchecked") - private FileConfig(File configFile) { - try { - Yaml yaml = new Yaml(); - String configFileStr = FileUtils.readFileToString(configFile, "UTF-8"); - //remove those pesky tab characters so a potential json file is YAML conform - configFileStr = cleanTabs(configFileStr, "fredboat.yaml"); - - Map config = yaml.load(configFileStr); - - //avoid null values, rather change them to empty strings - config.keySet().forEach((String key) -> config.putIfAbsent(key, "")); - - - //Load FileConfig values - - // Determine distribution - if ((boolean) config.getOrDefault("development", true)) { - distribution = DistributionEnum.DEVELOPMENT; - } else if ((boolean) config.getOrDefault("patron", true)) { - distribution = DistributionEnum.PATRON; - } else { - distribution = DistributionEnum.MUSIC; - } - log.info("Determined distribution: " + distribution); - - prefix = (String) config.getOrDefault("prefix", DEFAULT_PREFIX); - log.info("Using prefix: " + prefix); - restServerEnabled = (boolean) config.getOrDefault("restServerEnabled", true); - - Object admins = config.get("admins"); - if (admins instanceof List) { - ((List) admins).forEach((Object str) -> adminIds.add(str + "")); - } else if (admins instanceof String) { - adminIds.add(admins + ""); - } - useAutoBlacklist = (boolean) config.getOrDefault("useAutoBlacklist", true); - game = (String) config.getOrDefault("game", ""); - continuePlayback = (boolean) config.getOrDefault("continuePlayback", false); - - //Modular audiomanagers - youtubeAudio = (Boolean) config.getOrDefault("enableYouTube", true); - soundcloudAudio = (Boolean) config.getOrDefault("enableSoundCloud", true); - bandcampAudio = (Boolean) config.getOrDefault("enableBandCamp", true); - twitchAudio = (Boolean) config.getOrDefault("enableTwitch", true); - vimeoAudio = (Boolean) config.getOrDefault("enableVimeo", true); - mixerAudio = (Boolean) config.getOrDefault("enableMixer", true); - spotifyAudio = (Boolean) config.getOrDefault("enableSpotify", true); - localAudio = (Boolean) config.getOrDefault("enableLocal", false); - httpAudio = (Boolean) config.getOrDefault("enableHttp", false); - - - //Load Credential values - Object token = config.get("token"); - if (token instanceof String) { - botToken = (String) token; - } else { - Map tokens = (Map) token; - botToken = tokens.getOrDefault(distribution.getId(), ""); - } - if (botToken == null || botToken.isEmpty()) { - throw new RuntimeException("No discord bot token provided for the started distribution " + distribution - + "\nMake sure to put a " + distribution.getId() + " token in your fredboat.yaml file."); - } - - Object gkeys = config.get("googleServerKeys"); - if (gkeys instanceof List) { - ((List) gkeys).forEach((Object str) -> googleKeys.add((String) str)); - } else if (gkeys instanceof String) { - googleKeys.add((String) gkeys); - } else { - log.warn("No google API keys found. Some commands may not work, check the documentation."); - } - - // apis - malUser = (String) config.getOrDefault("malUser", ""); - malPassword = (String) config.getOrDefault("malPassword", ""); - - imgurClientId = (String) config.getOrDefault("imgurClientId", ""); - - spotifyId = (String) config.getOrDefault("spotifyId", ""); - spotifySecret = (String) config.getOrDefault("spotifySecret", ""); - - openWeatherKey = (String) config.getOrDefault("openWeatherKey", ""); - sentryDsn = (String) config.getOrDefault("sentryDsn", ""); - - - // main database - jdbcUrl = (String) config.getOrDefault("jdbcUrl", ""); - if (jdbcUrl == null || jdbcUrl.isEmpty()) { - if ("docker".equals(System.getenv("ENV"))) { - log.info("No main JDBC URL found, docker environment detected. Using default docker main JDBC url"); - jdbcUrl = "jdbc:postgresql://db:5432/fredboat?user=fredboat"; - } else { - String message = "No main jdbcUrl provided in a non-docker environment. FredBoat cannot work without a database."; - log.error(message); - throw new RuntimeException(message); - } - } - boolean useSshTunnel = (boolean) config.getOrDefault("useSshTunnel", false); - if (useSshTunnel) { - //Parse host:port - String sshHostRaw = (String) config.getOrDefault("sshHost", "localhost:22"); - String sshHost = sshHostRaw.split(":")[0]; - int sshPort; - try { - sshPort = Integer.parseInt(sshHostRaw.split(":")[1]); - } catch (Exception e) { - sshPort = 22; - } - String sshUser = (String) config.getOrDefault("sshUser", "fredboat"); - String sshPrivateKeyFile = (String) config.getOrDefault("sshPrivateKeyFile", "database.ppk"); - String sshKeyPassphrase = (String) config.getOrDefault("sshKeyPassphrase", ""); - int tunnelLocalPort = (int) config.getOrDefault("tunnelLocalPort", 9333);//9333 is a legacy port for backwards compatibility - String tunnelRemotePortKey = "tunnelRemotePort"; - if (config.containsKey("forwardToPort")) {//legacy check - tunnelRemotePortKey = "forwardToPort"; - } - int tunnelRemotePort = (int) config.getOrDefault(tunnelRemotePortKey, 5432); - - mainSshTunnelConfig = new SshTunnel.SshDetails(sshHost, sshUser) - .setKeyFile(sshPrivateKeyFile) - .setPassphrase(sshKeyPassphrase == null || sshKeyPassphrase.isEmpty() ? null : sshKeyPassphrase) - .setSshPort(sshPort) - .setLocalPort(tunnelLocalPort) - .setRemotePort(tunnelRemotePort); - } - - - // cache database - cacheJdbcUrl = (String) config.getOrDefault("cacheJdbcUrl", ""); - if (cacheJdbcUrl == null || cacheJdbcUrl.isEmpty()) { - if ("docker".equals(System.getenv("ENV"))) { - log.info("No cache jdbcUrl found, docker environment detected. Using default docker cache JDBC url"); - cacheJdbcUrl = "jdbc:postgresql://db:5432/fredboat_cache?user=fredboat"; - } else { - log.warn("No cache jdbcUrl provided in a non-docker environment. This may lead to a degraded performance, " - + "especially in a high usage environment, or when using Spotify playlists."); - cacheJdbcUrl = null; - } - } - if (jdbcUrl.equals(cacheJdbcUrl)) { - log.warn("The main and cache jdbc urls may not point to the same database due to how flyway handles migrations. " - + "The cache database will not be available in this execution of FredBoat. This may lead to a degraded performance, " - + "especially in a high usage environment, or when using Spotify playlists."); - cacheJdbcUrl = null; - } - boolean cacheUseSshTunnel = (boolean) config.getOrDefault("cacheUseSshTunnel", false); - if (cacheUseSshTunnel) { - //Parse host:port - String cacheSshHostRaw = (String) config.getOrDefault("cacheSshHost", "localhost:22"); - String cacheSshHost = cacheSshHostRaw.split(":")[0]; - int cacheSshPort; - try { - cacheSshPort = Integer.parseInt(cacheSshHostRaw.split(":")[1]); - } catch (Exception e) { - cacheSshPort = 22; - } - String cacheSshUser = (String) config.getOrDefault("cacheSshUser", "fredboat"); - String cacheSshPrivateKeyFile = (String) config.getOrDefault("cacheSshPrivateKeyFile", "database.ppk"); - String cacheSshKeyPassphrase = (String) config.getOrDefault("cacheSshKeyPassphrase", ""); - int cacheTunnelLocalPort = (int) config.getOrDefault("cacheTunnelLocalPort", 5433); - int cacheTunnelRemotePort = (int) config.getOrDefault("cacheTunnelRemotePort", 5432); - - cacheSshTunnelConfig = new SshTunnel.SshDetails(cacheSshHost, cacheSshUser) - .setKeyFile(cacheSshPrivateKeyFile) - .setPassphrase(cacheSshKeyPassphrase == null || cacheSshKeyPassphrase.isEmpty() ? null : cacheSshKeyPassphrase) - .setSshPort(cacheSshPort) - .setLocalPort(cacheTunnelLocalPort) - .setRemotePort(cacheTunnelRemotePort); - } - - // misc - Object linkNodes = config.get("lavalinkHosts"); - if (linkNodes != null) { - if (linkNodes instanceof Map) { - Map simpleNodes = (Map) linkNodes; - AtomicInteger nodeCounter = new AtomicInteger(0); - simpleNodes.forEach((host, pass) -> { - try { - String name = "Lavalink-Node#" + nodeCounter.getAndIncrement(); - URI uri = new URI(host); - lavalinkHosts.add(new LavalinkConfig.LavalinkHost(name, uri, pass)); - log.info("Lavalink node added: {} {}", name, uri); - } catch (URISyntaxException e) { - throw new RuntimeException("Failed parsing lavalink URI", e); - } - }); - } else { - List> namedNodes = (List>) linkNodes; - for (Map node : namedNodes) { - try { - String name = node.get("name"); - URI uri = new URI(node.get("host")); - lavalinkHosts.add(new LavalinkConfig.LavalinkHost(name, uri, node.get("pass"))); - } catch (URISyntaxException e) { - throw new RuntimeException("Failed parsing lavalink URI", e); - } - } - } - } - - eventLogWebhook = (String) config.getOrDefault("eventLogWebhook", ""); - eventLogInterval = (int) config.getOrDefault("eventLogInterval", 1); //minutes - guildStatsWebhook = (String) config.getOrDefault("guildStatsWebhook", ""); - guildStatsInterval = (int) config.getOrDefault("guildStatsInterval", 60); //minutes - - - // Undocumented creds - carbonKey = (String) config.getOrDefault("carbonKey", ""); - dikeUrl = (String) config.getOrDefault("dikeUrl", ""); - - - PlayerLimitManager.setLimit((Integer) config.getOrDefault("playerLimit", -1)); - } catch (IOException e) { - log.error("Failed to read one or more yaml files into strings", e); - throw new RuntimeException("Failed to read one or more yaml files into strings.", e); - } catch (YAMLException | ClassCastException e) { - log.error("Could not parse one or more yaml files! They are probably misformatted. " + - "Try using an online yaml validator.", e); - throw e; - } catch (Exception e) { - log.error("Could not init file config", e); - throw e; - } - } - - /** - * @param name relative name of a config file, without the file extension - * @return a handle on the requested file - */ - private static File loadConfigFile(String name) throws IOException { - String path = "./" + name + ".yaml"; - File file = new File(path); - if (!file.exists() || file.isDirectory()) { - throw new FileNotFoundException("Could not find '" + path + "' file."); - } - return file; - } - - private static String cleanTabs(String content, String file) { - CharMatcher tab = CharMatcher.is('\t'); - if (tab.matchesAnyOf(content)) { - log.warn("{} contains tab characters! Trying a fix-up.", file); - return tab.replaceFrom(content, " "); - } else { - return content; - } - } - - - // ******************************************************************************** - // Config Getters - // ******************************************************************************** - - @Override - public DistributionEnum getDistribution() { - return distribution; - } - - @Override - public String getPrefix() { - return prefix; - } - - @Override - public boolean isRestServerEnabled() { - return restServerEnabled; - } - - @Override - public List getAdminIds() { - return adminIds; - } - - @Override - public boolean useAutoBlacklist() { - return useAutoBlacklist; - } - - @Override - public String getGame() { - if (game.isEmpty()) { - return "Say " + getPrefix() + CommandInitializer.HELP_COMM_NAME; - } else { - return game; - } - } - - @Override - public boolean getContinuePlayback() { - return continuePlayback; - } - - @Override - public boolean isYouTubeEnabled() { - return youtubeAudio; - } - - @Override - public boolean isSoundCloudEnabled() { - return soundcloudAudio; - } - - @Override - public boolean isBandCampEnabled() { - return bandcampAudio; - } - - @Override - public boolean isTwitchEnabled() { - return twitchAudio; - } - - @Override - public boolean isVimeoEnabled() { - return vimeoAudio; - } - - @Override - public boolean isMixerEnabled() { - return mixerAudio; - } - - @Override - public boolean isSpotifyEnabled() { - return spotifyAudio; - } - - @Override - public boolean isLocalEnabled() { - return localAudio; - } - - @Override - public boolean isHttpEnabled() { - return httpAudio; - } - - - // ******************************************************************************** - // Credentials Getters - // ******************************************************************************** - - @Override - public String getBotToken() { - return botToken; - } - - @Override - public List getGoogleKeys() { - return googleKeys; - } - - @Override - public String getMalUser() { - return malUser; - } - - @Override - public String getMalPassword() { - return malPassword; - } - - @Override - public String getImgurClientId() { - return imgurClientId; - } - - @Override - public String getSpotifyId() { - return spotifyId; - } - - @Override - public String getSpotifySecret() { - return spotifySecret; - } - - @Override - public String getOpenWeatherKey() { - return openWeatherKey; - } - - @Override - public String getSentryDsn() { - return sentryDsn; - } - - @Override - @Nonnull - public String getMainJdbcUrl() { - return jdbcUrl; - } - - @Override - @Nullable - public SshTunnel.SshDetails getMainSshTunnelConfig() { - return mainSshTunnelConfig; - } - - @Override - @Nullable - //may return null if no cache database was provided. - public String getCacheJdbcUrl() { - return cacheJdbcUrl; - } - - @Override - @Nullable - public SshTunnel.SshDetails getCacheSshTunnelConfig() { - return cacheSshTunnelConfig; - } - - @Override - public List getLavalinkHosts() { - return lavalinkHosts; - } - - @Override - public String getEventLogWebhook() { - return eventLogWebhook; - } - - //minutes - @Override - public int getEventLogInterval() { - return eventLogInterval; - } - - @Override - public String getGuildStatsWebhook() { - return guildStatsWebhook; - } - - //minutes - @Override - public int getGuildStatsInterval() { - return guildStatsInterval; - } - - - // ******************************************************************************** - // Derived and undocumented values - // ******************************************************************************** - - @Override - public String getCarbonKey() { - return carbonKey; - } - - @Override - public String getDikeUrl() { - return dikeUrl; - } -} diff --git a/FredBoat/src/main/java/fredboat/config/property/LavalinkConfig.java b/FredBoat/src/main/java/fredboat/config/property/LavalinkConfig.java index 35da65260..42d897808 100644 --- a/FredBoat/src/main/java/fredboat/config/property/LavalinkConfig.java +++ b/FredBoat/src/main/java/fredboat/config/property/LavalinkConfig.java @@ -25,6 +25,7 @@ package fredboat.config.property; import java.net.URI; +import java.net.URISyntaxException; import java.util.List; /** @@ -35,19 +36,13 @@ public interface LavalinkConfig { /** * @return Lavalink nodes */ - List getLavalinkHosts(); + List getNodes(); - class LavalinkHost { + class LavalinkNode { - private final String name; - private final URI uri; - private final String password; - - public LavalinkHost(String name, URI uri, String password) { - this.name = name; - this.uri = uri; - this.password = password; - } + private String name = ""; + private URI uri; + private String pass = ""; public String getName() { return name; @@ -58,7 +53,19 @@ public URI getUri() { } public String getPassword() { - return password; + return pass; + } + + public void setName(String name) { + this.name = name; + } + + public void setHost(String host) throws URISyntaxException { + this.uri = new URI(host); + } + + public void setPass(String pass) { + this.pass = pass; } } } diff --git a/FredBoat/src/main/java/fredboat/config/property/FilePropertyConfigProvider.java b/FredBoat/src/main/java/fredboat/config/property/LavalinkConfigProperties.java similarity index 61% rename from FredBoat/src/main/java/fredboat/config/property/FilePropertyConfigProvider.java rename to FredBoat/src/main/java/fredboat/config/property/LavalinkConfigProperties.java index f6d12537f..fe4e510ae 100644 --- a/FredBoat/src/main/java/fredboat/config/property/FilePropertyConfigProvider.java +++ b/FredBoat/src/main/java/fredboat/config/property/LavalinkConfigProperties.java @@ -24,46 +24,28 @@ package fredboat.config.property; +import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; +import java.util.ArrayList; +import java.util.List; + /** - * Created by napster on 23.02.18. - *

- * Proxy calls to our reloading property configs + * Created by napster on 03.03.18. */ @Component -public class FilePropertyConfigProvider implements PropertyConfigProvider { - - public FilePropertyConfigProvider() { - } - - @Override - public AppConfig getAppConfig() { - return FileConfig.get(); - } - - @Override - public AudioSourcesConfig getAudioSourcesConfig() { - return FileConfig.get(); - } +@ConfigurationProperties(prefix = "lavalink") +public class LavalinkConfigProperties implements LavalinkConfig { - @Override - public Credentials getCredentials() { - return FileConfig.get(); - } + private List nodes = new ArrayList<>(); - @Override - public DatabaseConfig getDatabaseConfig() { - return FileConfig.get(); - } @Override - public EventLoggerConfig getEventLoggerConfig() { - return FileConfig.get(); + public List getNodes() { + return nodes; } - @Override - public LavalinkConfig getLavalinkConfig() { - return FileConfig.get(); + public void setNodes(List nodes) { + this.nodes = nodes; } } diff --git a/FredBoat/src/main/java/fredboat/config/property/SpringConfigPropertiesProvider.java b/FredBoat/src/main/java/fredboat/config/property/SpringConfigPropertiesProvider.java new file mode 100644 index 000000000..4b43ce3dc --- /dev/null +++ b/FredBoat/src/main/java/fredboat/config/property/SpringConfigPropertiesProvider.java @@ -0,0 +1,82 @@ +/* + * MIT License + * + * Copyright (c) 2017-2018 Frederik Ar. Mikkelsen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package fredboat.config.property; + +import org.springframework.stereotype.Component; + +/** + * Created by napster on 03.03.18. + */ +@Component +public class SpringConfigPropertiesProvider implements ConfigPropertiesProvider { + + private final AppConfig appConfig; + private final AudioSourcesConfig audioSourcesConfig; + private final Credentials credentials; + private final DatabaseConfig databaseConfig; + private final EventLoggerConfig eventLoggerConfig; + private final LavalinkConfig lavalinkConfig; + + public SpringConfigPropertiesProvider(AppConfig appConfig, AudioSourcesConfig audioSourcesConfig, + Credentials credentials, DatabaseConfig databaseConfig, + EventLoggerConfig eventLoggerConfig, LavalinkConfig lavalinkConfig) { + this.appConfig = appConfig; + this.audioSourcesConfig = audioSourcesConfig; + this.credentials = credentials; + this.databaseConfig = databaseConfig; + this.eventLoggerConfig = eventLoggerConfig; + this.lavalinkConfig = lavalinkConfig; + } + + @Override + public AppConfig getAppConfig() { + return appConfig; + } + + @Override + public AudioSourcesConfig getAudioSourcesConfig() { + return audioSourcesConfig; + } + + @Override + public Credentials getCredentials() { + return credentials; + } + + @Override + public DatabaseConfig getDatabaseConfig() { + return databaseConfig; + } + + @Override + public EventLoggerConfig getEventLoggerConfig() { + return eventLoggerConfig; + } + + @Override + public LavalinkConfig getLavalinkConfig() { + return lavalinkConfig; + } +} diff --git a/FredBoat/src/main/java/fredboat/db/EntityIO.java b/FredBoat/src/main/java/fredboat/db/EntityIO.java index 1babae946..d6a319401 100644 --- a/FredBoat/src/main/java/fredboat/db/EntityIO.java +++ b/FredBoat/src/main/java/fredboat/db/EntityIO.java @@ -25,7 +25,7 @@ package fredboat.db; -import fredboat.config.property.PropertyConfigProvider; +import fredboat.config.property.ConfigPropertiesProvider; import fredboat.db.api.*; import fredboat.db.entity.cache.SearchResult; import fredboat.db.entity.main.*; @@ -56,7 +56,7 @@ public class EntityIO implements BlacklistIO, GuildConfigIO, GuildDataIO, GuildM private static final Logger log = LoggerFactory.getLogger(EntityIO.class); - private final PropertyConfigProvider configProvider; + private final ConfigPropertiesProvider configProvider; private final GuildConfigRepo guildConfigRepo; private final GuildDataRepo guildDataRepo; @@ -68,7 +68,7 @@ public class EntityIO implements BlacklistIO, GuildConfigIO, GuildDataIO, GuildM @Nullable private final SearchResultRepo searchResultRepo; - public EntityIO(PropertyConfigProvider configProvider, BlacklistRepo blacklistRepo, GuildConfigRepo guildConfigRepo, + public EntityIO(ConfigPropertiesProvider configProvider, BlacklistRepo blacklistRepo, GuildConfigRepo guildConfigRepo, GuildDataRepo guildDataRepo, GuildModulesRepo guildModulesRepo, GuildPermsRepo guildPermsRepo, PrefixRepo prefixRepo, @Nullable SearchResultRepo searchResultRepo) { this.configProvider = configProvider; diff --git a/FredBoat/src/main/java/fredboat/event/EventLogger.java b/FredBoat/src/main/java/fredboat/event/EventLogger.java index 22619a73c..a831c30e0 100644 --- a/FredBoat/src/main/java/fredboat/event/EventLogger.java +++ b/FredBoat/src/main/java/fredboat/event/EventLogger.java @@ -26,7 +26,6 @@ package fredboat.event; import fredboat.config.property.EventLoggerConfig; -import fredboat.config.property.PropertyConfigProvider; import fredboat.jda.ShardProvider; import fredboat.main.ShutdownHandler; import fredboat.messaging.CentralMessaging; @@ -180,12 +179,11 @@ private Runnable createShutdownHook(ShutdownHandler shutdownHandler) { } //actual constructor - public EventLogger(PropertyConfigProvider configProvider, ShutdownHandler shutdownHandler, ShardProvider shardProvider) { + public EventLogger(EventLoggerConfig eventLoggerConfig, ShutdownHandler shutdownHandler, ShardProvider shardProvider) { this.shardProvider = shardProvider; - EventLoggerConfig config = configProvider.getEventLoggerConfig(); Runtime.getRuntime().addShutdownHook(new Thread(createShutdownHook(shutdownHandler), EventLogger.class.getSimpleName() + " shutdownhook")); - String eventLoggerWebhookUrl = config.getEventLogWebhook(); + String eventLoggerWebhookUrl = eventLoggerConfig.getEventLogWebhook(); WebhookClient eventLoggerWebhook = null; if (!eventLoggerWebhookUrl.isEmpty()) { try { @@ -220,11 +218,11 @@ public EventLogger(PropertyConfigProvider configProvider, ShutdownHandler shutdo } catch (Exception e) { log.error("Failed to send shard status summary to event log webhook", e); } - }, 0, Math.max(config.getEventLogInterval(), 1), TimeUnit.MINUTES); + }, 0, Math.max(eventLoggerConfig.getEventLogInterval(), 1), TimeUnit.MINUTES); } - String guildStatsWebhookUrl = config.getGuildStatsWebhook(); + String guildStatsWebhookUrl = eventLoggerConfig.getGuildStatsWebhook(); WebhookClient guildStatsWebhook = null; if (!guildStatsWebhookUrl.isEmpty()) { try { @@ -251,7 +249,7 @@ public EventLogger(PropertyConfigProvider configProvider, ShutdownHandler shutdo } this.guildStatsWebhook = workingWebhook; - int interval = Math.max(config.getGuildStatsInterval(), 1); + int interval = Math.max(eventLoggerConfig.getGuildStatsInterval(), 1); if (this.guildStatsWebhook != null) { scheduler.scheduleAtFixedRate(() -> { try { diff --git a/FredBoat/src/main/java/fredboat/main/BotController.java b/FredBoat/src/main/java/fredboat/main/BotController.java index 93dc4ab43..1501ffcd2 100644 --- a/FredBoat/src/main/java/fredboat/main/BotController.java +++ b/FredBoat/src/main/java/fredboat/main/BotController.java @@ -6,8 +6,8 @@ import fredboat.audio.player.PlayerRegistry; import fredboat.config.property.AppConfig; import fredboat.config.property.AudioSourcesConfig; +import fredboat.config.property.ConfigPropertiesProvider; import fredboat.config.property.Credentials; -import fredboat.config.property.PropertyConfigProvider; import fredboat.db.DatabaseManager; import fredboat.db.EntityIO; import fredboat.event.EventListenerBoat; @@ -35,7 +35,7 @@ public class BotController { .eventListener(new OkHttpEventMetrics("default", Metrics.httpEventCounter)) .build()); - private final PropertyConfigProvider configProvider; + private final ConfigPropertiesProvider configProvider; private final AudioConnectionFacade audioConnectionFacade; private final ShardManager shardManager; //central event listener that all events by all shards pass through @@ -51,7 +51,7 @@ public class BotController { private final Ratelimiter ratelimiter; - public BotController(PropertyConfigProvider configProvider, AudioConnectionFacade audioConnectionFacade, ShardManager shardManager, + public BotController(ConfigPropertiesProvider configProvider, AudioConnectionFacade audioConnectionFacade, ShardManager shardManager, EventListenerBoat eventListenerBoat, ShutdownHandler shutdownHandler, DatabaseManager databaseManager, EntityIO entityIO, ExecutorService executor, HibernateStatisticsCollector hibernateStats, PlayerRegistry playerRegistry, JdaEntityProvider jdaEntityProvider, BotMetrics botMetrics, diff --git a/FredBoat/src/main/java/fredboat/main/Launcher.java b/FredBoat/src/main/java/fredboat/main/Launcher.java index 74be51106..ece1f6d8a 100644 --- a/FredBoat/src/main/java/fredboat/main/Launcher.java +++ b/FredBoat/src/main/java/fredboat/main/Launcher.java @@ -1,5 +1,6 @@ package fredboat.main; +import com.google.common.base.CharMatcher; import com.sedmelluq.discord.lavaplayer.tools.PlayerLibrary; import fredboat.agent.CarbonitexAgent; import fredboat.agent.FredBoatAgent; @@ -12,8 +13,7 @@ import fredboat.command.admin.SentryDsnCommand; import fredboat.commandmeta.CommandInitializer; import fredboat.commandmeta.CommandRegistry; -import fredboat.config.property.FileConfig; -import fredboat.config.property.PropertyConfigProvider; +import fredboat.config.property.ConfigPropertiesProvider; import fredboat.feature.I18n; import fredboat.feature.metrics.BotMetrics; import fredboat.feature.metrics.MetricsServletAdapter; @@ -30,9 +30,11 @@ import net.dv8tion.jda.core.JDAInfo; import okhttp3.Credentials; import okhttp3.Response; +import org.apache.commons.io.FileUtils; import org.json.JSONObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.ApplicationArguments; import org.springframework.boot.ApplicationRunner; import org.springframework.boot.SpringApplication; @@ -43,9 +45,13 @@ import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration; import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration; import org.springframework.context.annotation.ComponentScan; +import org.yaml.snakeyaml.Yaml; import space.npstr.sqlsauce.DatabaseException; +import java.io.File; +import java.io.FileNotFoundException; import java.io.IOException; +import java.util.Map; import java.util.concurrent.ExecutorService; /** @@ -77,7 +83,7 @@ public class Launcher implements ApplicationRunner { private static final Logger log = LoggerFactory.getLogger(Launcher.class); public static final long START_TIME = System.currentTimeMillis(); private static BotController BC; //temporary hack access to the bot context - private final PropertyConfigProvider configProvider; + private final ConfigPropertiesProvider configProvider; private final ExecutorService executor; private final MetricsServletAdapter metricsServlet; private final CacheMetricsCollector cacheMetrics; @@ -90,6 +96,7 @@ public class Launcher implements ApplicationRunner { private final VideoSelectionCache videoSelectionCache; private final ShardProvider shardProvider; private final GuildProvider guildProvider; + private final int apiPort; public static void main(String[] args) throws IllegalArgumentException, DatabaseException { //just post the info to the console @@ -105,12 +112,7 @@ public static void main(String[] args) throws IllegalArgumentException, Database log.info(getVersionInfo()); //create the sentry appender as early as possible - String sentryDsn = FileConfig.get().getSentryDsn(); - if (!sentryDsn.isEmpty()) { - SentryDsnCommand.turnOn(sentryDsn); - } else { - SentryDsnCommand.turnOff(); - } + setUpSentry(); int javaVersionMajor = -1; @@ -137,11 +139,12 @@ public static BotController getBotController() { return BC; } - public Launcher(BotController botController, PropertyConfigProvider configProvider, ExecutorService executor, + public Launcher(BotController botController, ConfigPropertiesProvider configProvider, ExecutorService executor, MetricsServletAdapter metricsServlet, CacheMetricsCollector cacheMetrics, PlayerRegistry playerRegistry, StatsAgent statsAgent, BotMetrics botMetrics, Weather weather, AudioConnectionFacade audioConnectionFacade, TrackSearcher trackSearcher, - VideoSelectionCache videoSelectionCache, ShardProvider shardProvider, GuildProvider guildProvider) { + VideoSelectionCache videoSelectionCache, ShardProvider shardProvider, GuildProvider guildProvider, + @Value("${server.port:" + API.DEFAULT_PORT + "}") int apiPort) { Launcher.BC = botController; this.configProvider = configProvider; this.executor = executor; @@ -156,6 +159,7 @@ public Launcher(BotController botController, PropertyConfigProvider configProvid this.videoSelectionCache = videoSelectionCache; this.shardProvider = shardProvider; this.guildProvider = guildProvider; + this.apiPort = apiPort; } @Override @@ -164,7 +168,7 @@ public void run(ApplicationArguments args) throws InterruptedException { I18n.start(); try { - API.start(playerRegistry, botMetrics, shardProvider); + API.start(playerRegistry, botMetrics, shardProvider, apiPort); } catch (Exception e) { log.info("Failed to ignite Spark, FredBoat API unavailable", e); } @@ -296,4 +300,56 @@ private static String getVersionInfo() { + "\n\tLavaplayer " + PlayerLibrary.VERSION + "\n"; } + + private static void setUpSentry() { + String sentryDsn = System.getProperty("sentry.dsn"); + if (sentryDsn == null || sentryDsn.isEmpty()) { + sentryDsn = System.getenv("SENTRY_DSN"); + } + if (sentryDsn == null || sentryDsn.isEmpty()) { + try { + File configFile = loadConfigFile("fredboat"); + cleanTabs(configFile); + String configFileStr = FileUtils.readFileToString(configFile, "UTF-8"); + Yaml yaml = new Yaml(); + Map config = yaml.load(configFileStr); + @SuppressWarnings("unchecked") Map credentials + = (Map) config.getOrDefault("credentials", null); + sentryDsn = (String) credentials.getOrDefault("sentryDsn", ""); + } catch (Exception e) { + log.error("Failed to preload config to extract sentry dsn"); + } + } + + log.info("Senstry dsn: {}", sentryDsn); + if (sentryDsn != null && !sentryDsn.isEmpty()) { + SentryDsnCommand.turnOn(sentryDsn); + } else { + SentryDsnCommand.turnOff(); + } + } + + /** + * @param name relative name of a config file, without the file extension + * @return a handle on the requested file + */ + private static File loadConfigFile(String name) throws IOException { + String path = "./" + name + ".yaml"; + File file = new File(path); + if (!file.exists() || file.isDirectory()) { + throw new FileNotFoundException("Could not find '" + path + "' file."); + } + return file; + } + + //replace tabs with double spaces in a file + private static void cleanTabs(File file) throws IOException { + String content = FileUtils.readFileToString(file, "UTF-8"); + CharMatcher tab = CharMatcher.is('\t'); + if (tab.matchesAnyOf(content)) { + log.warn("{} contains tab characters! Trying a fix-up.", file); + String newContent = tab.replaceFrom(content, " "); + FileUtils.writeStringToFile(file, newContent, "UTF-8"); + } + } } diff --git a/FredBoat/src/main/java/fredboat/perms/PermsUtil.java b/FredBoat/src/main/java/fredboat/perms/PermsUtil.java index 3fdc04727..5844cae81 100644 --- a/FredBoat/src/main/java/fredboat/perms/PermsUtil.java +++ b/FredBoat/src/main/java/fredboat/perms/PermsUtil.java @@ -90,9 +90,9 @@ public static boolean checkPermsWithFeedback(PermissionLevel minLevel, CommandCo */ private static boolean isBotAdmin(Member member) { boolean botAdmin = false; - for (String id : Launcher.getBotController().getAppConfig().getAdminIds()) { + for (long id : Launcher.getBotController().getAppConfig().getAdminIds()) { Role r = member.getGuild().getRoleById(id); - if (member.getUser().getId().equals(id) + if (member.getUser().getIdLong() == id || (r != null && member.getRoles().contains(r))) { botAdmin = true; break; diff --git a/FredBoat/src/main/java/fredboat/util/ratelimit/Ratelimiter.java b/FredBoat/src/main/java/fredboat/util/ratelimit/Ratelimiter.java index 94be4b3c0..8a86f2368 100644 --- a/FredBoat/src/main/java/fredboat/util/ratelimit/Ratelimiter.java +++ b/FredBoat/src/main/java/fredboat/util/ratelimit/Ratelimiter.java @@ -63,9 +63,7 @@ public Ratelimiter(AppConfig appConfig, ExecutorService executor, BlacklistIO bl Set whitelist = ConcurrentHashMap.newKeySet(); //only works for those admins who are added with their userId and not through a roleId - for (String admin : appConfig.getAdminIds()) { - whitelist.add(Long.valueOf(admin)); - } + whitelist.addAll(appConfig.getAdminIds()); //Create all the rate limiters we want ratelimits = new ArrayList<>(); diff --git a/FredBoat/src/test/java/fredboat/test/MockConfig.java b/FredBoat/src/test/java/fredboat/test/MockConfig.java index ed6b67223..636c9c711 100644 --- a/FredBoat/src/test/java/fredboat/test/MockConfig.java +++ b/FredBoat/src/test/java/fredboat/test/MockConfig.java @@ -95,7 +95,7 @@ public boolean isRestServerEnabled() { } @Override - public List getAdminIds() { + public List getAdminIds() { return Collections.emptyList(); } @@ -228,7 +228,7 @@ public SshTunnel.SshDetails getCacheSshTunnelConfig() { } @Override - public List getLavalinkHosts() { + public List getNodes() { return Collections.emptyList(); } From 4ed2bf198e0f026c7079786d847f8aa4c8a9d2c0 Mon Sep 17 00:00:00 2001 From: Napster Date: Sat, 3 Mar 2018 22:26:04 +0100 Subject: [PATCH 05/41] Correct config file name for docker --- FredBoat/.dockerignore | 2 +- FredBoat/Dockerfile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/FredBoat/.dockerignore b/FredBoat/.dockerignore index ba869c99e..0ca32a143 100644 --- a/FredBoat/.dockerignore +++ b/FredBoat/.dockerignore @@ -2,4 +2,4 @@ #ignore everything except the following files, they are used in the Dockerfile to build the fredboat image !Dockerfile !FredBoat.jar -!fredboat.yaml.example +!fredboat.example.yaml diff --git a/FredBoat/Dockerfile b/FredBoat/Dockerfile index 487d45919..bab7a7e1d 100644 --- a/FredBoat/Dockerfile +++ b/FredBoat/Dockerfile @@ -4,7 +4,7 @@ ENV ENV docker RUN mkdir -p /opt/FredBoat -COPY fredboat.yaml.example /opt/FredBoat/fredboat.yaml +COPY fredboat.example.yaml /opt/FredBoat/fredboat.yaml COPY FredBoat.jar /opt/FredBoat/FredBoat.jar EXPOSE 1356 From 587d45ec7359a8e121b777bcebf1cbd7fe2b5e26 Mon Sep 17 00:00:00 2001 From: Napster Date: Sat, 3 Mar 2018 22:26:51 +0100 Subject: [PATCH 06/41] Add an example for yaml lists --- FredBoat/fredboat.example.yaml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/FredBoat/fredboat.example.yaml b/FredBoat/fredboat.example.yaml index 74c2d07f4..dad6951f8 100644 --- a/FredBoat/fredboat.example.yaml +++ b/FredBoat/fredboat.example.yaml @@ -14,6 +14,7 @@ ### ### key: value ### +### ### You can wrap most values into quotation marks, except numbers and booleans: ### ### someUrl: "http://example.com" @@ -21,6 +22,19 @@ ### somePortNumber: 22 ### useSomeFeature: true ### +### +### You can have a list of things like this: +### +### listOfStrings: ["string1", "string2", "string3"] +### +### or like this: +### +### listOfStrings: +### - "string1" +### - "string2" +### - "string3" +### +### ### More information on correctly formatting yaml files: http://www.yaml.org/start.html From e1406f807789294d487e248483152def4294eee6 Mon Sep 17 00:00:00 2001 From: Napster Date: Sat, 3 Mar 2018 22:28:24 +0100 Subject: [PATCH 07/41] Add missing undocumented (and unused) player limit config option --- .../java/fredboat/config/property/AppConfig.java | 2 ++ .../config/property/AppConfigProperties.java | 13 +++++++++++++ .../src/test/java/fredboat/test/MockConfig.java | 5 +++++ 3 files changed, 20 insertions(+) diff --git a/FredBoat/src/main/java/fredboat/config/property/AppConfig.java b/FredBoat/src/main/java/fredboat/config/property/AppConfig.java index 232d5a390..b8ff9c6dd 100644 --- a/FredBoat/src/main/java/fredboat/config/property/AppConfig.java +++ b/FredBoat/src/main/java/fredboat/config/property/AppConfig.java @@ -60,6 +60,8 @@ default String getPrefix() { boolean useAutoBlacklist(); + int getPlayerLimit(); + /** * @return empty string for default status */ diff --git a/FredBoat/src/main/java/fredboat/config/property/AppConfigProperties.java b/FredBoat/src/main/java/fredboat/config/property/AppConfigProperties.java index e9960132f..c53a4066b 100644 --- a/FredBoat/src/main/java/fredboat/config/property/AppConfigProperties.java +++ b/FredBoat/src/main/java/fredboat/config/property/AppConfigProperties.java @@ -24,6 +24,7 @@ package fredboat.config.property; +import fredboat.audio.player.PlayerLimitManager; import fredboat.shared.constant.DistributionEnum; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; @@ -48,6 +49,8 @@ public class AppConfigProperties implements AppConfig { private String game = ""; private boolean continuePlayback; + //undocumented + private int playerLimit = -1; @Override public DistributionEnum getDistribution() { @@ -86,6 +89,11 @@ public boolean getContinuePlayback() { return continuePlayback; } + @Override + public int getPlayerLimit() { + return playerLimit; + } + public void setDevelopment(boolean development) { this.development = development; } @@ -117,4 +125,9 @@ public void setGame(String game) { public void setContinuePlayback(boolean continuePlayback) { this.continuePlayback = continuePlayback; } + + public void setPlayerLimit(int playerLimit) { + this.playerLimit = playerLimit; + PlayerLimitManager.setLimit(playerLimit); //todo make the playlimitmanager a component + } } diff --git a/FredBoat/src/test/java/fredboat/test/MockConfig.java b/FredBoat/src/test/java/fredboat/test/MockConfig.java index 636c9c711..0842b6410 100644 --- a/FredBoat/src/test/java/fredboat/test/MockConfig.java +++ b/FredBoat/src/test/java/fredboat/test/MockConfig.java @@ -114,6 +114,11 @@ public boolean getContinuePlayback() { return false; } + @Override + public int getPlayerLimit() { + return -1; + } + @Override public boolean isYouTubeEnabled() { return false; From 0efaf6d2d46b5735d4e018568b662d4a3b1f086d Mon Sep 17 00:00:00 2001 From: Napster Date: Sat, 3 Mar 2018 22:29:37 +0100 Subject: [PATCH 08/41] Readd logging of various config values as they are read for the first time --- .../config/property/AppConfigProperties.java | 15 +++++- .../property/CredentialsProperties.java | 12 +++++ .../property/DatabaseConfigProperties.java | 53 +++++++++++++++++-- .../property/LavalinkConfigProperties.java | 7 +++ 4 files changed, 83 insertions(+), 4 deletions(-) diff --git a/FredBoat/src/main/java/fredboat/config/property/AppConfigProperties.java b/FredBoat/src/main/java/fredboat/config/property/AppConfigProperties.java index c53a4066b..38fc9f09d 100644 --- a/FredBoat/src/main/java/fredboat/config/property/AppConfigProperties.java +++ b/FredBoat/src/main/java/fredboat/config/property/AppConfigProperties.java @@ -26,6 +26,8 @@ import fredboat.audio.player.PlayerLimitManager; import fredboat.shared.constant.DistributionEnum; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; @@ -39,6 +41,8 @@ @ConfigurationProperties(prefix = "config") public class AppConfigProperties implements AppConfig { + private static final Logger log = LoggerFactory.getLogger(AppConfigProperties.class); + private boolean development = true; private boolean patron = true; @@ -52,11 +56,19 @@ public class AppConfigProperties implements AppConfig { //undocumented private int playerLimit = -1; + private boolean distributionLogged = false; + + @Override public DistributionEnum getDistribution() { - return development ? DistributionEnum.DEVELOPMENT + DistributionEnum distribution = development ? DistributionEnum.DEVELOPMENT : patron ? DistributionEnum.PATRON : DistributionEnum.MUSIC; + if (!distributionLogged) { + log.info("Determined distribution: {}", distribution); + distributionLogged = true; + } + return distribution; } @Override @@ -104,6 +116,7 @@ public void setPatron(boolean patron) { public void setPrefix(String prefix) { this.prefix = prefix; + log.info("Using prefix: {}", prefix); } public void setRestServerEnabled(boolean restServerEnabled) { diff --git a/FredBoat/src/main/java/fredboat/config/property/CredentialsProperties.java b/FredBoat/src/main/java/fredboat/config/property/CredentialsProperties.java index 6466a62f2..c45d1a178 100644 --- a/FredBoat/src/main/java/fredboat/config/property/CredentialsProperties.java +++ b/FredBoat/src/main/java/fredboat/config/property/CredentialsProperties.java @@ -24,6 +24,8 @@ package fredboat.config.property; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; @@ -37,6 +39,8 @@ @ConfigurationProperties(prefix = "credentials") public class CredentialsProperties implements Credentials { + private static final Logger log = LoggerFactory.getLogger(CredentialsProperties.class); + private String discordBotToken = ""; private List googleApiKeys = new ArrayList<>(); private String malUser = ""; @@ -107,10 +111,18 @@ public String getDikeUrl() { public void setDiscordBotToken(String discordBotToken) { this.discordBotToken = discordBotToken; + //noinspection ConstantConditions + if (discordBotToken == null || discordBotToken.isEmpty()) { + throw new RuntimeException("No discord bot token provided." + + "\nMake sure to put a discord bot token into your fredboat.yaml file."); + } } public void setGoogleApiKeys(List googleApiKeys) { this.googleApiKeys = googleApiKeys; + if (googleApiKeys.isEmpty()) { + log.warn("No google API keys found. Some commands may not work, check the documentation."); + } } public void setMalUser(String malUser) { diff --git a/FredBoat/src/main/java/fredboat/config/property/DatabaseConfigProperties.java b/FredBoat/src/main/java/fredboat/config/property/DatabaseConfigProperties.java index 694025dd0..3acc6e96b 100644 --- a/FredBoat/src/main/java/fredboat/config/property/DatabaseConfigProperties.java +++ b/FredBoat/src/main/java/fredboat/config/property/DatabaseConfigProperties.java @@ -24,6 +24,8 @@ package fredboat.config.property; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; import space.npstr.sqlsauce.ssh.SshTunnel; @@ -38,12 +40,27 @@ @SuppressWarnings("unused") public class DatabaseConfigProperties implements DatabaseConfig { + private static final Logger log = LoggerFactory.getLogger(DatabaseConfigProperties.class); + private Db main = new Db(); private Db cache = new Db(); @Override public String getMainJdbcUrl() { - return main.getJdbcUrl(); + String jdbcUrl = main.getJdbcUrl(); + //noinspection ConstantConditions + if (jdbcUrl == null || jdbcUrl.isEmpty()) { + if ("docker".equals(System.getenv("ENV"))) { + log.info("No main JDBC URL found, docker environment detected. Using default docker main JDBC url"); + jdbcUrl = "jdbc:postgresql://db:5432/fredboat?user=fredboat"; + main.setJdbcUrl(jdbcUrl); + } else { + String message = "No main jdbcUrl provided in a non-docker environment. FredBoat cannot work without a database."; + log.error(message); + throw new RuntimeException(message); + } + } + return jdbcUrl; } @Nullable @@ -52,11 +69,41 @@ public SshTunnel.SshDetails getMainSshTunnelConfig() { return main.getTunnel().toDetails(); } + private boolean hasWarnedEmptyCacheJdbc = false; + private boolean hasWarnedSameJdbcs = false; + + @Nullable @Override public String getCacheJdbcUrl() { - String cacheJdbcUrl = cache.getJdbcUrl(); - return !cacheJdbcUrl.isEmpty() ? cacheJdbcUrl : null; + String jdbcUrl = cache.getJdbcUrl(); + //noinspection ConstantConditions + if (jdbcUrl == null || jdbcUrl.isEmpty()) { + if ("docker".equals(System.getenv("ENV"))) { + log.info("No cache jdbcUrl found, docker environment detected. Using default docker cache JDBC url"); + jdbcUrl = "jdbc:postgresql://db:5432/fredboat_cache?user=fredboat"; + cache.setJdbcUrl(jdbcUrl); + } else { + if (!hasWarnedEmptyCacheJdbc) { + log.warn("No cache jdbcUrl provided in a non-docker environment. This may lead to a degraded performance, " + + "especially in a high usage environment, or when using Spotify playlists."); + hasWarnedEmptyCacheJdbc = true; + } + jdbcUrl = ""; + } + } + + if (!jdbcUrl.isEmpty() && jdbcUrl.equals(getMainJdbcUrl())) { + if (!hasWarnedSameJdbcs) { + log.warn("The main and cache jdbc urls may not point to the same database due to how flyway handles migrations. " + + "The cache database will not be available in this execution of FredBoat. This may lead to a degraded performance, " + + "especially in a high usage environment, or when using Spotify playlists."); + hasWarnedSameJdbcs = true; + } + jdbcUrl = ""; + } + + return !jdbcUrl.isEmpty() ? jdbcUrl : null; } @Nullable diff --git a/FredBoat/src/main/java/fredboat/config/property/LavalinkConfigProperties.java b/FredBoat/src/main/java/fredboat/config/property/LavalinkConfigProperties.java index fe4e510ae..4e7be12a4 100644 --- a/FredBoat/src/main/java/fredboat/config/property/LavalinkConfigProperties.java +++ b/FredBoat/src/main/java/fredboat/config/property/LavalinkConfigProperties.java @@ -24,6 +24,8 @@ package fredboat.config.property; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; @@ -37,6 +39,8 @@ @ConfigurationProperties(prefix = "lavalink") public class LavalinkConfigProperties implements LavalinkConfig { + private static final Logger log = LoggerFactory.getLogger(LavalinkConfigProperties.class); + private List nodes = new ArrayList<>(); @@ -47,5 +51,8 @@ public List getNodes() { public void setNodes(List nodes) { this.nodes = nodes; + for (LavalinkNode node : nodes) { + log.info("Lavalink node added: {} {}", node.getName(), node.getUri()); + } } } From 8d9083f724ae9a4fa6386814d141945509b79d1b Mon Sep 17 00:00:00 2001 From: Napster Date: Fri, 16 Feb 2018 19:46:09 +0100 Subject: [PATCH 09/41] It works :clap: --- Backend/.gitignore | 2 + Backend/application.yml.example | 6 ++ Backend/build.gradle | 27 +++++ .../java/fredboat/backend/Application.java | 51 +++++++++ .../java/fredboat/backend/DbController.java | 80 ++++++++++++++ .../backend/config/CacheDbConfig.java | 65 +++++++++++ .../fredboat/backend/config/DbConfig.java | 102 ++++++++++++++++++ .../fredboat/backend/config/MainDbConfig.java | 59 ++++++++++ .../fredboat/backend/config/package-info.java | 29 +++++ .../java/fredboat/backend/package-info.java | 29 +++++ .../impl/cache/SpringSearchResultRepo.java | 42 ++++++++ .../db/repos/impl/cache/package-info.java | 29 +++++ .../impl/main/SpringGuildConfigRepo.java | 42 ++++++++ .../db/repos/impl/main/package-info.java | 29 +++++ ...itional-spring-configuration-metadata.json | 14 +++ build.gradle | 1 + settings.gradle | 2 + 17 files changed, 609 insertions(+) create mode 100644 Backend/.gitignore create mode 100644 Backend/application.yml.example create mode 100644 Backend/build.gradle create mode 100644 Backend/src/main/java/fredboat/backend/Application.java create mode 100644 Backend/src/main/java/fredboat/backend/DbController.java create mode 100644 Backend/src/main/java/fredboat/backend/config/CacheDbConfig.java create mode 100644 Backend/src/main/java/fredboat/backend/config/DbConfig.java create mode 100644 Backend/src/main/java/fredboat/backend/config/MainDbConfig.java create mode 100644 Backend/src/main/java/fredboat/backend/config/package-info.java create mode 100644 Backend/src/main/java/fredboat/backend/package-info.java create mode 100644 Backend/src/main/java/fredboat/db/repos/impl/cache/SpringSearchResultRepo.java create mode 100644 Backend/src/main/java/fredboat/db/repos/impl/cache/package-info.java create mode 100644 Backend/src/main/java/fredboat/db/repos/impl/main/SpringGuildConfigRepo.java create mode 100644 Backend/src/main/java/fredboat/db/repos/impl/main/package-info.java create mode 100644 Backend/src/main/resources/META-INF/additional-spring-configuration-metadata.json diff --git a/Backend/.gitignore b/Backend/.gitignore new file mode 100644 index 000000000..d26dd62cf --- /dev/null +++ b/Backend/.gitignore @@ -0,0 +1,2 @@ +/logs/ +application.yml diff --git a/Backend/application.yml.example b/Backend/application.yml.example new file mode 100644 index 000000000..0da71ecb0 --- /dev/null +++ b/Backend/application.yml.example @@ -0,0 +1,6 @@ +fredboat: + db: + main: + jdbcUrl: "" + cache: + jdbcUrl: "" diff --git a/Backend/build.gradle b/Backend/build.gradle new file mode 100644 index 000000000..572e0f340 --- /dev/null +++ b/Backend/build.gradle @@ -0,0 +1,27 @@ +apply plugin: 'propdeps' +apply plugin: 'propdeps-idea' +apply plugin: 'org.springframework.boot' +apply plugin: 'io.spring.dependency-management' + + +description = 'FredBoat backend, providing REST database services' +version '1.0' +ext { + moduleName = 'Backend' +} + +dependencies { + compile project(':Database') + + compile group: 'com.google.code.gson', name: 'gson', version: gsonVersion + + //versioning is handled by spring + compile "org.springframework.boot:spring-boot-starter-data-jpa" + compile "org.springframework.boot:spring-boot-starter-data-rest" + testCompile "org.springframework.boot:spring-boot-starter-test" + optional "org.springframework.boot:spring-boot-configuration-processor" +} + +//required by spring boot configuration processor +compileJava.dependsOn(processResources) + diff --git a/Backend/src/main/java/fredboat/backend/Application.java b/Backend/src/main/java/fredboat/backend/Application.java new file mode 100644 index 000000000..c3810e841 --- /dev/null +++ b/Backend/src/main/java/fredboat/backend/Application.java @@ -0,0 +1,51 @@ +/* + * + * MIT License + * + * Copyright (c) 2017-2018 Frederik Ar. Mikkelsen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package fredboat.backend; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration; +import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; +import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration; +import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration; + +/** + * Created by napster on 16.02.18. + */ +@SpringBootApplication +@EnableAutoConfiguration(exclude = { //we handle these ourselves + DataSourceAutoConfiguration.class, + DataSourceTransactionManagerAutoConfiguration.class, + HibernateJpaAutoConfiguration.class, + FlywayAutoConfiguration.class +}) +public class Application { + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } +} diff --git a/Backend/src/main/java/fredboat/backend/DbController.java b/Backend/src/main/java/fredboat/backend/DbController.java new file mode 100644 index 000000000..ef93db3df --- /dev/null +++ b/Backend/src/main/java/fredboat/backend/DbController.java @@ -0,0 +1,80 @@ +/* + * + * MIT License + * + * Copyright (c) 2017-2018 Frederik Ar. Mikkelsen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package fredboat.backend; + +import com.google.gson.Gson; +import fredboat.db.entity.main.GuildConfig; +import fredboat.db.repos.impl.cache.SpringSearchResultRepo; +import fredboat.db.repos.impl.main.SpringGuildConfigRepo; +import org.hibernate.internal.util.ReflectHelper; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import space.npstr.sqlsauce.DatabaseException; +import space.npstr.sqlsauce.entities.SaucedEntity; +import space.npstr.sqlsauce.fp.types.EntityKey; + +import javax.annotation.CheckReturnValue; +import java.io.Serializable; +import java.lang.reflect.Constructor; + +/** + * Created by napster on 16.02.18. + */ +@RestController +public class DbController { + + private final SpringGuildConfigRepo guildConfigRepo; + private final SpringSearchResultRepo searchResultRepo; + private final Gson gson = new Gson(); + + public DbController(SpringGuildConfigRepo guildConfigRepo, + SpringSearchResultRepo searchResultRepo) { + + this.guildConfigRepo = guildConfigRepo; + this.searchResultRepo = searchResultRepo; + } + + @RequestMapping("/main/guildconfig/{id}") + public String guildConfig(@PathVariable("id") String id) { + GuildConfig gc = guildConfigRepo.findById(id).orElse(newInstance(EntityKey.of(id, GuildConfig.class))); + return gson.toJson(gc); + } + + + @CheckReturnValue + private static , I extends Serializable> E newInstance(final EntityKey id) { + try { + Constructor constructor = ReflectHelper.getDefaultConstructor(id.clazz); + final E entity = constructor.newInstance((Object[]) null); + return entity.setId(id.id); + } catch (final ReflectiveOperationException e) { + final String message = String.format("Could not construct an entity of class %s with id %s", + id.clazz.getName(), id.toString()); + throw new DatabaseException(message, e); + } + } +} diff --git a/Backend/src/main/java/fredboat/backend/config/CacheDbConfig.java b/Backend/src/main/java/fredboat/backend/config/CacheDbConfig.java new file mode 100644 index 000000000..623947be1 --- /dev/null +++ b/Backend/src/main/java/fredboat/backend/config/CacheDbConfig.java @@ -0,0 +1,65 @@ +/* + * + * MIT License + * + * Copyright (c) 2017-2018 Frederik Ar. Mikkelsen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package fredboat.backend.config; + +import fredboat.db.DatabaseManager; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; +import org.springframework.orm.jpa.JpaTransactionManager; +import org.springframework.transaction.PlatformTransactionManager; +import org.springframework.transaction.annotation.EnableTransactionManagement; +import space.npstr.sqlsauce.DatabaseConnection; + +import javax.annotation.Nullable; +import javax.persistence.EntityManagerFactory; + +/** + * Created by napster on 16.02.18. + */ +@Configuration +@EnableTransactionManagement +@EnableJpaRepositories( + entityManagerFactoryRef = "cacheEntityManagerFactory", + transactionManagerRef = "cacheTransactionManager", + basePackages = {"fredboat.db.repos.impl.cache"} +) +public class CacheDbConfig { + + @Nullable + @Bean(name = "cacheEntityManagerFactory") + public EntityManagerFactory cacheEntityManagerFactory(DatabaseManager databaseManager) { + DatabaseConnection databaseConnection = databaseManager.getCacheDbConn(); + return databaseConnection == null ? null : databaseConnection.getEntityManagerFactory(); + } + + @Bean(name = "cacheTransactionManager") + public PlatformTransactionManager cacheTransactionManager( + @Qualifier("cacheEntityManagerFactory") EntityManagerFactory cacheEntityManagerFactory) { + return new JpaTransactionManager(cacheEntityManagerFactory); + } +} diff --git a/Backend/src/main/java/fredboat/backend/config/DbConfig.java b/Backend/src/main/java/fredboat/backend/config/DbConfig.java new file mode 100644 index 000000000..046975d3f --- /dev/null +++ b/Backend/src/main/java/fredboat/backend/config/DbConfig.java @@ -0,0 +1,102 @@ +/* + * + * MIT License + * + * Copyright (c) 2017-2018 Frederik Ar. Mikkelsen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package fredboat.backend.config; + +import fredboat.db.DatabaseManager; +import org.springframework.beans.factory.config.ConfigurableBeanFactory; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Scope; +import org.springframework.orm.jpa.JpaVendorAdapter; +import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; +import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; +import org.springframework.stereotype.Component; + +/** + * Created by napster on 16.02.18. + */ +@ConfigurationProperties(prefix = "fredboat.db") +@Component +public class DbConfig { + + @Bean("databaseManager") + @Scope(ConfigurableBeanFactory.SCOPE_SINGLETON) + DatabaseManager getDatabaseManager(DbConfig dbConfig) { + //todo improve these parameters + return new DatabaseManager(null, null, + 4, "Backend", true, + dbConfig.getMain().getJdbcUrl(), null, + dbConfig.getCache().getJdbcUrl(), null, + (puName, dataSource, properties, entityPackages) -> { + LocalContainerEntityManagerFactoryBean emfb = new LocalContainerEntityManagerFactoryBean(); + emfb.setDataSource(dataSource); + emfb.setPackagesToScan(entityPackages.toArray(new String[entityPackages.size()])); + + JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter(); + emfb.setJpaVendorAdapter(vendorAdapter); + emfb.setJpaProperties(properties); + + emfb.afterPropertiesSet(); //initiate creation of the native emf + return emfb.getNativeEntityManagerFactory(); + }); + } + + private final Main main = new Main(); + + public Main getMain() { + return main; + } + + private final Cache cache = new Cache(); + + public Cache getCache() { + return cache; + } + + public static class Main { + private String jdbcUrl = ""; + + public String getJdbcUrl() { + return jdbcUrl; + } + + public void setJdbcUrl(String jdbcUrl) { + this.jdbcUrl = jdbcUrl; + } + } + + public static class Cache { + private String jdbcUrl = ""; + + public String getJdbcUrl() { + return jdbcUrl; + } + + public void setJdbcUrl(String jdbcUrl) { + this.jdbcUrl = jdbcUrl; + } + } +} diff --git a/Backend/src/main/java/fredboat/backend/config/MainDbConfig.java b/Backend/src/main/java/fredboat/backend/config/MainDbConfig.java new file mode 100644 index 000000000..17f7a7a87 --- /dev/null +++ b/Backend/src/main/java/fredboat/backend/config/MainDbConfig.java @@ -0,0 +1,59 @@ +/* + * + * MIT License + * + * Copyright (c) 2017-2018 Frederik Ar. Mikkelsen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package fredboat.backend.config; + +import fredboat.db.DatabaseManager; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; +import org.springframework.orm.jpa.JpaTransactionManager; +import org.springframework.transaction.PlatformTransactionManager; +import org.springframework.transaction.annotation.EnableTransactionManagement; + +import javax.persistence.EntityManagerFactory; + +/** + * Created by napster on 16.02.18. + */ +@Configuration +@EnableTransactionManagement +@EnableJpaRepositories(basePackages = {"fredboat.db.repos.impl.main"}) +public class MainDbConfig { + + @Primary + @Bean(name = "entityManagerFactory") + public EntityManagerFactory entityManagerFactory(DatabaseManager databaseManager) { + return databaseManager.getMainDbConn().getEntityManagerFactory(); + } + + @Primary + @Bean(name = "transactionManager") + public PlatformTransactionManager transactionManager(@Qualifier("entityManagerFactory") EntityManagerFactory entityManagerFactory) { + return new JpaTransactionManager(entityManagerFactory); + } +} diff --git a/Backend/src/main/java/fredboat/backend/config/package-info.java b/Backend/src/main/java/fredboat/backend/config/package-info.java new file mode 100644 index 000000000..99057decc --- /dev/null +++ b/Backend/src/main/java/fredboat/backend/config/package-info.java @@ -0,0 +1,29 @@ +/* + * + * MIT License + * + * Copyright (c) 2017-2018 Frederik Ar. Mikkelsen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +@space.npstr.annotations.FieldsAreNonNullByDefault +@space.npstr.annotations.ParametersAreNonnullByDefault +@space.npstr.annotations.ReturnTypesAreNonNullByDefault +package fredboat.backend.config; diff --git a/Backend/src/main/java/fredboat/backend/package-info.java b/Backend/src/main/java/fredboat/backend/package-info.java new file mode 100644 index 000000000..dc82d6dde --- /dev/null +++ b/Backend/src/main/java/fredboat/backend/package-info.java @@ -0,0 +1,29 @@ +/* + * + * MIT License + * + * Copyright (c) 2017-2018 Frederik Ar. Mikkelsen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +@space.npstr.annotations.FieldsAreNonNullByDefault +@space.npstr.annotations.ParametersAreNonnullByDefault +@space.npstr.annotations.ReturnTypesAreNonNullByDefault +package fredboat.backend; diff --git a/Backend/src/main/java/fredboat/db/repos/impl/cache/SpringSearchResultRepo.java b/Backend/src/main/java/fredboat/db/repos/impl/cache/SpringSearchResultRepo.java new file mode 100644 index 000000000..de58b060a --- /dev/null +++ b/Backend/src/main/java/fredboat/db/repos/impl/cache/SpringSearchResultRepo.java @@ -0,0 +1,42 @@ +/* + * + * MIT License + * + * Copyright (c) 2017-2018 Frederik Ar. Mikkelsen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package fredboat.db.repos.impl.cache; + +import fredboat.db.entity.cache.SearchResult; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +import java.util.Optional; + +/** + * Created by napster on 16.02.18. + */ +@Repository +public interface SpringSearchResultRepo extends JpaRepository { + + @Override + Optional findById(SearchResult.SearchResultId searchResultId); +} diff --git a/Backend/src/main/java/fredboat/db/repos/impl/cache/package-info.java b/Backend/src/main/java/fredboat/db/repos/impl/cache/package-info.java new file mode 100644 index 000000000..dc908f691 --- /dev/null +++ b/Backend/src/main/java/fredboat/db/repos/impl/cache/package-info.java @@ -0,0 +1,29 @@ +/* + * + * MIT License + * + * Copyright (c) 2017-2018 Frederik Ar. Mikkelsen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +@space.npstr.annotations.FieldsAreNonNullByDefault +@space.npstr.annotations.ParametersAreNonnullByDefault +@space.npstr.annotations.ReturnTypesAreNonNullByDefault +package fredboat.db.repos.impl.cache; diff --git a/Backend/src/main/java/fredboat/db/repos/impl/main/SpringGuildConfigRepo.java b/Backend/src/main/java/fredboat/db/repos/impl/main/SpringGuildConfigRepo.java new file mode 100644 index 000000000..40cf58da9 --- /dev/null +++ b/Backend/src/main/java/fredboat/db/repos/impl/main/SpringGuildConfigRepo.java @@ -0,0 +1,42 @@ +/* + * + * MIT License + * + * Copyright (c) 2017-2018 Frederik Ar. Mikkelsen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package fredboat.db.repos.impl.main; + +import fredboat.db.entity.main.GuildConfig; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +import java.util.Optional; + +/** + * Created by napster on 16.02.18. + */ +@Repository +public interface SpringGuildConfigRepo extends JpaRepository { + + @Override + Optional findById(String id); +} diff --git a/Backend/src/main/java/fredboat/db/repos/impl/main/package-info.java b/Backend/src/main/java/fredboat/db/repos/impl/main/package-info.java new file mode 100644 index 000000000..c017307b1 --- /dev/null +++ b/Backend/src/main/java/fredboat/db/repos/impl/main/package-info.java @@ -0,0 +1,29 @@ +/* + * + * MIT License + * + * Copyright (c) 2017-2018 Frederik Ar. Mikkelsen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +@space.npstr.annotations.FieldsAreNonNullByDefault +@space.npstr.annotations.ParametersAreNonnullByDefault +@space.npstr.annotations.ReturnTypesAreNonNullByDefault +package fredboat.db.repos.impl.main; diff --git a/Backend/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/Backend/src/main/resources/META-INF/additional-spring-configuration-metadata.json new file mode 100644 index 000000000..6aa18ceb9 --- /dev/null +++ b/Backend/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -0,0 +1,14 @@ +{ + "properties": [ + { + "name": "fredboat.db.main.jdbcUrl", + "type": "java.lang.String", + "description": "Jdbc url of the main database including username and password." + }, + { + "name": "fredboat.db.cache.jdbcUrl", + "type": "java.lang.String", + "description": "Jdbc url of the cache database including username and password." + } + ] +} diff --git a/build.gradle b/build.gradle index f2f633e39..c58cedf53 100644 --- a/build.gradle +++ b/build.gradle @@ -78,6 +78,7 @@ subprojects { togglzVersion = '2.5.0.Final' guavaVersion = '24.0-jre' bucket4jVersion = '3.1.1' + gsonVersion = '2.8.2' //logging / monitoring deps logbackVersion = '1.2.3' diff --git a/settings.gradle b/settings.gradle index 1ec28b3b0..ec130b650 100644 --- a/settings.gradle +++ b/settings.gradle @@ -3,8 +3,10 @@ include ':FredBoat' include ':Bootloader' include ':Shared' include ':Database' +include ':Backend' project(':FredBoat').projectDir = "$rootDir/FredBoat" as File project(':Bootloader').projectDir = "$rootDir/Bootloader" as File project(':Shared').projectDir = "$rootDir/Shared" as File project(':Database').projectDir = "$rootDir/Database" as File +project(':Backend').projectDir = "$rootDir/Backend" as File From e782aacedde682f42bd722329874a224f24adc3e Mon Sep 17 00:00:00 2001 From: Napster Date: Wed, 28 Feb 2018 00:07:19 +0100 Subject: [PATCH 10/41] Add more comprehensive error logs about empty jdbc urls --- Database/src/main/java/fredboat/db/DatabaseManager.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Database/src/main/java/fredboat/db/DatabaseManager.java b/Database/src/main/java/fredboat/db/DatabaseManager.java index 279a87349..00bfc7c4b 100644 --- a/Database/src/main/java/fredboat/db/DatabaseManager.java +++ b/Database/src/main/java/fredboat/db/DatabaseManager.java @@ -106,6 +106,13 @@ public DatabaseManager(@Nullable HibernateStatisticsCollector hibernateStats, this.cacheJdbc = cacheJdbc; this.cacheTunnel = cacheTunnel; this.entityManagerFactoryBuilder = entityManagerFactoryBuilder; + + if (mainJdbc.isEmpty()) { + log.error("Main jdbc url is empty - database creation will fail"); + } + if (cacheJdbc != null && cacheJdbc.isEmpty()) { + log.error("Cache jdbc url is empty - database creation will fail"); + } } public DatabaseConnection getMainDbConn() { From aee8ff0ff43ab5b72e0105ac8a71133fd9bd8482 Mon Sep 17 00:00:00 2001 From: Napster Date: Sat, 17 Feb 2018 02:45:03 +0100 Subject: [PATCH 11/41] Basic proof of concept rest repo implementation --- Backend/application.yml.example | 4 + Backend/build.gradle | 10 +- .../java/fredboat/backend/Application.java | 2 + .../java/fredboat/backend/DbController.java | 80 -------------- .../backend/GuildConfigController.java | 74 +++++++++++++ .../fredboat/backend/config/DbConfig.java | 16 ++- .../impl/cache/SpringSearchResultRepo.java | 42 ------- .../db/repos/impl/cache/package-info.java | 29 ----- .../db/repos/impl/main/package-info.java | 29 ----- Database/build.gradle | 2 + .../impl/RestGuildConfigRepo.java | 17 ++- .../db/repositories/impl/RestRepo.java | 103 ++++++++++++++++++ .../main/java/fredboat/util/rest/Http.java | 8 ++ 13 files changed, 219 insertions(+), 197 deletions(-) delete mode 100644 Backend/src/main/java/fredboat/backend/DbController.java create mode 100644 Backend/src/main/java/fredboat/backend/GuildConfigController.java delete mode 100644 Backend/src/main/java/fredboat/db/repos/impl/cache/SpringSearchResultRepo.java delete mode 100644 Backend/src/main/java/fredboat/db/repos/impl/cache/package-info.java delete mode 100644 Backend/src/main/java/fredboat/db/repos/impl/main/package-info.java rename Backend/src/main/java/fredboat/db/repos/impl/main/SpringGuildConfigRepo.java => Database/src/main/java/fredboat/db/repositories/impl/RestGuildConfigRepo.java (76%) create mode 100644 Database/src/main/java/fredboat/db/repositories/impl/RestRepo.java diff --git a/Backend/application.yml.example b/Backend/application.yml.example index 0da71ecb0..e6f593361 100644 --- a/Backend/application.yml.example +++ b/Backend/application.yml.example @@ -1,3 +1,7 @@ +spring: + http: + converters: + preferred-json-mapper: gson fredboat: db: main: diff --git a/Backend/build.gradle b/Backend/build.gradle index 572e0f340..1b00deeec 100644 --- a/Backend/build.gradle +++ b/Backend/build.gradle @@ -1,7 +1,6 @@ apply plugin: 'propdeps' apply plugin: 'propdeps-idea' apply plugin: 'org.springframework.boot' -apply plugin: 'io.spring.dependency-management' description = 'FredBoat backend, providing REST database services' @@ -13,13 +12,12 @@ ext { dependencies { compile project(':Database') - compile group: 'com.google.code.gson', name: 'gson', version: gsonVersion //versioning is handled by spring - compile "org.springframework.boot:spring-boot-starter-data-jpa" - compile "org.springframework.boot:spring-boot-starter-data-rest" - testCompile "org.springframework.boot:spring-boot-starter-test" - optional "org.springframework.boot:spring-boot-configuration-processor" + compile "org.springframework.boot:spring-boot-starter-data-jpa:$springBootVersion" + compile "org.springframework.boot:spring-boot-starter-web:$springBootVersion" + testCompile "org.springframework.boot:spring-boot-starter-test:$springBootVersion" + optional "org.springframework.boot:spring-boot-configuration-processor:$springBootVersion" } //required by spring boot configuration processor diff --git a/Backend/src/main/java/fredboat/backend/Application.java b/Backend/src/main/java/fredboat/backend/Application.java index c3810e841..c209d4973 100644 --- a/Backend/src/main/java/fredboat/backend/Application.java +++ b/Backend/src/main/java/fredboat/backend/Application.java @@ -45,6 +45,8 @@ }) public class Application { + public static final String API_VERSION = "v1"; + public static void main(String[] args) { SpringApplication.run(Application.class, args); } diff --git a/Backend/src/main/java/fredboat/backend/DbController.java b/Backend/src/main/java/fredboat/backend/DbController.java deleted file mode 100644 index ef93db3df..000000000 --- a/Backend/src/main/java/fredboat/backend/DbController.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * - * MIT License - * - * Copyright (c) 2017-2018 Frederik Ar. Mikkelsen - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package fredboat.backend; - -import com.google.gson.Gson; -import fredboat.db.entity.main.GuildConfig; -import fredboat.db.repos.impl.cache.SpringSearchResultRepo; -import fredboat.db.repos.impl.main.SpringGuildConfigRepo; -import org.hibernate.internal.util.ReflectHelper; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; -import space.npstr.sqlsauce.DatabaseException; -import space.npstr.sqlsauce.entities.SaucedEntity; -import space.npstr.sqlsauce.fp.types.EntityKey; - -import javax.annotation.CheckReturnValue; -import java.io.Serializable; -import java.lang.reflect.Constructor; - -/** - * Created by napster on 16.02.18. - */ -@RestController -public class DbController { - - private final SpringGuildConfigRepo guildConfigRepo; - private final SpringSearchResultRepo searchResultRepo; - private final Gson gson = new Gson(); - - public DbController(SpringGuildConfigRepo guildConfigRepo, - SpringSearchResultRepo searchResultRepo) { - - this.guildConfigRepo = guildConfigRepo; - this.searchResultRepo = searchResultRepo; - } - - @RequestMapping("/main/guildconfig/{id}") - public String guildConfig(@PathVariable("id") String id) { - GuildConfig gc = guildConfigRepo.findById(id).orElse(newInstance(EntityKey.of(id, GuildConfig.class))); - return gson.toJson(gc); - } - - - @CheckReturnValue - private static , I extends Serializable> E newInstance(final EntityKey id) { - try { - Constructor constructor = ReflectHelper.getDefaultConstructor(id.clazz); - final E entity = constructor.newInstance((Object[]) null); - return entity.setId(id.id); - } catch (final ReflectiveOperationException e) { - final String message = String.format("Could not construct an entity of class %s with id %s", - id.clazz.getName(), id.toString()); - throw new DatabaseException(message, e); - } - } -} diff --git a/Backend/src/main/java/fredboat/backend/GuildConfigController.java b/Backend/src/main/java/fredboat/backend/GuildConfigController.java new file mode 100644 index 000000000..7a2cfb2f7 --- /dev/null +++ b/Backend/src/main/java/fredboat/backend/GuildConfigController.java @@ -0,0 +1,74 @@ +/* + * + * MIT License + * + * Copyright (c) 2017-2018 Frederik Ar. Mikkelsen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package fredboat.backend; + +import fredboat.db.entity.main.GuildConfig; +import fredboat.db.repositories.impl.SqlSauceGuildConfigRepo; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.web.bind.annotation.*; +import space.npstr.sqlsauce.DatabaseWrapper; + +import javax.annotation.Nullable; + +/** + * Created by napster on 17.02.18. + */ +@RestController +public class GuildConfigController extends SqlSauceGuildConfigRepo { + + private static final String ROUTE = "/" + Application.API_VERSION + "/guildconfig"; + + @Autowired + public GuildConfigController(@Qualifier("mainDbWrapper") DatabaseWrapper dbWrapper) { + super(dbWrapper); + } + + @GetMapping(ROUTE + "/get/{guildId}") + @Nullable + @Override + public GuildConfig get(@PathVariable("guildId") String id) { + return super.get(id); + } + + @DeleteMapping(ROUTE + "/delete/{guildId}") + @Override + public void delete(@PathVariable("guildId") String id) { + super.delete(id); + } + + @GetMapping(ROUTE + "/fetch/{guildId}") + @Override + public GuildConfig fetch(@PathVariable("guildId") String id) { + return super.fetch(id); + } + + @PostMapping(ROUTE + "/merge") + @Override + public GuildConfig merge(@RequestBody GuildConfig entity) { + return super.merge(entity); + } +} diff --git a/Backend/src/main/java/fredboat/backend/config/DbConfig.java b/Backend/src/main/java/fredboat/backend/config/DbConfig.java index 046975d3f..364853e75 100644 --- a/Backend/src/main/java/fredboat/backend/config/DbConfig.java +++ b/Backend/src/main/java/fredboat/backend/config/DbConfig.java @@ -34,6 +34,9 @@ import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; import org.springframework.stereotype.Component; +import space.npstr.sqlsauce.DatabaseWrapper; + +import javax.annotation.Nullable; /** * Created by napster on 16.02.18. @@ -44,7 +47,7 @@ public class DbConfig { @Bean("databaseManager") @Scope(ConfigurableBeanFactory.SCOPE_SINGLETON) - DatabaseManager getDatabaseManager(DbConfig dbConfig) { + public DatabaseManager getDatabaseManager(DbConfig dbConfig) { //todo improve these parameters return new DatabaseManager(null, null, 4, "Backend", true, @@ -64,6 +67,17 @@ DatabaseManager getDatabaseManager(DbConfig dbConfig) { }); } + @Bean("mainDbWrapper") + public DatabaseWrapper getMainDbWrapper(DatabaseManager databaseManager) { + return databaseManager.getMainDbWrapper(); + } + + @Nullable + @Bean("cacheDbWrapper") + public DatabaseWrapper getCacheDbWrapper(DatabaseManager databaseManager) { + return databaseManager.getCacheDbWrapper(); + } + private final Main main = new Main(); public Main getMain() { diff --git a/Backend/src/main/java/fredboat/db/repos/impl/cache/SpringSearchResultRepo.java b/Backend/src/main/java/fredboat/db/repos/impl/cache/SpringSearchResultRepo.java deleted file mode 100644 index de58b060a..000000000 --- a/Backend/src/main/java/fredboat/db/repos/impl/cache/SpringSearchResultRepo.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * - * MIT License - * - * Copyright (c) 2017-2018 Frederik Ar. Mikkelsen - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package fredboat.db.repos.impl.cache; - -import fredboat.db.entity.cache.SearchResult; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.stereotype.Repository; - -import java.util.Optional; - -/** - * Created by napster on 16.02.18. - */ -@Repository -public interface SpringSearchResultRepo extends JpaRepository { - - @Override - Optional findById(SearchResult.SearchResultId searchResultId); -} diff --git a/Backend/src/main/java/fredboat/db/repos/impl/cache/package-info.java b/Backend/src/main/java/fredboat/db/repos/impl/cache/package-info.java deleted file mode 100644 index dc908f691..000000000 --- a/Backend/src/main/java/fredboat/db/repos/impl/cache/package-info.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * - * MIT License - * - * Copyright (c) 2017-2018 Frederik Ar. Mikkelsen - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -@space.npstr.annotations.FieldsAreNonNullByDefault -@space.npstr.annotations.ParametersAreNonnullByDefault -@space.npstr.annotations.ReturnTypesAreNonNullByDefault -package fredboat.db.repos.impl.cache; diff --git a/Backend/src/main/java/fredboat/db/repos/impl/main/package-info.java b/Backend/src/main/java/fredboat/db/repos/impl/main/package-info.java deleted file mode 100644 index c017307b1..000000000 --- a/Backend/src/main/java/fredboat/db/repos/impl/main/package-info.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * - * MIT License - * - * Copyright (c) 2017-2018 Frederik Ar. Mikkelsen - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -@space.npstr.annotations.FieldsAreNonNullByDefault -@space.npstr.annotations.ParametersAreNonnullByDefault -@space.npstr.annotations.ReturnTypesAreNonNullByDefault -package fredboat.db.repos.impl.main; diff --git a/Database/build.gradle b/Database/build.gradle index 7c9b3b686..107e387ba 100644 --- a/Database/build.gradle +++ b/Database/build.gradle @@ -15,4 +15,6 @@ dependencies { compile group: 'org.flywaydb', name: 'flyway-core', version: flywayVersion compile group: 'net.ttddyy', name: 'datasource-proxy', version: dsProxyVersion compile group: 'javax.xml.bind', name: 'jaxb-api', version: jaxbApiVersion // required by hibernate for java 9 + + compile group: 'com.google.code.gson', name: 'gson', version: gsonVersion } diff --git a/Backend/src/main/java/fredboat/db/repos/impl/main/SpringGuildConfigRepo.java b/Database/src/main/java/fredboat/db/repositories/impl/RestGuildConfigRepo.java similarity index 76% rename from Backend/src/main/java/fredboat/db/repos/impl/main/SpringGuildConfigRepo.java rename to Database/src/main/java/fredboat/db/repositories/impl/RestGuildConfigRepo.java index 40cf58da9..777d54ed3 100644 --- a/Backend/src/main/java/fredboat/db/repos/impl/main/SpringGuildConfigRepo.java +++ b/Database/src/main/java/fredboat/db/repositories/impl/RestGuildConfigRepo.java @@ -23,20 +23,17 @@ * SOFTWARE. */ -package fredboat.db.repos.impl.main; +package fredboat.db.repositories.impl; import fredboat.db.entity.main.GuildConfig; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.stereotype.Repository; - -import java.util.Optional; +import fredboat.db.repositories.api.GuildConfigRepo; /** - * Created by napster on 16.02.18. + * Created by napster on 17.02.18. */ -@Repository -public interface SpringGuildConfigRepo extends JpaRepository { +public class RestGuildConfigRepo extends RestRepo implements GuildConfigRepo { - @Override - Optional findById(String id); + public RestGuildConfigRepo(String path) { + super(path, GuildConfig.class); + } } diff --git a/Database/src/main/java/fredboat/db/repositories/impl/RestRepo.java b/Database/src/main/java/fredboat/db/repositories/impl/RestRepo.java new file mode 100644 index 000000000..f832c0866 --- /dev/null +++ b/Database/src/main/java/fredboat/db/repositories/impl/RestRepo.java @@ -0,0 +1,103 @@ +/* + * + * MIT License + * + * Copyright (c) 2017-2018 Frederik Ar. Mikkelsen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package fredboat.db.repositories.impl; + +import com.google.gson.Gson; +import fredboat.db.repositories.api.Repo; +import fredboat.util.rest.Http; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import space.npstr.sqlsauce.entities.SaucedEntity; + +import javax.annotation.Nullable; +import java.io.IOException; +import java.io.Serializable; + +/** + * Created by napster on 17.02.18. + */ +public abstract class RestRepo> implements Repo { + + private static final Logger log = LoggerFactory.getLogger(RestRepo.class); + + protected final String path; + protected final Class entityClass; + protected final Http http; + protected final Gson gson; + + public RestRepo(String path, Class entityClass) { + this.path = path; + this.entityClass = entityClass; + this.http = new Http(Http.DEFAULT_BUILDER.newBuilder().build()); //todo add metrics? + this.gson = new Gson(); + } + + public Class getEntityClass() { + return entityClass; + } + + @Nullable + @Override + public E get(I id) { + try { + return gson.fromJson(http.get(path + "/get/" + id).asString(), entityClass); + } catch (IOException e) { //todo decide on error handling strategy + log.error("Could not GET entity with id {} of class {}", id, entityClass, e); + return null; + } + } + + @Override + public void delete(I id) { + try { + //noinspection ResultOfMethodCallIgnored + http.delete(path + "/delete/" + id).execute(); + } catch (IOException e) { //todo decide on error handling strategy + log.error("Could not DELETE entity with id {} of class {}", id, entityClass, e); + } + } + + @Override + public E fetch(I id) { + try { + return gson.fromJson(http.get(path + "/fetch/" + id).asString(), entityClass); + } catch (IOException e) { //todo decide on error handling strategy + log.error("Could not FETCH entity with id {} of class {}", id, entityClass, e); + return null; + } + } + + @Override + public E merge(E entity) { + try { + Http.SimpleRequest merge = http.post(path + "/merge/", gson.toJson(entity), "application/json"); + return gson.fromJson(merge.asString(), entityClass); + } catch (IOException e) { //todo decide on error handling strategy + log.error("Could not MERGE entity with id {} of class {}", entity.getId(), entityClass, e); + return null; + } + } +} diff --git a/Shared/src/main/java/fredboat/util/rest/Http.java b/Shared/src/main/java/fredboat/util/rest/Http.java index 6882c8d89..269193b68 100644 --- a/Shared/src/main/java/fredboat/util/rest/Http.java +++ b/Shared/src/main/java/fredboat/util/rest/Http.java @@ -92,6 +92,14 @@ public SimpleRequest get(@Nonnull String url) { .url(url)); } + @Nonnull + @CheckReturnValue + public SimpleRequest delete(@Nonnull String url) { + return new SimpleRequest(new Request.Builder() + .delete() + .url(url)); + } + @Nonnull @CheckReturnValue From daeb0d9f9e7018bb9b7c27ada9bf8397c89c03a6 Mon Sep 17 00:00:00 2001 From: Napster Date: Sat, 17 Feb 2018 18:19:17 +0100 Subject: [PATCH 12/41] Implement rest repositories --- .../impl/rest/RestBlacklistRepo.java | 60 ++++++++++++++++++ .../impl/{ => rest}/RestGuildConfigRepo.java | 10 ++- .../impl/rest/RestGuildDataRepo.java | 43 +++++++++++++ .../impl/rest/RestGuildModulesRepo.java | 43 +++++++++++++ .../impl/rest/RestGuildPermsRepo.java | 43 +++++++++++++ .../impl/rest/RestPrefixRepo.java | 61 +++++++++++++++++++ .../impl/{ => rest}/RestRepo.java | 25 +++++--- .../impl/rest/RestSearchResultRepo.java | 60 ++++++++++++++++++ .../repositories/impl/rest/package-info.java | 29 +++++++++ 9 files changed, 361 insertions(+), 13 deletions(-) create mode 100644 Database/src/main/java/fredboat/db/repositories/impl/rest/RestBlacklistRepo.java rename Database/src/main/java/fredboat/db/repositories/impl/{ => rest}/RestGuildConfigRepo.java (82%) create mode 100644 Database/src/main/java/fredboat/db/repositories/impl/rest/RestGuildDataRepo.java create mode 100644 Database/src/main/java/fredboat/db/repositories/impl/rest/RestGuildModulesRepo.java create mode 100644 Database/src/main/java/fredboat/db/repositories/impl/rest/RestGuildPermsRepo.java create mode 100644 Database/src/main/java/fredboat/db/repositories/impl/rest/RestPrefixRepo.java rename Database/src/main/java/fredboat/db/repositories/impl/{ => rest}/RestRepo.java (76%) create mode 100644 Database/src/main/java/fredboat/db/repositories/impl/rest/RestSearchResultRepo.java create mode 100644 Database/src/main/java/fredboat/db/repositories/impl/rest/package-info.java diff --git a/Database/src/main/java/fredboat/db/repositories/impl/rest/RestBlacklistRepo.java b/Database/src/main/java/fredboat/db/repositories/impl/rest/RestBlacklistRepo.java new file mode 100644 index 000000000..7b6af1836 --- /dev/null +++ b/Database/src/main/java/fredboat/db/repositories/impl/rest/RestBlacklistRepo.java @@ -0,0 +1,60 @@ +/* + * + * MIT License + * + * Copyright (c) 2017-2018 Frederik Ar. Mikkelsen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package fredboat.db.repositories.impl.rest; + +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; +import fredboat.db.entity.main.BlacklistEntry; +import fredboat.db.repositories.api.BlacklistRepo; +import fredboat.util.rest.Http; + +import java.io.IOException; +import java.util.Collections; +import java.util.List; + +/** + * Created by napster on 17.02.18. + */ +public class RestBlacklistRepo extends RestRepo implements BlacklistRepo { + + public static final String PATH = "/blacklist"; + + public RestBlacklistRepo(String apiBasePath, Http http, Gson gson) { + super(apiBasePath + PATH, BlacklistEntry.class, http, gson); + } + + @Override + public List loadBlacklist() { + try { + Http.SimpleRequest get = http.get(path + "/loadall"); + return gson.fromJson(get.asString(), new TypeToken>() { + }.getType()); + } catch (IOException e) { //todo decide on error handling strategy + log.error("Could not load the blacklist", e); + return Collections.emptyList(); + } + } +} diff --git a/Database/src/main/java/fredboat/db/repositories/impl/RestGuildConfigRepo.java b/Database/src/main/java/fredboat/db/repositories/impl/rest/RestGuildConfigRepo.java similarity index 82% rename from Database/src/main/java/fredboat/db/repositories/impl/RestGuildConfigRepo.java rename to Database/src/main/java/fredboat/db/repositories/impl/rest/RestGuildConfigRepo.java index 777d54ed3..7b05a16a9 100644 --- a/Database/src/main/java/fredboat/db/repositories/impl/RestGuildConfigRepo.java +++ b/Database/src/main/java/fredboat/db/repositories/impl/rest/RestGuildConfigRepo.java @@ -23,17 +23,21 @@ * SOFTWARE. */ -package fredboat.db.repositories.impl; +package fredboat.db.repositories.impl.rest; +import com.google.gson.Gson; import fredboat.db.entity.main.GuildConfig; import fredboat.db.repositories.api.GuildConfigRepo; +import fredboat.util.rest.Http; /** * Created by napster on 17.02.18. */ public class RestGuildConfigRepo extends RestRepo implements GuildConfigRepo { - public RestGuildConfigRepo(String path) { - super(path, GuildConfig.class); + public static final String PATH = "/guildconfig"; + + public RestGuildConfigRepo(String apiBasePath, Http http, Gson gson) { + super(apiBasePath + PATH, GuildConfig.class, http, gson); } } diff --git a/Database/src/main/java/fredboat/db/repositories/impl/rest/RestGuildDataRepo.java b/Database/src/main/java/fredboat/db/repositories/impl/rest/RestGuildDataRepo.java new file mode 100644 index 000000000..ff8401a34 --- /dev/null +++ b/Database/src/main/java/fredboat/db/repositories/impl/rest/RestGuildDataRepo.java @@ -0,0 +1,43 @@ +/* + * + * MIT License + * + * Copyright (c) 2017-2018 Frederik Ar. Mikkelsen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package fredboat.db.repositories.impl.rest; + +import com.google.gson.Gson; +import fredboat.db.entity.main.GuildData; +import fredboat.db.repositories.api.GuildDataRepo; +import fredboat.util.rest.Http; + +/** + * Created by napster on 17.02.18. + */ +public class RestGuildDataRepo extends RestRepo implements GuildDataRepo { + + public static final String PATH = "/guilddata"; + + public RestGuildDataRepo(String apiBasePath, Http http, Gson gson) { + super(apiBasePath + PATH, GuildData.class, http, gson); + } +} diff --git a/Database/src/main/java/fredboat/db/repositories/impl/rest/RestGuildModulesRepo.java b/Database/src/main/java/fredboat/db/repositories/impl/rest/RestGuildModulesRepo.java new file mode 100644 index 000000000..090e85201 --- /dev/null +++ b/Database/src/main/java/fredboat/db/repositories/impl/rest/RestGuildModulesRepo.java @@ -0,0 +1,43 @@ +/* + * + * MIT License + * + * Copyright (c) 2017-2018 Frederik Ar. Mikkelsen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package fredboat.db.repositories.impl.rest; + +import com.google.gson.Gson; +import fredboat.db.entity.main.GuildModules; +import fredboat.db.repositories.api.GuildModulesRepo; +import fredboat.util.rest.Http; + +/** + * Created by napster on 17.02.18. + */ +public class RestGuildModulesRepo extends RestRepo implements GuildModulesRepo { + + public static final String PATH = "/guildmodules"; + + public RestGuildModulesRepo(String apiBasePath, Http http, Gson gson) { + super(apiBasePath + PATH, GuildModules.class, http, gson); + } +} diff --git a/Database/src/main/java/fredboat/db/repositories/impl/rest/RestGuildPermsRepo.java b/Database/src/main/java/fredboat/db/repositories/impl/rest/RestGuildPermsRepo.java new file mode 100644 index 000000000..868f0a48e --- /dev/null +++ b/Database/src/main/java/fredboat/db/repositories/impl/rest/RestGuildPermsRepo.java @@ -0,0 +1,43 @@ +/* + * + * MIT License + * + * Copyright (c) 2017-2018 Frederik Ar. Mikkelsen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package fredboat.db.repositories.impl.rest; + +import com.google.gson.Gson; +import fredboat.db.entity.main.GuildPermissions; +import fredboat.db.repositories.api.GuildPermsRepo; +import fredboat.util.rest.Http; + +/** + * Created by napster on 17.02.18. + */ +public class RestGuildPermsRepo extends RestRepo implements GuildPermsRepo { + + public static final String PATH = "/guildperms"; + + public RestGuildPermsRepo(String apiBasePath, Http http, Gson gson) { + super(apiBasePath + PATH, GuildPermissions.class, http, gson); + } +} diff --git a/Database/src/main/java/fredboat/db/repositories/impl/rest/RestPrefixRepo.java b/Database/src/main/java/fredboat/db/repositories/impl/rest/RestPrefixRepo.java new file mode 100644 index 000000000..74f7a5052 --- /dev/null +++ b/Database/src/main/java/fredboat/db/repositories/impl/rest/RestPrefixRepo.java @@ -0,0 +1,61 @@ +/* + * + * MIT License + * + * Copyright (c) 2017-2018 Frederik Ar. Mikkelsen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package fredboat.db.repositories.impl.rest; + +import com.google.gson.Gson; +import fredboat.db.entity.main.Prefix; +import fredboat.db.repositories.api.PrefixRepo; +import fredboat.util.rest.Http; +import space.npstr.sqlsauce.entities.GuildBotComposite; + +import javax.annotation.Nullable; +import java.io.IOException; + +/** + * Created by napster on 17.02.18. + */ +public class RestPrefixRepo extends RestRepo implements PrefixRepo { + + public static final String PATH = "/prefix"; + + public RestPrefixRepo(String apiBasePath, Http http, Gson gson) { + super(apiBasePath + PATH, Prefix.class, http, gson); + } + + @Nullable + @Override + public String getPrefix(GuildBotComposite id) { + try { + String payload = gson.toJson(id); + log.debug("Payload: " + payload); + Http.SimpleRequest getRaw = http.post(path + "/getraw", payload, "application/json"); + return gson.fromJson(getRaw.asString(), String.class); + } catch (IOException e) { //todo decide on error handling strategy + log.error("Could not get raw prefix", e); + return null; + } + } +} diff --git a/Database/src/main/java/fredboat/db/repositories/impl/RestRepo.java b/Database/src/main/java/fredboat/db/repositories/impl/rest/RestRepo.java similarity index 76% rename from Database/src/main/java/fredboat/db/repositories/impl/RestRepo.java rename to Database/src/main/java/fredboat/db/repositories/impl/rest/RestRepo.java index f832c0866..4122c7ad7 100644 --- a/Database/src/main/java/fredboat/db/repositories/impl/RestRepo.java +++ b/Database/src/main/java/fredboat/db/repositories/impl/rest/RestRepo.java @@ -23,7 +23,7 @@ * SOFTWARE. */ -package fredboat.db.repositories.impl; +package fredboat.db.repositories.impl.rest; import com.google.gson.Gson; import fredboat.db.repositories.api.Repo; @@ -38,21 +38,23 @@ /** * Created by napster on 17.02.18. + * + * Counterpart to the EntityController of the Backend module. */ public abstract class RestRepo> implements Repo { - private static final Logger log = LoggerFactory.getLogger(RestRepo.class); + protected static final Logger log = LoggerFactory.getLogger(RestRepo.class); protected final String path; protected final Class entityClass; protected final Http http; protected final Gson gson; - public RestRepo(String path, Class entityClass) { + public RestRepo(String path, Class entityClass, Http http, Gson gson) { this.path = path; this.entityClass = entityClass; - this.http = new Http(Http.DEFAULT_BUILDER.newBuilder().build()); //todo add metrics? - this.gson = new Gson(); + this.http = http; + this.gson = gson; } public Class getEntityClass() { @@ -63,7 +65,8 @@ public Class getEntityClass() { @Override public E get(I id) { try { - return gson.fromJson(http.get(path + "/get/" + id).asString(), entityClass); + Http.SimpleRequest get = http.post(path + "/get", gson.toJson(id), "application/json"); + return gson.fromJson(get.asString(), entityClass); } catch (IOException e) { //todo decide on error handling strategy log.error("Could not GET entity with id {} of class {}", id, entityClass, e); return null; @@ -71,10 +74,11 @@ public E get(I id) { } @Override - public void delete(I id) { + public void delete(I id) { //todo success handling? try { + Http.SimpleRequest delete = http.post(path + "/delete", gson.toJson(id), "application/json"); //noinspection ResultOfMethodCallIgnored - http.delete(path + "/delete/" + id).execute(); + delete.execute(); } catch (IOException e) { //todo decide on error handling strategy log.error("Could not DELETE entity with id {} of class {}", id, entityClass, e); } @@ -83,7 +87,8 @@ public void delete(I id) { @Override public E fetch(I id) { try { - return gson.fromJson(http.get(path + "/fetch/" + id).asString(), entityClass); + Http.SimpleRequest fetch = http.post(path + "/fetch", gson.toJson(id), "application/json"); + return gson.fromJson(fetch.asString(), entityClass); } catch (IOException e) { //todo decide on error handling strategy log.error("Could not FETCH entity with id {} of class {}", id, entityClass, e); return null; @@ -93,7 +98,7 @@ public E fetch(I id) { @Override public E merge(E entity) { try { - Http.SimpleRequest merge = http.post(path + "/merge/", gson.toJson(entity), "application/json"); + Http.SimpleRequest merge = http.post(path + "/merge", gson.toJson(entity), "application/json"); return gson.fromJson(merge.asString(), entityClass); } catch (IOException e) { //todo decide on error handling strategy log.error("Could not MERGE entity with id {} of class {}", entity.getId(), entityClass, e); diff --git a/Database/src/main/java/fredboat/db/repositories/impl/rest/RestSearchResultRepo.java b/Database/src/main/java/fredboat/db/repositories/impl/rest/RestSearchResultRepo.java new file mode 100644 index 000000000..148cfc1e2 --- /dev/null +++ b/Database/src/main/java/fredboat/db/repositories/impl/rest/RestSearchResultRepo.java @@ -0,0 +1,60 @@ +/* + * + * MIT License + * + * Copyright (c) 2017-2018 Frederik Ar. Mikkelsen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package fredboat.db.repositories.impl.rest; + +import com.google.gson.Gson; +import fredboat.db.entity.cache.SearchResult; +import fredboat.db.repositories.api.SearchResultRepo; +import fredboat.util.rest.Http; + +import javax.annotation.Nullable; +import java.io.IOException; + +/** + * Created by napster on 17.02.18. + */ +public class RestSearchResultRepo extends RestRepo implements SearchResultRepo { + + public static final String PATH = "/searchresult"; + + public RestSearchResultRepo(String apiBasePath, Http http, Gson gson) { + super(apiBasePath + PATH, SearchResult.class, http, gson); + } + + @Nullable + @Override + public SearchResult getMaxAged(SearchResult.SearchResultId id, long maxAgeMillis) { + try { + String url = path + "/getmaxaged"; + Http.SimpleRequest getMaxAged = http.post(url, gson.toJson(id), "application/json") + .url(url, Http.Params.of("millis", Long.toString(maxAgeMillis))); + return gson.fromJson(getMaxAged.asString(), SearchResult.class); + } catch (IOException e) { //todo decide on error handling strategy + log.error("Could not get search result", e); + return null; + } + } +} diff --git a/Database/src/main/java/fredboat/db/repositories/impl/rest/package-info.java b/Database/src/main/java/fredboat/db/repositories/impl/rest/package-info.java new file mode 100644 index 000000000..1bddf5981 --- /dev/null +++ b/Database/src/main/java/fredboat/db/repositories/impl/rest/package-info.java @@ -0,0 +1,29 @@ +/* + * + * MIT License + * + * Copyright (c) 2017-2018 Frederik Ar. Mikkelsen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +@space.npstr.annotations.FieldsAreNonNullByDefault +@space.npstr.annotations.ParametersAreNonnullByDefault +@space.npstr.annotations.ReturnTypesAreNonNullByDefault +package fredboat.db.repositories.impl.rest; From fb204e3bef8837dd29227a00f970a7bf51dd6430 Mon Sep 17 00:00:00 2001 From: Napster Date: Sat, 17 Feb 2018 18:22:39 +0100 Subject: [PATCH 13/41] Add debug request logger --- .../backend/config/RequestLoggerConfig.java | 66 +++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 Backend/src/main/java/fredboat/backend/config/RequestLoggerConfig.java diff --git a/Backend/src/main/java/fredboat/backend/config/RequestLoggerConfig.java b/Backend/src/main/java/fredboat/backend/config/RequestLoggerConfig.java new file mode 100644 index 000000000..82531e608 --- /dev/null +++ b/Backend/src/main/java/fredboat/backend/config/RequestLoggerConfig.java @@ -0,0 +1,66 @@ +/* + * + * MIT License + * + * Copyright (c) 2017-2018 Frederik Ar. Mikkelsen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package fredboat.backend.config; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.filter.AbstractRequestLoggingFilter; + +import javax.servlet.http.HttpServletRequest; + +/** + * Created by napster on 17.02.18. + */ +@Configuration +public class RequestLoggerConfig { + + @Bean + public AbstractRequestLoggingFilter logFilter() { + RequestLogger filter = new RequestLogger(); + filter.setIncludeQueryString(true); + filter.setIncludePayload(true); + filter.setMaxPayloadLength(10000); + filter.setIncludeHeaders(true); + filter.setAfterMessagePrefix("REQUEST DATA : "); + return filter; + } + + private static class RequestLogger extends AbstractRequestLoggingFilter { + private static final Logger log = LoggerFactory.getLogger(RequestLogger.class); + + @Override + protected void beforeRequest(HttpServletRequest request, String message) { +// log.debug(message); + } + + @Override + protected void afterRequest(HttpServletRequest request, String message) { + log.debug(message); + } + } +} From d7fa1dda7438e93b58dbdab3a324c1e3905f8018 Mon Sep 17 00:00:00 2001 From: Napster Date: Sat, 17 Feb 2018 18:24:11 +0100 Subject: [PATCH 14/41] Clean up spring boot config stuff --- .../java/fredboat/backend/Application.java | 2 +- .../backend/GuildConfigController.java | 74 ------------------- .../backend/config/CacheDbConfig.java | 65 ---------------- .../fredboat/backend/config/DbConfig.java | 2 + .../fredboat/backend/config/MainDbConfig.java | 59 --------------- 5 files changed, 3 insertions(+), 199 deletions(-) delete mode 100644 Backend/src/main/java/fredboat/backend/GuildConfigController.java delete mode 100644 Backend/src/main/java/fredboat/backend/config/CacheDbConfig.java delete mode 100644 Backend/src/main/java/fredboat/backend/config/MainDbConfig.java diff --git a/Backend/src/main/java/fredboat/backend/Application.java b/Backend/src/main/java/fredboat/backend/Application.java index c209d4973..87c6b6acb 100644 --- a/Backend/src/main/java/fredboat/backend/Application.java +++ b/Backend/src/main/java/fredboat/backend/Application.java @@ -37,7 +37,7 @@ * Created by napster on 16.02.18. */ @SpringBootApplication -@EnableAutoConfiguration(exclude = { //we handle these ourselves +@EnableAutoConfiguration(exclude = { //we handle these ourselves via the DatabaseManager DataSourceAutoConfiguration.class, DataSourceTransactionManagerAutoConfiguration.class, HibernateJpaAutoConfiguration.class, diff --git a/Backend/src/main/java/fredboat/backend/GuildConfigController.java b/Backend/src/main/java/fredboat/backend/GuildConfigController.java deleted file mode 100644 index 7a2cfb2f7..000000000 --- a/Backend/src/main/java/fredboat/backend/GuildConfigController.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * - * MIT License - * - * Copyright (c) 2017-2018 Frederik Ar. Mikkelsen - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package fredboat.backend; - -import fredboat.db.entity.main.GuildConfig; -import fredboat.db.repositories.impl.SqlSauceGuildConfigRepo; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.web.bind.annotation.*; -import space.npstr.sqlsauce.DatabaseWrapper; - -import javax.annotation.Nullable; - -/** - * Created by napster on 17.02.18. - */ -@RestController -public class GuildConfigController extends SqlSauceGuildConfigRepo { - - private static final String ROUTE = "/" + Application.API_VERSION + "/guildconfig"; - - @Autowired - public GuildConfigController(@Qualifier("mainDbWrapper") DatabaseWrapper dbWrapper) { - super(dbWrapper); - } - - @GetMapping(ROUTE + "/get/{guildId}") - @Nullable - @Override - public GuildConfig get(@PathVariable("guildId") String id) { - return super.get(id); - } - - @DeleteMapping(ROUTE + "/delete/{guildId}") - @Override - public void delete(@PathVariable("guildId") String id) { - super.delete(id); - } - - @GetMapping(ROUTE + "/fetch/{guildId}") - @Override - public GuildConfig fetch(@PathVariable("guildId") String id) { - return super.fetch(id); - } - - @PostMapping(ROUTE + "/merge") - @Override - public GuildConfig merge(@RequestBody GuildConfig entity) { - return super.merge(entity); - } -} diff --git a/Backend/src/main/java/fredboat/backend/config/CacheDbConfig.java b/Backend/src/main/java/fredboat/backend/config/CacheDbConfig.java deleted file mode 100644 index 623947be1..000000000 --- a/Backend/src/main/java/fredboat/backend/config/CacheDbConfig.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * - * MIT License - * - * Copyright (c) 2017-2018 Frederik Ar. Mikkelsen - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package fredboat.backend.config; - -import fredboat.db.DatabaseManager; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.data.jpa.repository.config.EnableJpaRepositories; -import org.springframework.orm.jpa.JpaTransactionManager; -import org.springframework.transaction.PlatformTransactionManager; -import org.springframework.transaction.annotation.EnableTransactionManagement; -import space.npstr.sqlsauce.DatabaseConnection; - -import javax.annotation.Nullable; -import javax.persistence.EntityManagerFactory; - -/** - * Created by napster on 16.02.18. - */ -@Configuration -@EnableTransactionManagement -@EnableJpaRepositories( - entityManagerFactoryRef = "cacheEntityManagerFactory", - transactionManagerRef = "cacheTransactionManager", - basePackages = {"fredboat.db.repos.impl.cache"} -) -public class CacheDbConfig { - - @Nullable - @Bean(name = "cacheEntityManagerFactory") - public EntityManagerFactory cacheEntityManagerFactory(DatabaseManager databaseManager) { - DatabaseConnection databaseConnection = databaseManager.getCacheDbConn(); - return databaseConnection == null ? null : databaseConnection.getEntityManagerFactory(); - } - - @Bean(name = "cacheTransactionManager") - public PlatformTransactionManager cacheTransactionManager( - @Qualifier("cacheEntityManagerFactory") EntityManagerFactory cacheEntityManagerFactory) { - return new JpaTransactionManager(cacheEntityManagerFactory); - } -} diff --git a/Backend/src/main/java/fredboat/backend/config/DbConfig.java b/Backend/src/main/java/fredboat/backend/config/DbConfig.java index 364853e75..fb4085806 100644 --- a/Backend/src/main/java/fredboat/backend/config/DbConfig.java +++ b/Backend/src/main/java/fredboat/backend/config/DbConfig.java @@ -29,6 +29,7 @@ import org.springframework.beans.factory.config.ConfigurableBeanFactory; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Primary; import org.springframework.context.annotation.Scope; import org.springframework.orm.jpa.JpaVendorAdapter; import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; @@ -67,6 +68,7 @@ public DatabaseManager getDatabaseManager(DbConfig dbConfig) { }); } + @Primary @Bean("mainDbWrapper") public DatabaseWrapper getMainDbWrapper(DatabaseManager databaseManager) { return databaseManager.getMainDbWrapper(); diff --git a/Backend/src/main/java/fredboat/backend/config/MainDbConfig.java b/Backend/src/main/java/fredboat/backend/config/MainDbConfig.java deleted file mode 100644 index 17f7a7a87..000000000 --- a/Backend/src/main/java/fredboat/backend/config/MainDbConfig.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * - * MIT License - * - * Copyright (c) 2017-2018 Frederik Ar. Mikkelsen - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package fredboat.backend.config; - -import fredboat.db.DatabaseManager; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Primary; -import org.springframework.data.jpa.repository.config.EnableJpaRepositories; -import org.springframework.orm.jpa.JpaTransactionManager; -import org.springframework.transaction.PlatformTransactionManager; -import org.springframework.transaction.annotation.EnableTransactionManagement; - -import javax.persistence.EntityManagerFactory; - -/** - * Created by napster on 16.02.18. - */ -@Configuration -@EnableTransactionManagement -@EnableJpaRepositories(basePackages = {"fredboat.db.repos.impl.main"}) -public class MainDbConfig { - - @Primary - @Bean(name = "entityManagerFactory") - public EntityManagerFactory entityManagerFactory(DatabaseManager databaseManager) { - return databaseManager.getMainDbConn().getEntityManagerFactory(); - } - - @Primary - @Bean(name = "transactionManager") - public PlatformTransactionManager transactionManager(@Qualifier("entityManagerFactory") EntityManagerFactory entityManagerFactory) { - return new JpaTransactionManager(entityManagerFactory); - } -} From 3f890d215b098a8f64f615c572e2c6b10f58ad1a Mon Sep 17 00:00:00 2001 From: Napster Date: Sat, 17 Feb 2018 18:25:04 +0100 Subject: [PATCH 15/41] Add rest controllers --- .../java/fredboat/backend/Application.java | 52 +++++++++++++ .../backend/rest/BlacklistController.java | 57 ++++++++++++++ .../backend/rest/EntityController.java | 78 +++++++++++++++++++ .../backend/rest/GuildConfigController.java | 45 +++++++++++ .../backend/rest/GuildDataController.java | 45 +++++++++++ .../backend/rest/GuildModulesController.java | 45 +++++++++++ .../backend/rest/GuildPermsController.java | 45 +++++++++++ .../backend/rest/PrefixController.java | 60 ++++++++++++++ .../backend/rest/SearchResultController.java | 57 ++++++++++++++ .../fredboat/backend/rest/package-info.java | 29 +++++++ 10 files changed, 513 insertions(+) create mode 100644 Backend/src/main/java/fredboat/backend/rest/BlacklistController.java create mode 100644 Backend/src/main/java/fredboat/backend/rest/EntityController.java create mode 100644 Backend/src/main/java/fredboat/backend/rest/GuildConfigController.java create mode 100644 Backend/src/main/java/fredboat/backend/rest/GuildDataController.java create mode 100644 Backend/src/main/java/fredboat/backend/rest/GuildModulesController.java create mode 100644 Backend/src/main/java/fredboat/backend/rest/GuildPermsController.java create mode 100644 Backend/src/main/java/fredboat/backend/rest/PrefixController.java create mode 100644 Backend/src/main/java/fredboat/backend/rest/SearchResultController.java create mode 100644 Backend/src/main/java/fredboat/backend/rest/package-info.java diff --git a/Backend/src/main/java/fredboat/backend/Application.java b/Backend/src/main/java/fredboat/backend/Application.java index 87c6b6acb..794c47bea 100644 --- a/Backend/src/main/java/fredboat/backend/Application.java +++ b/Backend/src/main/java/fredboat/backend/Application.java @@ -25,6 +25,9 @@ package fredboat.backend; +import fredboat.db.repositories.api.*; +import fredboat.db.repositories.impl.*; +import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.SpringBootApplication; @@ -32,6 +35,9 @@ import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration; import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Primary; +import space.npstr.sqlsauce.DatabaseWrapper; /** * Created by napster on 16.02.18. @@ -50,4 +56,50 @@ public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } + + + //main db repos + @Bean + @Primary + public GuildConfigRepo guildConfigRepo(DatabaseWrapper wrapper) { + return new SqlSauceGuildConfigRepo(wrapper); + } + + @Bean + @Primary + public BlacklistRepo blacklistRepo(DatabaseWrapper wrapper) { + return new SqlSauceBlacklistRepo(wrapper); + } + + @Bean + @Primary + public GuildDataRepo guildDataRepo(DatabaseWrapper wrapper) { + return new SqlSauceGuildDataRepo(wrapper); + } + + @Bean + @Primary + public GuildModulesRepo guildModulesRepo(DatabaseWrapper wrapper) { + return new SqlSauceGuildModulesRepo(wrapper); + } + + @Bean + @Primary + public GuildPermsRepo guildPermsRepo(DatabaseWrapper wrapper) { + return new SqlSauceGuildPermsRepo(wrapper); + } + + @Bean + @Primary + public PrefixRepo prefixRepo(DatabaseWrapper wrapper) { + return new SqlSaucePrefixRepo(wrapper); + } + + + //cache db repos + @Bean + @Primary + public SearchResultRepo searchResultRepo(@Qualifier("cacheDbWrapper") DatabaseWrapper wrapper) { + return new SqlSauceSearchResultRepo(wrapper); + } } diff --git a/Backend/src/main/java/fredboat/backend/rest/BlacklistController.java b/Backend/src/main/java/fredboat/backend/rest/BlacklistController.java new file mode 100644 index 000000000..323acec32 --- /dev/null +++ b/Backend/src/main/java/fredboat/backend/rest/BlacklistController.java @@ -0,0 +1,57 @@ +/* + * + * MIT License + * + * Copyright (c) 2017-2018 Frederik Ar. Mikkelsen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package fredboat.backend.rest; + +import fredboat.backend.Application; +import fredboat.db.entity.main.BlacklistEntry; +import fredboat.db.repositories.api.BlacklistRepo; +import fredboat.db.repositories.impl.rest.RestBlacklistRepo; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; + +/** + * Created by napster on 17.02.18. + */ +@RestController +@RequestMapping("/" + Application.API_VERSION + RestBlacklistRepo.PATH) +public class BlacklistController extends EntityController implements BlacklistRepo { + + protected final BlacklistRepo blacklistRepo; + + public BlacklistController(BlacklistRepo repo) { + super(repo); + this.blacklistRepo = repo; + } + + @GetMapping("/loadall") + @Override + public List loadBlacklist() { + return blacklistRepo.loadBlacklist(); + } +} diff --git a/Backend/src/main/java/fredboat/backend/rest/EntityController.java b/Backend/src/main/java/fredboat/backend/rest/EntityController.java new file mode 100644 index 000000000..f9ec4abce --- /dev/null +++ b/Backend/src/main/java/fredboat/backend/rest/EntityController.java @@ -0,0 +1,78 @@ +/* + * + * MIT License + * + * Copyright (c) 2017-2018 Frederik Ar. Mikkelsen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package fredboat.backend.rest; + +import fredboat.db.repositories.api.Repo; +import fredboat.db.repositories.impl.rest.RestRepo; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import space.npstr.sqlsauce.entities.SaucedEntity; + +import javax.annotation.Nullable; +import java.io.Serializable; + +/** + * Created by napster on 17.02.18. + *

+ * Counterpart to the {@link RestRepo} + *

+ * Oh no, all those PostMappings are totally against Https/Rest principles...too bad that GET / DELETE do not support + * RequestBodies, and our Ids can be a bit more than a simple string / long. So they are passed as json as part of the + * body. + */ +public abstract class EntityController> implements Repo { + + protected final Repo repo; + + public EntityController(Repo repo) { + this.repo = repo; + } + + @Override + @PostMapping("/get") + @Nullable + public E get(@RequestBody I id) { + return repo.get(id); + } + + @Override + @PostMapping("/delete") + public void delete(@RequestBody I id) { + repo.delete(id); + } + + @Override + @PostMapping("/fetch") + public E fetch(@RequestBody I id) { + return repo.fetch(id); + } + + @Override + @PostMapping("/merge") + public E merge(@RequestBody E entity) { + return repo.merge(entity); + } +} diff --git a/Backend/src/main/java/fredboat/backend/rest/GuildConfigController.java b/Backend/src/main/java/fredboat/backend/rest/GuildConfigController.java new file mode 100644 index 000000000..7ddad89a5 --- /dev/null +++ b/Backend/src/main/java/fredboat/backend/rest/GuildConfigController.java @@ -0,0 +1,45 @@ +/* + * + * MIT License + * + * Copyright (c) 2017-2018 Frederik Ar. Mikkelsen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package fredboat.backend.rest; + +import fredboat.backend.Application; +import fredboat.db.entity.main.GuildConfig; +import fredboat.db.repositories.api.GuildConfigRepo; +import fredboat.db.repositories.impl.rest.RestGuildConfigRepo; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * Created by napster on 17.02.18. + */ +@RestController +@RequestMapping("/" + Application.API_VERSION + RestGuildConfigRepo.PATH) +public class GuildConfigController extends EntityController implements GuildConfigRepo { + + public GuildConfigController(GuildConfigRepo repo) { + super(repo); + } +} diff --git a/Backend/src/main/java/fredboat/backend/rest/GuildDataController.java b/Backend/src/main/java/fredboat/backend/rest/GuildDataController.java new file mode 100644 index 000000000..ec4049d47 --- /dev/null +++ b/Backend/src/main/java/fredboat/backend/rest/GuildDataController.java @@ -0,0 +1,45 @@ +/* + * + * MIT License + * + * Copyright (c) 2017-2018 Frederik Ar. Mikkelsen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package fredboat.backend.rest; + +import fredboat.backend.Application; +import fredboat.db.entity.main.GuildData; +import fredboat.db.repositories.api.GuildDataRepo; +import fredboat.db.repositories.impl.rest.RestGuildDataRepo; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * Created by napster on 17.02.18. + */ +@RestController +@RequestMapping("/" + Application.API_VERSION + RestGuildDataRepo.PATH) +public class GuildDataController extends EntityController implements GuildDataRepo { + + public GuildDataController(GuildDataRepo repo) { + super(repo); + } +} diff --git a/Backend/src/main/java/fredboat/backend/rest/GuildModulesController.java b/Backend/src/main/java/fredboat/backend/rest/GuildModulesController.java new file mode 100644 index 000000000..49c5b82b1 --- /dev/null +++ b/Backend/src/main/java/fredboat/backend/rest/GuildModulesController.java @@ -0,0 +1,45 @@ +/* + * + * MIT License + * + * Copyright (c) 2017-2018 Frederik Ar. Mikkelsen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package fredboat.backend.rest; + +import fredboat.backend.Application; +import fredboat.db.entity.main.GuildModules; +import fredboat.db.repositories.api.GuildModulesRepo; +import fredboat.db.repositories.impl.rest.RestGuildModulesRepo; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * Created by napster on 17.02.18. + */ +@RestController +@RequestMapping("/" + Application.API_VERSION + RestGuildModulesRepo.PATH) +public class GuildModulesController extends EntityController implements GuildModulesRepo { + + public GuildModulesController(GuildModulesRepo repo) { + super(repo); + } +} diff --git a/Backend/src/main/java/fredboat/backend/rest/GuildPermsController.java b/Backend/src/main/java/fredboat/backend/rest/GuildPermsController.java new file mode 100644 index 000000000..f23b00347 --- /dev/null +++ b/Backend/src/main/java/fredboat/backend/rest/GuildPermsController.java @@ -0,0 +1,45 @@ +/* + * + * MIT License + * + * Copyright (c) 2017-2018 Frederik Ar. Mikkelsen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package fredboat.backend.rest; + +import fredboat.backend.Application; +import fredboat.db.entity.main.GuildPermissions; +import fredboat.db.repositories.api.GuildPermsRepo; +import fredboat.db.repositories.impl.rest.RestGuildPermsRepo; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * Created by napster on 17.02.18. + */ +@RestController +@RequestMapping("/" + Application.API_VERSION + RestGuildPermsRepo.PATH) +public class GuildPermsController extends EntityController implements GuildPermsRepo { + + public GuildPermsController(GuildPermsRepo repo) { + super(repo); + } +} diff --git a/Backend/src/main/java/fredboat/backend/rest/PrefixController.java b/Backend/src/main/java/fredboat/backend/rest/PrefixController.java new file mode 100644 index 000000000..b53fb27df --- /dev/null +++ b/Backend/src/main/java/fredboat/backend/rest/PrefixController.java @@ -0,0 +1,60 @@ +/* + * + * MIT License + * + * Copyright (c) 2017-2018 Frederik Ar. Mikkelsen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package fredboat.backend.rest; + +import fredboat.backend.Application; +import fredboat.db.entity.main.Prefix; +import fredboat.db.repositories.api.PrefixRepo; +import fredboat.db.repositories.impl.rest.RestPrefixRepo; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import space.npstr.sqlsauce.entities.GuildBotComposite; + +import javax.annotation.Nullable; + +/** + * Created by napster on 17.02.18. + */ +@RestController +@RequestMapping("/" + Application.API_VERSION + RestPrefixRepo.PATH) +public class PrefixController extends EntityController implements PrefixRepo { + + protected final PrefixRepo prefixRepo; + + public PrefixController(PrefixRepo repo) { + super(repo); + this.prefixRepo = repo; + } + + @Nullable + @PostMapping("/getraw") + @Override + public String getPrefix(@RequestBody GuildBotComposite id) { + return prefixRepo.getPrefix(id); + } +} diff --git a/Backend/src/main/java/fredboat/backend/rest/SearchResultController.java b/Backend/src/main/java/fredboat/backend/rest/SearchResultController.java new file mode 100644 index 000000000..4e49a4c02 --- /dev/null +++ b/Backend/src/main/java/fredboat/backend/rest/SearchResultController.java @@ -0,0 +1,57 @@ +/* + * + * MIT License + * + * Copyright (c) 2017-2018 Frederik Ar. Mikkelsen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package fredboat.backend.rest; + +import fredboat.backend.Application; +import fredboat.db.entity.cache.SearchResult; +import fredboat.db.repositories.api.SearchResultRepo; +import fredboat.db.repositories.impl.rest.RestSearchResultRepo; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Nullable; + +/** + * Created by napster on 17.02.18. + */ +@RestController +@RequestMapping("/" + Application.API_VERSION + RestSearchResultRepo.PATH) +public class SearchResultController extends EntityController + implements SearchResultRepo { + + protected final SearchResultRepo searchResultRepo; + + public SearchResultController(SearchResultRepo repo) { + super(repo); + this.searchResultRepo = repo; + } + + @Nullable + @PostMapping("/getmaxaged") + @Override + public SearchResult getMaxAged(@RequestBody SearchResult.SearchResultId id, @RequestParam("millis") long maxAgeMillis) { + return searchResultRepo.getMaxAged(id, maxAgeMillis); + } +} diff --git a/Backend/src/main/java/fredboat/backend/rest/package-info.java b/Backend/src/main/java/fredboat/backend/rest/package-info.java new file mode 100644 index 000000000..290fbcc76 --- /dev/null +++ b/Backend/src/main/java/fredboat/backend/rest/package-info.java @@ -0,0 +1,29 @@ +/* + * + * MIT License + * + * Copyright (c) 2017-2018 Frederik Ar. Mikkelsen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +@space.npstr.annotations.FieldsAreNonNullByDefault +@space.npstr.annotations.ParametersAreNonnullByDefault +@space.npstr.annotations.ReturnTypesAreNonNullByDefault +package fredboat.backend.rest; From 2bc0b51b2c4be689930758067088e29f2bd980b8 Mon Sep 17 00:00:00 2001 From: Napster Date: Sat, 17 Feb 2018 18:26:35 +0100 Subject: [PATCH 16/41] Add backend based EntityIO --- FredBoat/fredboat.example.yaml | 6 ++ .../fredboat/command/admin/TestCommand.java | 11 ++- .../fredboat/config/RepoConfiguration.java | 81 +++++++++++++++---- .../config/property/BackendConfig.java | 33 ++++++++ .../property/BackendConfigProperties.java | 46 +++++++++++ .../property/ConfigPropertiesProvider.java | 2 + .../SpringConfigPropertiesProvider.java | 9 ++- .../java/fredboat/main/BotController.java | 13 +-- 8 files changed, 177 insertions(+), 24 deletions(-) create mode 100644 FredBoat/src/main/java/fredboat/config/property/BackendConfig.java create mode 100644 FredBoat/src/main/java/fredboat/config/property/BackendConfigProperties.java diff --git a/FredBoat/fredboat.example.yaml b/FredBoat/fredboat.example.yaml index dad6951f8..8d354f635 100644 --- a/FredBoat/fredboat.example.yaml +++ b/FredBoat/fredboat.example.yaml @@ -136,6 +136,12 @@ event-logger: ### Developers and very experienced users only ################################################################ +backend: + host: "" + user: "" + pass: "" + + database: main: # FredBoat was written to work with PostgreSQL. diff --git a/FredBoat/src/main/java/fredboat/command/admin/TestCommand.java b/FredBoat/src/main/java/fredboat/command/admin/TestCommand.java index 59343ae18..0b9e210cb 100644 --- a/FredBoat/src/main/java/fredboat/command/admin/TestCommand.java +++ b/FredBoat/src/main/java/fredboat/command/admin/TestCommand.java @@ -60,9 +60,14 @@ public TestCommand(String name, String... aliases) { @Override public void onInvoke(@Nonnull CommandContext context) { - Launcher.getBotController().getExecutor().submit( - () -> invoke(Launcher.getBotController().getDatabaseManager().getMainDbConn(), context, context.args) - ); + if (Launcher.getBotController().getBackendConfig().getBackendUrl().isEmpty()) { + Launcher.getBotController().getExecutor().submit( + () -> invoke(Launcher.getBotController().getDatabaseManager().getMainDbConn(), context, context.args) + ); + } else {//todo test rest repos instead? + context.reply("No direct database connection has been set up for this bot that could be stress tested."); + return; + } } boolean invoke(DatabaseConnection dbConn, Context context, String args[]) { diff --git a/FredBoat/src/main/java/fredboat/config/RepoConfiguration.java b/FredBoat/src/main/java/fredboat/config/RepoConfiguration.java index d4b7cf5d6..9271bac6c 100644 --- a/FredBoat/src/main/java/fredboat/config/RepoConfiguration.java +++ b/FredBoat/src/main/java/fredboat/config/RepoConfiguration.java @@ -24,9 +24,14 @@ package fredboat.config; +import com.google.gson.Gson; +import fredboat.config.property.BackendConfig; +import fredboat.db.DatabaseManager; import fredboat.db.repositories.api.*; import fredboat.db.repositories.impl.*; -import org.springframework.beans.factory.annotation.Qualifier; +import fredboat.db.repositories.impl.rest.*; +import fredboat.main.BotController; +import fredboat.util.rest.Http; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import space.npstr.sqlsauce.DatabaseWrapper; @@ -41,39 +46,85 @@ @Configuration public class RepoConfiguration { + private final BackendConfig backendConfig; + private final DatabaseManager databaseManager; + private final Gson gson = new Gson(); + private final Http http = BotController.HTTP; //todo replace + + public RepoConfiguration(BackendConfig backendConfig, DatabaseManager databaseManager) { + this.backendConfig = backendConfig; + this.databaseManager = databaseManager; + } + @Bean - public BlacklistRepo blacklistRepo(DatabaseWrapper mainDbWrapper) { - return new SqlSauceBlacklistRepo(mainDbWrapper); + public BlacklistRepo blacklistRepo() { + String backendUrl = backendConfig.getBackendUrl(); + if (backendUrl.isEmpty()) { + return new SqlSauceBlacklistRepo(databaseManager.getMainDbWrapper()); + } else { + return new RestBlacklistRepo(backendUrl, http, gson); + } } @Bean - public GuildConfigRepo guildConfigRepo(DatabaseWrapper mainDbWrapper) { - return new SqlSauceGuildConfigRepo(mainDbWrapper); + public GuildConfigRepo guildConfigRepo() { + String backendUrl = backendConfig.getBackendUrl(); + if (backendUrl.isEmpty()) { + return new SqlSauceGuildConfigRepo(databaseManager.getMainDbWrapper()); + } else { + return new RestGuildConfigRepo(backendUrl, http, gson); + } } @Bean - public GuildDataRepo guildDataRepo(DatabaseWrapper mainDbWrapper) { - return new SqlSauceGuildDataRepo(mainDbWrapper); + public GuildDataRepo guildDataRepo() { + String backendUrl = backendConfig.getBackendUrl(); + if (backendUrl.isEmpty()) { + return new SqlSauceGuildDataRepo(databaseManager.getMainDbWrapper()); + } else { + return new RestGuildDataRepo(backendUrl, http, gson); + } } @Bean - public GuildModulesRepo guildModulesRepo(DatabaseWrapper mainDbWrapper) { - return new SqlSauceGuildModulesRepo(mainDbWrapper); + public GuildModulesRepo guildModulesRepo() { + String backendUrl = backendConfig.getBackendUrl(); + if (backendUrl.isEmpty()) { + return new SqlSauceGuildModulesRepo(databaseManager.getMainDbWrapper()); + } else { + return new RestGuildModulesRepo(backendUrl, http, gson); + } } @Bean - public GuildPermsRepo guildPermsRepo(DatabaseWrapper mainDbWrapper) { - return new SqlSauceGuildPermsRepo(mainDbWrapper); + public GuildPermsRepo guildPermsRepo() { + String backendUrl = backendConfig.getBackendUrl(); + if (backendUrl.isEmpty()) { + return new SqlSauceGuildPermsRepo(databaseManager.getMainDbWrapper()); + } else { + return new RestGuildPermsRepo(backendUrl, http, gson); + } } @Bean - public PrefixRepo prefixRepo(DatabaseWrapper mainDbWrapper) { - return new SqlSaucePrefixRepo(mainDbWrapper); + public PrefixRepo prefixRepo() { + String backendUrl = backendConfig.getBackendUrl(); + if (backendUrl.isEmpty()) { + return new SqlSaucePrefixRepo(databaseManager.getMainDbWrapper()); + } else { + return new RestPrefixRepo(backendUrl, http, gson); + } } @Nullable @Bean - public SearchResultRepo searchResultRepo(@Nullable @Qualifier("cacheDbWrapper") DatabaseWrapper cacheDbWrapper) { - return cacheDbWrapper == null ? null : new SqlSauceSearchResultRepo(cacheDbWrapper); //todo noop repo for cache entities? + public SearchResultRepo searchResultRepo() { + String backendUrl = backendConfig.getBackendUrl(); + if (backendUrl.isEmpty()) { + DatabaseWrapper cacheDbWrapper = databaseManager.getCacheDbWrapper(); + return cacheDbWrapper == null ? null : new SqlSauceSearchResultRepo(cacheDbWrapper); //todo noop repo for cache entities? + } else { + return new RestSearchResultRepo(backendUrl, http, gson); + } } } diff --git a/FredBoat/src/main/java/fredboat/config/property/BackendConfig.java b/FredBoat/src/main/java/fredboat/config/property/BackendConfig.java new file mode 100644 index 000000000..6ef3ee242 --- /dev/null +++ b/FredBoat/src/main/java/fredboat/config/property/BackendConfig.java @@ -0,0 +1,33 @@ +/* + * MIT License + * + * Copyright (c) 2017-2018 Frederik Ar. Mikkelsen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package fredboat.config.property; + +/** + * Created by napster on 27.02.18. + */ +public interface BackendConfig { + + String getHost(); +} diff --git a/FredBoat/src/main/java/fredboat/config/property/BackendConfigProperties.java b/FredBoat/src/main/java/fredboat/config/property/BackendConfigProperties.java new file mode 100644 index 000000000..8f954b8c8 --- /dev/null +++ b/FredBoat/src/main/java/fredboat/config/property/BackendConfigProperties.java @@ -0,0 +1,46 @@ +/* + * MIT License + * + * Copyright (c) 2017-2018 Frederik Ar. Mikkelsen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package fredboat.config.property; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +/** + * Created by napster on 03.03.18. + */ +@Component +@ConfigurationProperties(prefix = "backend") +public class BackendConfigProperties implements BackendConfig { + + private String host = ""; + + public String getHost() { + return host; + } + + public void setHost(String host) { + this.host = host; + } +} diff --git a/FredBoat/src/main/java/fredboat/config/property/ConfigPropertiesProvider.java b/FredBoat/src/main/java/fredboat/config/property/ConfigPropertiesProvider.java index 5a452721e..9a2e5686e 100644 --- a/FredBoat/src/main/java/fredboat/config/property/ConfigPropertiesProvider.java +++ b/FredBoat/src/main/java/fredboat/config/property/ConfigPropertiesProvider.java @@ -35,6 +35,8 @@ public interface ConfigPropertiesProvider { AudioSourcesConfig getAudioSourcesConfig(); + BackendConfig getBackendConfig(); + Credentials getCredentials(); DatabaseConfig getDatabaseConfig(); diff --git a/FredBoat/src/main/java/fredboat/config/property/SpringConfigPropertiesProvider.java b/FredBoat/src/main/java/fredboat/config/property/SpringConfigPropertiesProvider.java index 4b43ce3dc..58484f417 100644 --- a/FredBoat/src/main/java/fredboat/config/property/SpringConfigPropertiesProvider.java +++ b/FredBoat/src/main/java/fredboat/config/property/SpringConfigPropertiesProvider.java @@ -33,16 +33,18 @@ public class SpringConfigPropertiesProvider implements ConfigPropertiesProvider { private final AppConfig appConfig; + private final BackendConfig backendConfig; private final AudioSourcesConfig audioSourcesConfig; private final Credentials credentials; private final DatabaseConfig databaseConfig; private final EventLoggerConfig eventLoggerConfig; private final LavalinkConfig lavalinkConfig; - public SpringConfigPropertiesProvider(AppConfig appConfig, AudioSourcesConfig audioSourcesConfig, + public SpringConfigPropertiesProvider(AppConfig appConfig, BackendConfig backendConfig, AudioSourcesConfig audioSourcesConfig, Credentials credentials, DatabaseConfig databaseConfig, EventLoggerConfig eventLoggerConfig, LavalinkConfig lavalinkConfig) { this.appConfig = appConfig; + this.backendConfig = backendConfig; this.audioSourcesConfig = audioSourcesConfig; this.credentials = credentials; this.databaseConfig = databaseConfig; @@ -60,6 +62,11 @@ public AudioSourcesConfig getAudioSourcesConfig() { return audioSourcesConfig; } + @Override + public BackendConfig getBackendConfig() { + return backendConfig; + } + @Override public Credentials getCredentials() { return credentials; diff --git a/FredBoat/src/main/java/fredboat/main/BotController.java b/FredBoat/src/main/java/fredboat/main/BotController.java index 1501ffcd2..b22a49511 100644 --- a/FredBoat/src/main/java/fredboat/main/BotController.java +++ b/FredBoat/src/main/java/fredboat/main/BotController.java @@ -4,10 +4,7 @@ import fredboat.agent.FredBoatAgent; import fredboat.audio.player.AudioConnectionFacade; import fredboat.audio.player.PlayerRegistry; -import fredboat.config.property.AppConfig; -import fredboat.config.property.AudioSourcesConfig; -import fredboat.config.property.ConfigPropertiesProvider; -import fredboat.config.property.Credentials; +import fredboat.config.property.*; import fredboat.db.DatabaseManager; import fredboat.db.EntityIO; import fredboat.event.EventListenerBoat; @@ -64,7 +61,9 @@ public BotController(ConfigPropertiesProvider configProvider, AudioConnectionFac this.shutdownHandler = shutdownHandler; this.databaseManager = databaseManager; this.entityIO = entityIO; - hibernateStats.register(); //call this exactly once after all db connections have been created + try { + hibernateStats.register(); //call this exactly once after all db connections have been created + } catch (IllegalStateException ignored) {}//can happen when using the REST repos this.executor = executor; this.playerRegistry = playerRegistry; this.jdaEntityProvider = jdaEntityProvider; @@ -83,6 +82,10 @@ public AudioSourcesConfig getAudioSourcesConfig() { return configProvider.getAudioSourcesConfig(); } + public BackendConfig getBackendConfig() { + return configProvider.getBackendConfig(); + } + public Credentials getCredentials() { return configProvider.getCredentials(); } From 3380f1466e8e42bf5996428ec7e9e45d9070efbc Mon Sep 17 00:00:00 2001 From: Napster Date: Sun, 18 Feb 2018 19:44:30 +0100 Subject: [PATCH 17/41] Remove unused entity getter with nullable contract --- .../backend/rest/EntityController.java | 8 -- .../db/repositories/api/GuildBasedRepo.java | 14 +-- .../api/LegacyGuildBasedRepo.java | 14 +-- .../fredboat/db/repositories/api/Repo.java | 9 -- .../db/repositories/impl/SqlSauceRepo.java | 7 -- .../impl/rest/CachedRestRepo.java | 91 +++++++++++++++++++ .../impl/rest/RestBlacklistRepo.java | 10 +- .../impl/rest/RestGuildConfigRepo.java | 9 +- .../impl/rest/RestGuildDataRepo.java | 9 +- .../impl/rest/RestGuildModulesRepo.java | 9 +- .../impl/rest/RestGuildPermsRepo.java | 9 +- .../impl/rest/RestPrefixRepo.java | 9 +- .../db/repositories/impl/rest/RestRepo.java | 13 --- .../impl/rest/RestSearchResultRepo.java | 9 +- FredBoat/build.gradle | 1 - Shared/build.gradle | 2 + .../java/fredboat/util/rest/CacheUtil.java | 0 17 files changed, 154 insertions(+), 69 deletions(-) create mode 100644 Database/src/main/java/fredboat/db/repositories/impl/rest/CachedRestRepo.java rename {FredBoat => Shared}/src/main/java/fredboat/util/rest/CacheUtil.java (100%) diff --git a/Backend/src/main/java/fredboat/backend/rest/EntityController.java b/Backend/src/main/java/fredboat/backend/rest/EntityController.java index f9ec4abce..21091ee5d 100644 --- a/Backend/src/main/java/fredboat/backend/rest/EntityController.java +++ b/Backend/src/main/java/fredboat/backend/rest/EntityController.java @@ -31,7 +31,6 @@ import org.springframework.web.bind.annotation.RequestBody; import space.npstr.sqlsauce.entities.SaucedEntity; -import javax.annotation.Nullable; import java.io.Serializable; /** @@ -51,13 +50,6 @@ public EntityController(Repo repo) { this.repo = repo; } - @Override - @PostMapping("/get") - @Nullable - public E get(@RequestBody I id) { - return repo.get(id); - } - @Override @PostMapping("/delete") public void delete(@RequestBody I id) { diff --git a/Database/src/main/java/fredboat/db/repositories/api/GuildBasedRepo.java b/Database/src/main/java/fredboat/db/repositories/api/GuildBasedRepo.java index ef4096f19..a692250a9 100644 --- a/Database/src/main/java/fredboat/db/repositories/api/GuildBasedRepo.java +++ b/Database/src/main/java/fredboat/db/repositories/api/GuildBasedRepo.java @@ -27,30 +27,20 @@ import net.dv8tion.jda.core.entities.Guild; -import javax.annotation.Nullable; - /** * Created by napster on 05.02.18. */ public interface GuildBasedRepo extends Repo { /** - * Type safety on top of {@link Repo#get(Object)} for entities based on guilds. - */ - @Nullable - default E get(Guild guild) { - return get(guild.getIdLong()); - } - - /** - * Type safety on top of {@link Repo#get(Object)} for entities based on guilds. + * Type safety on top of {@link Repo#delete(Object)} for entities based on guilds. */ default void delete(Guild guild) { delete(guild.getIdLong()); } /** - * Type safety on top of {@link Repo#get(Object)} for entities based on guilds. + * Type safety on top of {@link Repo#fetch(Object)} for entities based on guilds. */ default E fetch(Guild guild) { return fetch(guild.getIdLong()); diff --git a/Database/src/main/java/fredboat/db/repositories/api/LegacyGuildBasedRepo.java b/Database/src/main/java/fredboat/db/repositories/api/LegacyGuildBasedRepo.java index c57dbce47..39a43d03e 100644 --- a/Database/src/main/java/fredboat/db/repositories/api/LegacyGuildBasedRepo.java +++ b/Database/src/main/java/fredboat/db/repositories/api/LegacyGuildBasedRepo.java @@ -27,8 +27,6 @@ import net.dv8tion.jda.core.entities.Guild; -import javax.annotation.Nullable; - /** * Created by napster on 05.02.18. *

@@ -38,22 +36,14 @@ public interface LegacyGuildBasedRepo extends Repo { /** - * Type safety on top of {@link Repo#get(Object)} for entities based on guilds. - */ - @Nullable - default E get(Guild guild) { - return get(guild.getId()); - } - - /** - * Type safety on top of {@link Repo#get(Object)} for entities based on guilds. + * Type safety on top of {@link Repo#delete(Object)} for entities based on guilds. */ default void delete(Guild guild) { delete(guild.getId()); } /** - * Type safety on top of {@link Repo#get(Object)} for entities based on guilds. + * Type safety on top of {@link Repo#fetch(Object)} for entities based on guilds. */ default E fetch(Guild guild) { return fetch(guild.getId()); diff --git a/Database/src/main/java/fredboat/db/repositories/api/Repo.java b/Database/src/main/java/fredboat/db/repositories/api/Repo.java index 3bdb5c1c1..b6e19e33d 100644 --- a/Database/src/main/java/fredboat/db/repositories/api/Repo.java +++ b/Database/src/main/java/fredboat/db/repositories/api/Repo.java @@ -25,20 +25,11 @@ package fredboat.db.repositories.api; -import javax.annotation.Nullable; - /** * Created by napster on 05.02.18. */ public interface Repo { - /** - * @param id id of the entity that shall be returned - * @return the entity of the provided id, if such an entity exists in the database, null otherwise - */ - @Nullable - E get(I id); - /** * @param id of the entity that shall be deleted */ diff --git a/Database/src/main/java/fredboat/db/repositories/impl/SqlSauceRepo.java b/Database/src/main/java/fredboat/db/repositories/impl/SqlSauceRepo.java index 21fb88252..59fa94598 100644 --- a/Database/src/main/java/fredboat/db/repositories/impl/SqlSauceRepo.java +++ b/Database/src/main/java/fredboat/db/repositories/impl/SqlSauceRepo.java @@ -30,7 +30,6 @@ import space.npstr.sqlsauce.entities.SaucedEntity; import space.npstr.sqlsauce.fp.types.EntityKey; -import javax.annotation.Nullable; import java.io.Serializable; /** @@ -54,12 +53,6 @@ public Class getEntityClass() { return entityClass; } - @Nullable - @Override - public E get(I id) { - return dbWrapper.getEntity(EntityKey.of(id, entityClass)); - } - @Override public void delete(I id) { dbWrapper.deleteEntity(EntityKey.of(id, entityClass)); diff --git a/Database/src/main/java/fredboat/db/repositories/impl/rest/CachedRestRepo.java b/Database/src/main/java/fredboat/db/repositories/impl/rest/CachedRestRepo.java new file mode 100644 index 000000000..245cb1e11 --- /dev/null +++ b/Database/src/main/java/fredboat/db/repositories/impl/rest/CachedRestRepo.java @@ -0,0 +1,91 @@ +/* + * + * MIT License + * + * Copyright (c) 2017-2018 Frederik Ar. Mikkelsen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package fredboat.db.repositories.impl.rest; + +import com.google.common.cache.CacheBuilder; +import com.google.common.cache.CacheLoader; +import com.google.common.cache.LoadingCache; +import com.google.gson.Gson; +import fredboat.util.rest.CacheUtil; +import fredboat.util.rest.Http; +import io.prometheus.client.guava.cache.CacheMetricsCollector; +import space.npstr.sqlsauce.entities.SaucedEntity; + +import java.io.Serializable; +import java.util.concurrent.TimeUnit; + +/** + * Created by napster on 18.02.18. + */ +public abstract class CachedRestRepo> extends RestRepo { + + private final LoadingCache cache; + + /** + * Create the CachedRestRepo using a default cache + */ + public CachedRestRepo(String path, Class entityClass, Http http, Gson gson) { + this(path, entityClass, http, gson, + CacheBuilder.newBuilder() + .expireAfterAccess(60, TimeUnit.SECONDS) + .expireAfterWrite(120, TimeUnit.SECONDS) + .recordStats() + ); + } + + public CachedRestRepo(String path, Class entityClass, Http http, Gson gson, CacheBuilder cacheBuilder) { + super(path, entityClass, http, gson); + this.cache = cacheBuilder.build(CacheLoader.from(super::fetch)); + } + + /** + * Add the cache of this CachedRestRepo to the provided metrics under the provided name + * + * @return itself for chaining calls + */ + public CachedRestRepo registerCacheStats(CacheMetricsCollector cacheMetrics, String name) { + cacheMetrics.addCache(name, cache); + return this; + } + + @Override + public void delete(I id) { + super.delete(id); + cache.invalidate(id); + } + + @Override + public E fetch(I id) { + return CacheUtil.getUncheckedUnwrapped(cache, id); + } + + @Override + public E merge(E entity) { + E merged = super.merge(entity); + cache.put(merged.getId(), merged); + return merged; + } +} diff --git a/Database/src/main/java/fredboat/db/repositories/impl/rest/RestBlacklistRepo.java b/Database/src/main/java/fredboat/db/repositories/impl/rest/RestBlacklistRepo.java index 7b6af1836..dd7df8350 100644 --- a/Database/src/main/java/fredboat/db/repositories/impl/rest/RestBlacklistRepo.java +++ b/Database/src/main/java/fredboat/db/repositories/impl/rest/RestBlacklistRepo.java @@ -30,6 +30,7 @@ import fredboat.db.entity.main.BlacklistEntry; import fredboat.db.repositories.api.BlacklistRepo; import fredboat.util.rest.Http; +import io.prometheus.client.guava.cache.CacheMetricsCollector; import java.io.IOException; import java.util.Collections; @@ -38,7 +39,7 @@ /** * Created by napster on 17.02.18. */ -public class RestBlacklistRepo extends RestRepo implements BlacklistRepo { +public class RestBlacklistRepo extends CachedRestRepo implements BlacklistRepo { public static final String PATH = "/blacklist"; @@ -46,6 +47,13 @@ public RestBlacklistRepo(String apiBasePath, Http http, Gson gson) { super(apiBasePath + PATH, BlacklistEntry.class, http, gson); } + + @Override + public RestBlacklistRepo registerCacheStats(CacheMetricsCollector cacheMetrics, String name) { + super.registerCacheStats(cacheMetrics, name); + return this; + } + @Override public List loadBlacklist() { try { diff --git a/Database/src/main/java/fredboat/db/repositories/impl/rest/RestGuildConfigRepo.java b/Database/src/main/java/fredboat/db/repositories/impl/rest/RestGuildConfigRepo.java index 7b05a16a9..2c9c7f9d9 100644 --- a/Database/src/main/java/fredboat/db/repositories/impl/rest/RestGuildConfigRepo.java +++ b/Database/src/main/java/fredboat/db/repositories/impl/rest/RestGuildConfigRepo.java @@ -29,15 +29,22 @@ import fredboat.db.entity.main.GuildConfig; import fredboat.db.repositories.api.GuildConfigRepo; import fredboat.util.rest.Http; +import io.prometheus.client.guava.cache.CacheMetricsCollector; /** * Created by napster on 17.02.18. */ -public class RestGuildConfigRepo extends RestRepo implements GuildConfigRepo { +public class RestGuildConfigRepo extends CachedRestRepo implements GuildConfigRepo { public static final String PATH = "/guildconfig"; public RestGuildConfigRepo(String apiBasePath, Http http, Gson gson) { super(apiBasePath + PATH, GuildConfig.class, http, gson); } + + @Override + public RestGuildConfigRepo registerCacheStats(CacheMetricsCollector cacheMetrics, String name) { + super.registerCacheStats(cacheMetrics, name); + return this; + } } diff --git a/Database/src/main/java/fredboat/db/repositories/impl/rest/RestGuildDataRepo.java b/Database/src/main/java/fredboat/db/repositories/impl/rest/RestGuildDataRepo.java index ff8401a34..e38f0d92e 100644 --- a/Database/src/main/java/fredboat/db/repositories/impl/rest/RestGuildDataRepo.java +++ b/Database/src/main/java/fredboat/db/repositories/impl/rest/RestGuildDataRepo.java @@ -29,15 +29,22 @@ import fredboat.db.entity.main.GuildData; import fredboat.db.repositories.api.GuildDataRepo; import fredboat.util.rest.Http; +import io.prometheus.client.guava.cache.CacheMetricsCollector; /** * Created by napster on 17.02.18. */ -public class RestGuildDataRepo extends RestRepo implements GuildDataRepo { +public class RestGuildDataRepo extends CachedRestRepo implements GuildDataRepo { public static final String PATH = "/guilddata"; public RestGuildDataRepo(String apiBasePath, Http http, Gson gson) { super(apiBasePath + PATH, GuildData.class, http, gson); } + + @Override + public RestGuildDataRepo registerCacheStats(CacheMetricsCollector cacheMetrics, String name) { + super.registerCacheStats(cacheMetrics, name); + return this; + } } diff --git a/Database/src/main/java/fredboat/db/repositories/impl/rest/RestGuildModulesRepo.java b/Database/src/main/java/fredboat/db/repositories/impl/rest/RestGuildModulesRepo.java index 090e85201..3d850df9c 100644 --- a/Database/src/main/java/fredboat/db/repositories/impl/rest/RestGuildModulesRepo.java +++ b/Database/src/main/java/fredboat/db/repositories/impl/rest/RestGuildModulesRepo.java @@ -29,15 +29,22 @@ import fredboat.db.entity.main.GuildModules; import fredboat.db.repositories.api.GuildModulesRepo; import fredboat.util.rest.Http; +import io.prometheus.client.guava.cache.CacheMetricsCollector; /** * Created by napster on 17.02.18. */ -public class RestGuildModulesRepo extends RestRepo implements GuildModulesRepo { +public class RestGuildModulesRepo extends CachedRestRepo implements GuildModulesRepo { public static final String PATH = "/guildmodules"; public RestGuildModulesRepo(String apiBasePath, Http http, Gson gson) { super(apiBasePath + PATH, GuildModules.class, http, gson); } + + @Override + public RestGuildModulesRepo registerCacheStats(CacheMetricsCollector cacheMetrics, String name) { + super.registerCacheStats(cacheMetrics, name); + return this; + } } diff --git a/Database/src/main/java/fredboat/db/repositories/impl/rest/RestGuildPermsRepo.java b/Database/src/main/java/fredboat/db/repositories/impl/rest/RestGuildPermsRepo.java index 868f0a48e..e56483385 100644 --- a/Database/src/main/java/fredboat/db/repositories/impl/rest/RestGuildPermsRepo.java +++ b/Database/src/main/java/fredboat/db/repositories/impl/rest/RestGuildPermsRepo.java @@ -29,15 +29,22 @@ import fredboat.db.entity.main.GuildPermissions; import fredboat.db.repositories.api.GuildPermsRepo; import fredboat.util.rest.Http; +import io.prometheus.client.guava.cache.CacheMetricsCollector; /** * Created by napster on 17.02.18. */ -public class RestGuildPermsRepo extends RestRepo implements GuildPermsRepo { +public class RestGuildPermsRepo extends CachedRestRepo implements GuildPermsRepo { public static final String PATH = "/guildperms"; public RestGuildPermsRepo(String apiBasePath, Http http, Gson gson) { super(apiBasePath + PATH, GuildPermissions.class, http, gson); } + + @Override + public RestGuildPermsRepo registerCacheStats(CacheMetricsCollector cacheMetrics, String name) { + super.registerCacheStats(cacheMetrics, name); + return this; + } } diff --git a/Database/src/main/java/fredboat/db/repositories/impl/rest/RestPrefixRepo.java b/Database/src/main/java/fredboat/db/repositories/impl/rest/RestPrefixRepo.java index 74f7a5052..9cff4679f 100644 --- a/Database/src/main/java/fredboat/db/repositories/impl/rest/RestPrefixRepo.java +++ b/Database/src/main/java/fredboat/db/repositories/impl/rest/RestPrefixRepo.java @@ -29,6 +29,7 @@ import fredboat.db.entity.main.Prefix; import fredboat.db.repositories.api.PrefixRepo; import fredboat.util.rest.Http; +import io.prometheus.client.guava.cache.CacheMetricsCollector; import space.npstr.sqlsauce.entities.GuildBotComposite; import javax.annotation.Nullable; @@ -37,7 +38,7 @@ /** * Created by napster on 17.02.18. */ -public class RestPrefixRepo extends RestRepo implements PrefixRepo { +public class RestPrefixRepo extends CachedRestRepo implements PrefixRepo { public static final String PATH = "/prefix"; @@ -45,6 +46,12 @@ public RestPrefixRepo(String apiBasePath, Http http, Gson gson) { super(apiBasePath + PATH, Prefix.class, http, gson); } + @Override + public RestPrefixRepo registerCacheStats(CacheMetricsCollector cacheMetrics, String name) { + super.registerCacheStats(cacheMetrics, name); + return this; + } + @Nullable @Override public String getPrefix(GuildBotComposite id) { diff --git a/Database/src/main/java/fredboat/db/repositories/impl/rest/RestRepo.java b/Database/src/main/java/fredboat/db/repositories/impl/rest/RestRepo.java index 4122c7ad7..d689d797c 100644 --- a/Database/src/main/java/fredboat/db/repositories/impl/rest/RestRepo.java +++ b/Database/src/main/java/fredboat/db/repositories/impl/rest/RestRepo.java @@ -32,7 +32,6 @@ import org.slf4j.LoggerFactory; import space.npstr.sqlsauce.entities.SaucedEntity; -import javax.annotation.Nullable; import java.io.IOException; import java.io.Serializable; @@ -61,18 +60,6 @@ public Class getEntityClass() { return entityClass; } - @Nullable - @Override - public E get(I id) { - try { - Http.SimpleRequest get = http.post(path + "/get", gson.toJson(id), "application/json"); - return gson.fromJson(get.asString(), entityClass); - } catch (IOException e) { //todo decide on error handling strategy - log.error("Could not GET entity with id {} of class {}", id, entityClass, e); - return null; - } - } - @Override public void delete(I id) { //todo success handling? try { diff --git a/Database/src/main/java/fredboat/db/repositories/impl/rest/RestSearchResultRepo.java b/Database/src/main/java/fredboat/db/repositories/impl/rest/RestSearchResultRepo.java index 148cfc1e2..b98428243 100644 --- a/Database/src/main/java/fredboat/db/repositories/impl/rest/RestSearchResultRepo.java +++ b/Database/src/main/java/fredboat/db/repositories/impl/rest/RestSearchResultRepo.java @@ -29,6 +29,7 @@ import fredboat.db.entity.cache.SearchResult; import fredboat.db.repositories.api.SearchResultRepo; import fredboat.util.rest.Http; +import io.prometheus.client.guava.cache.CacheMetricsCollector; import javax.annotation.Nullable; import java.io.IOException; @@ -36,7 +37,7 @@ /** * Created by napster on 17.02.18. */ -public class RestSearchResultRepo extends RestRepo implements SearchResultRepo { +public class RestSearchResultRepo extends CachedRestRepo implements SearchResultRepo { public static final String PATH = "/searchresult"; @@ -44,6 +45,12 @@ public RestSearchResultRepo(String apiBasePath, Http http, Gson gson) { super(apiBasePath + PATH, SearchResult.class, http, gson); } + @Override + public RestSearchResultRepo registerCacheStats(CacheMetricsCollector cacheMetrics, String name) { + super.registerCacheStats(cacheMetrics, name); + return this; + } + @Nullable @Override public SearchResult getMaxAged(SearchResult.SearchResultId id, long maxAgeMillis) { diff --git a/FredBoat/build.gradle b/FredBoat/build.gradle index 1951cf122..fb5a13f63 100644 --- a/FredBoat/build.gradle +++ b/FredBoat/build.gradle @@ -56,7 +56,6 @@ dependencies { compile group: 'it.unimi.dsi', name: 'fastutil', version: fastUtilVersion compile group: 'org.togglz', name: 'togglz-core', version: togglzVersion - compile group: 'com.google.guava', name: 'guava', version: guavaVersion compile group: 'com.github.vladimir-bukhtoyarov', name: 'bucket4j-core', version: bucket4jVersion //tests diff --git a/Shared/build.gradle b/Shared/build.gradle index be2c9156e..f9543f86f 100644 --- a/Shared/build.gradle +++ b/Shared/build.gradle @@ -18,6 +18,8 @@ dependencies { compile group: 'com.squareup.okhttp3', name: 'okhttp', version: okhttpVersion + compile group: 'com.google.guava', name: 'guava', version: guavaVersion + compile group: 'io.prometheus', name: 'simpleclient', version: prometheusClientVersion compile group: 'io.prometheus', name: 'simpleclient_hotspot', version: prometheusClientVersion compile group: 'io.prometheus', name: 'simpleclient_logback', version: prometheusClientVersion diff --git a/FredBoat/src/main/java/fredboat/util/rest/CacheUtil.java b/Shared/src/main/java/fredboat/util/rest/CacheUtil.java similarity index 100% rename from FredBoat/src/main/java/fredboat/util/rest/CacheUtil.java rename to Shared/src/main/java/fredboat/util/rest/CacheUtil.java From 67c162813d2f49e4d6f79230fc780986cc75b3ea Mon Sep 17 00:00:00 2001 From: Napster Date: Mon, 19 Feb 2018 01:48:01 +0100 Subject: [PATCH 18/41] Implement basic auth --- Backend/application.yml.example | 6 + Backend/build.gradle | 1 + .../config/{DbConfig.java => AppConfig.java} | 105 ++++++++++++++---- .../backend/config/SecurityConfig.java | 59 ++++++++++ .../impl/rest/CachedRestRepo.java | 8 +- .../impl/rest/RestBlacklistRepo.java | 6 +- .../impl/rest/RestGuildConfigRepo.java | 4 +- .../impl/rest/RestGuildDataRepo.java | 4 +- .../impl/rest/RestGuildModulesRepo.java | 4 +- .../impl/rest/RestGuildPermsRepo.java | 4 +- .../impl/rest/RestPrefixRepo.java | 6 +- .../db/repositories/impl/rest/RestRepo.java | 17 ++- .../impl/rest/RestSearchResultRepo.java | 6 +- .../fredboat/command/admin/TestCommand.java | 2 +- .../fredboat/config/RepoConfiguration.java | 28 ++--- .../config/property/BackendConfig.java | 6 + .../property/BackendConfigProperties.java | 30 +++++ .../main/java/fredboat/util/rest/Http.java | 10 +- 18 files changed, 241 insertions(+), 65 deletions(-) rename Backend/src/main/java/fredboat/backend/config/{DbConfig.java => AppConfig.java} (60%) create mode 100644 Backend/src/main/java/fredboat/backend/config/SecurityConfig.java diff --git a/Backend/application.yml.example b/Backend/application.yml.example index e6f593361..7604914fe 100644 --- a/Backend/application.yml.example +++ b/Backend/application.yml.example @@ -8,3 +8,9 @@ fredboat: jdbcUrl: "" cache: jdbcUrl: "" + security: + admins: + - name: fredbotto + pass: 123 + - name: patronbotto + pass: 456 diff --git a/Backend/build.gradle b/Backend/build.gradle index 1b00deeec..70675bbc4 100644 --- a/Backend/build.gradle +++ b/Backend/build.gradle @@ -16,6 +16,7 @@ dependencies { //versioning is handled by spring compile "org.springframework.boot:spring-boot-starter-data-jpa:$springBootVersion" compile "org.springframework.boot:spring-boot-starter-web:$springBootVersion" + compile "org.springframework.boot:spring-boot-starter-security:$springBootVersion" testCompile "org.springframework.boot:spring-boot-starter-test:$springBootVersion" optional "org.springframework.boot:spring-boot-configuration-processor:$springBootVersion" } diff --git a/Backend/src/main/java/fredboat/backend/config/DbConfig.java b/Backend/src/main/java/fredboat/backend/config/AppConfig.java similarity index 60% rename from Backend/src/main/java/fredboat/backend/config/DbConfig.java rename to Backend/src/main/java/fredboat/backend/config/AppConfig.java index fb4085806..f2434a008 100644 --- a/Backend/src/main/java/fredboat/backend/config/DbConfig.java +++ b/Backend/src/main/java/fredboat/backend/config/AppConfig.java @@ -28,27 +28,33 @@ import fredboat.db.DatabaseManager; import org.springframework.beans.factory.config.ConfigurableBeanFactory; import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import org.springframework.context.annotation.Scope; import org.springframework.orm.jpa.JpaVendorAdapter; import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; -import org.springframework.stereotype.Component; import space.npstr.sqlsauce.DatabaseWrapper; import javax.annotation.Nullable; +import java.util.ArrayList; +import java.util.List; /** * Created by napster on 16.02.18. + * + * Mirrors the fredboat tree of the application.yaml */ -@ConfigurationProperties(prefix = "fredboat.db") -@Component -public class DbConfig { +@ConfigurationProperties(prefix = "fredboat") +@Configuration +@EnableConfigurationProperties +public class AppConfig { @Bean("databaseManager") @Scope(ConfigurableBeanFactory.SCOPE_SINGLETON) - public DatabaseManager getDatabaseManager(DbConfig dbConfig) { + public DatabaseManager getDatabaseManager(Db dbConfig) { //todo improve these parameters return new DatabaseManager(null, null, 4, "Backend", true, @@ -80,39 +86,90 @@ public DatabaseWrapper getCacheDbWrapper(DatabaseManager databaseManager) { return databaseManager.getCacheDbWrapper(); } - private final Main main = new Main(); + private final Db db = new Db(); - public Main getMain() { - return main; + @Bean + public Db getDb() { + return db; } - private final Cache cache = new Cache(); + public static class Db { - public Cache getCache() { - return cache; - } + private final Main main = new Main(); + + public Main getMain() { + return main; + } + + private final Cache cache = new Cache(); - public static class Main { - private String jdbcUrl = ""; + public Cache getCache() { + return cache; + } + + public static class Main { + private String jdbcUrl = ""; + + public String getJdbcUrl() { + return jdbcUrl; + } - public String getJdbcUrl() { - return jdbcUrl; + public void setJdbcUrl(String jdbcUrl) { + this.jdbcUrl = jdbcUrl; + } } - public void setJdbcUrl(String jdbcUrl) { - this.jdbcUrl = jdbcUrl; + public static class Cache { + private String jdbcUrl = ""; + + public String getJdbcUrl() { + return jdbcUrl; + } + + public void setJdbcUrl(String jdbcUrl) { + this.jdbcUrl = jdbcUrl; + } } } - public static class Cache { - private String jdbcUrl = ""; + private final Security security = new Security(); - public String getJdbcUrl() { - return jdbcUrl; + @Bean + public Security getSecurity() { + return security; + } + + public static class Security { + + private List admins = new ArrayList<>(); + + public List getAdmins() { + return admins; + } + + public void setAdmins(List admins) { + this.admins = admins; } - public void setJdbcUrl(String jdbcUrl) { - this.jdbcUrl = jdbcUrl; + public static class Admin { + private String name = ""; + private String pass = ""; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPass() { + return pass; + } + + public void setPass(String pass) { + this.pass = pass; + } } } } diff --git a/Backend/src/main/java/fredboat/backend/config/SecurityConfig.java b/Backend/src/main/java/fredboat/backend/config/SecurityConfig.java new file mode 100644 index 000000000..fc261d8e1 --- /dev/null +++ b/Backend/src/main/java/fredboat/backend/config/SecurityConfig.java @@ -0,0 +1,59 @@ +/* + * + * MIT License + * + * Copyright (c) 2017-2018 Frederik Ar. Mikkelsen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package fredboat.backend.config; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.config.annotation.authentication.configurers.provisioning.InMemoryUserDetailsManagerConfigurer; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.config.http.SessionCreationPolicy; + +/** + * Created by napster on 18.02.18. + */ +@Configuration +@EnableWebSecurity +public class SecurityConfig extends WebSecurityConfigurerAdapter { + + @Override + protected void configure(HttpSecurity http) throws Exception { + http.csrf().disable().authorizeRequests().anyRequest().authenticated() + .and().httpBasic() + .and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS); + } + + @Autowired + public void configureGlobal(AuthenticationManagerBuilder auth, AppConfig.Security security) throws Exception { + InMemoryUserDetailsManagerConfigurer inMemoryAuth = auth.inMemoryAuthentication(); + for (AppConfig.Security.Admin admin : security.getAdmins()) { + //we are treating the pass as tokens right now so using the noop encoder is fine + inMemoryAuth.withUser(admin.getName()).password("{noop}" + admin.getPass()).roles("ADMIN", "USER"); + } + } +} diff --git a/Database/src/main/java/fredboat/db/repositories/impl/rest/CachedRestRepo.java b/Database/src/main/java/fredboat/db/repositories/impl/rest/CachedRestRepo.java index 245cb1e11..c0ffe0109 100644 --- a/Database/src/main/java/fredboat/db/repositories/impl/rest/CachedRestRepo.java +++ b/Database/src/main/java/fredboat/db/repositories/impl/rest/CachedRestRepo.java @@ -47,8 +47,8 @@ public abstract class CachedRestRepo entityClass, Http http, Gson gson) { - this(path, entityClass, http, gson, + public CachedRestRepo(String path, Class entityClass, Http http, Gson gson, String auth) { + this(path, entityClass, http, gson, auth, CacheBuilder.newBuilder() .expireAfterAccess(60, TimeUnit.SECONDS) .expireAfterWrite(120, TimeUnit.SECONDS) @@ -56,8 +56,8 @@ public CachedRestRepo(String path, Class entityClass, Http http, Gson gson) { ); } - public CachedRestRepo(String path, Class entityClass, Http http, Gson gson, CacheBuilder cacheBuilder) { - super(path, entityClass, http, gson); + public CachedRestRepo(String path, Class entityClass, Http http, Gson gson, String auth, CacheBuilder cacheBuilder) { + super(path, entityClass, http, gson, auth); this.cache = cacheBuilder.build(CacheLoader.from(super::fetch)); } diff --git a/Database/src/main/java/fredboat/db/repositories/impl/rest/RestBlacklistRepo.java b/Database/src/main/java/fredboat/db/repositories/impl/rest/RestBlacklistRepo.java index dd7df8350..2e2be85a8 100644 --- a/Database/src/main/java/fredboat/db/repositories/impl/rest/RestBlacklistRepo.java +++ b/Database/src/main/java/fredboat/db/repositories/impl/rest/RestBlacklistRepo.java @@ -43,8 +43,8 @@ public class RestBlacklistRepo extends CachedRestRepo impl public static final String PATH = "/blacklist"; - public RestBlacklistRepo(String apiBasePath, Http http, Gson gson) { - super(apiBasePath + PATH, BlacklistEntry.class, http, gson); + public RestBlacklistRepo(String apiBasePath, Http http, Gson gson, String auth) { + super(apiBasePath + PATH, BlacklistEntry.class, http, gson, auth); } @@ -58,7 +58,7 @@ public RestBlacklistRepo registerCacheStats(CacheMetricsCollector cacheMetrics, public List loadBlacklist() { try { Http.SimpleRequest get = http.get(path + "/loadall"); - return gson.fromJson(get.asString(), new TypeToken>() { + return gson.fromJson(auth(get).asString(), new TypeToken>() { }.getType()); } catch (IOException e) { //todo decide on error handling strategy log.error("Could not load the blacklist", e); diff --git a/Database/src/main/java/fredboat/db/repositories/impl/rest/RestGuildConfigRepo.java b/Database/src/main/java/fredboat/db/repositories/impl/rest/RestGuildConfigRepo.java index 2c9c7f9d9..7eb5aab92 100644 --- a/Database/src/main/java/fredboat/db/repositories/impl/rest/RestGuildConfigRepo.java +++ b/Database/src/main/java/fredboat/db/repositories/impl/rest/RestGuildConfigRepo.java @@ -38,8 +38,8 @@ public class RestGuildConfigRepo extends CachedRestRepo imp public static final String PATH = "/guildconfig"; - public RestGuildConfigRepo(String apiBasePath, Http http, Gson gson) { - super(apiBasePath + PATH, GuildConfig.class, http, gson); + public RestGuildConfigRepo(String apiBasePath, Http http, Gson gson, String auth) { + super(apiBasePath + PATH, GuildConfig.class, http, gson, auth); } @Override diff --git a/Database/src/main/java/fredboat/db/repositories/impl/rest/RestGuildDataRepo.java b/Database/src/main/java/fredboat/db/repositories/impl/rest/RestGuildDataRepo.java index e38f0d92e..49a728b96 100644 --- a/Database/src/main/java/fredboat/db/repositories/impl/rest/RestGuildDataRepo.java +++ b/Database/src/main/java/fredboat/db/repositories/impl/rest/RestGuildDataRepo.java @@ -38,8 +38,8 @@ public class RestGuildDataRepo extends CachedRestRepo implement public static final String PATH = "/guilddata"; - public RestGuildDataRepo(String apiBasePath, Http http, Gson gson) { - super(apiBasePath + PATH, GuildData.class, http, gson); + public RestGuildDataRepo(String apiBasePath, Http http, Gson gson, String auth) { + super(apiBasePath + PATH, GuildData.class, http, gson, auth); } @Override diff --git a/Database/src/main/java/fredboat/db/repositories/impl/rest/RestGuildModulesRepo.java b/Database/src/main/java/fredboat/db/repositories/impl/rest/RestGuildModulesRepo.java index 3d850df9c..421aa26da 100644 --- a/Database/src/main/java/fredboat/db/repositories/impl/rest/RestGuildModulesRepo.java +++ b/Database/src/main/java/fredboat/db/repositories/impl/rest/RestGuildModulesRepo.java @@ -38,8 +38,8 @@ public class RestGuildModulesRepo extends CachedRestRepo imp public static final String PATH = "/guildmodules"; - public RestGuildModulesRepo(String apiBasePath, Http http, Gson gson) { - super(apiBasePath + PATH, GuildModules.class, http, gson); + public RestGuildModulesRepo(String apiBasePath, Http http, Gson gson, String auth) { + super(apiBasePath + PATH, GuildModules.class, http, gson, auth); } @Override diff --git a/Database/src/main/java/fredboat/db/repositories/impl/rest/RestGuildPermsRepo.java b/Database/src/main/java/fredboat/db/repositories/impl/rest/RestGuildPermsRepo.java index e56483385..765a9fad2 100644 --- a/Database/src/main/java/fredboat/db/repositories/impl/rest/RestGuildPermsRepo.java +++ b/Database/src/main/java/fredboat/db/repositories/impl/rest/RestGuildPermsRepo.java @@ -38,8 +38,8 @@ public class RestGuildPermsRepo extends CachedRestRepo public static final String PATH = "/guildperms"; - public RestGuildPermsRepo(String apiBasePath, Http http, Gson gson) { - super(apiBasePath + PATH, GuildPermissions.class, http, gson); + public RestGuildPermsRepo(String apiBasePath, Http http, Gson gson, String auth) { + super(apiBasePath + PATH, GuildPermissions.class, http, gson, auth); } @Override diff --git a/Database/src/main/java/fredboat/db/repositories/impl/rest/RestPrefixRepo.java b/Database/src/main/java/fredboat/db/repositories/impl/rest/RestPrefixRepo.java index 9cff4679f..aa200169f 100644 --- a/Database/src/main/java/fredboat/db/repositories/impl/rest/RestPrefixRepo.java +++ b/Database/src/main/java/fredboat/db/repositories/impl/rest/RestPrefixRepo.java @@ -42,8 +42,8 @@ public class RestPrefixRepo extends CachedRestRepo im public static final String PATH = "/prefix"; - public RestPrefixRepo(String apiBasePath, Http http, Gson gson) { - super(apiBasePath + PATH, Prefix.class, http, gson); + public RestPrefixRepo(String apiBasePath, Http http, Gson gson, String auth) { + super(apiBasePath + PATH, Prefix.class, http, gson, auth); } @Override @@ -59,7 +59,7 @@ public String getPrefix(GuildBotComposite id) { String payload = gson.toJson(id); log.debug("Payload: " + payload); Http.SimpleRequest getRaw = http.post(path + "/getraw", payload, "application/json"); - return gson.fromJson(getRaw.asString(), String.class); + return gson.fromJson(auth(getRaw).asString(), String.class); } catch (IOException e) { //todo decide on error handling strategy log.error("Could not get raw prefix", e); return null; diff --git a/Database/src/main/java/fredboat/db/repositories/impl/rest/RestRepo.java b/Database/src/main/java/fredboat/db/repositories/impl/rest/RestRepo.java index d689d797c..f9a39e18b 100644 --- a/Database/src/main/java/fredboat/db/repositories/impl/rest/RestRepo.java +++ b/Database/src/main/java/fredboat/db/repositories/impl/rest/RestRepo.java @@ -48,12 +48,14 @@ public abstract class RestRepo entityClass; protected final Http http; protected final Gson gson; + protected final String auth; - public RestRepo(String path, Class entityClass, Http http, Gson gson) { + public RestRepo(String path, Class entityClass, Http http, Gson gson, String auth) { this.path = path; this.entityClass = entityClass; this.http = http; this.gson = gson; + this.auth = auth; } public Class getEntityClass() { @@ -65,7 +67,7 @@ public void delete(I id) { //todo success handling? try { Http.SimpleRequest delete = http.post(path + "/delete", gson.toJson(id), "application/json"); //noinspection ResultOfMethodCallIgnored - delete.execute(); + auth(delete).execute(); } catch (IOException e) { //todo decide on error handling strategy log.error("Could not DELETE entity with id {} of class {}", id, entityClass, e); } @@ -75,7 +77,7 @@ public void delete(I id) { //todo success handling? public E fetch(I id) { try { Http.SimpleRequest fetch = http.post(path + "/fetch", gson.toJson(id), "application/json"); - return gson.fromJson(fetch.asString(), entityClass); + return gson.fromJson(auth(fetch).asString(), entityClass); } catch (IOException e) { //todo decide on error handling strategy log.error("Could not FETCH entity with id {} of class {}", id, entityClass, e); return null; @@ -86,10 +88,17 @@ public E fetch(I id) { public E merge(E entity) { try { Http.SimpleRequest merge = http.post(path + "/merge", gson.toJson(entity), "application/json"); - return gson.fromJson(merge.asString(), entityClass); + return gson.fromJson(auth(merge).asString(), entityClass); } catch (IOException e) { //todo decide on error handling strategy log.error("Could not MERGE entity with id {} of class {}", entity.getId(), entityClass, e); return null; } } + + /** + * @return the provided request but authed + */ + protected Http.SimpleRequest auth(Http.SimpleRequest request) { + return request.auth(auth); + } } diff --git a/Database/src/main/java/fredboat/db/repositories/impl/rest/RestSearchResultRepo.java b/Database/src/main/java/fredboat/db/repositories/impl/rest/RestSearchResultRepo.java index b98428243..35d680f48 100644 --- a/Database/src/main/java/fredboat/db/repositories/impl/rest/RestSearchResultRepo.java +++ b/Database/src/main/java/fredboat/db/repositories/impl/rest/RestSearchResultRepo.java @@ -41,8 +41,8 @@ public class RestSearchResultRepo extends CachedRestRepo invoke(Launcher.getBotController().getDatabaseManager().getMainDbConn(), context, context.args) ); diff --git a/FredBoat/src/main/java/fredboat/config/RepoConfiguration.java b/FredBoat/src/main/java/fredboat/config/RepoConfiguration.java index 9271bac6c..105574865 100644 --- a/FredBoat/src/main/java/fredboat/config/RepoConfiguration.java +++ b/FredBoat/src/main/java/fredboat/config/RepoConfiguration.java @@ -58,73 +58,73 @@ public RepoConfiguration(BackendConfig backendConfig, DatabaseManager databaseMa @Bean public BlacklistRepo blacklistRepo() { - String backendUrl = backendConfig.getBackendUrl(); + String backendUrl = backendConfig.getHost(); if (backendUrl.isEmpty()) { return new SqlSauceBlacklistRepo(databaseManager.getMainDbWrapper()); } else { - return new RestBlacklistRepo(backendUrl, http, gson); + return new RestBlacklistRepo(backendUrl, http, gson, backendConfig.getBasicAuth()); } } @Bean public GuildConfigRepo guildConfigRepo() { - String backendUrl = backendConfig.getBackendUrl(); + String backendUrl = backendConfig.getHost(); if (backendUrl.isEmpty()) { return new SqlSauceGuildConfigRepo(databaseManager.getMainDbWrapper()); } else { - return new RestGuildConfigRepo(backendUrl, http, gson); + return new RestGuildConfigRepo(backendUrl, http, gson, backendConfig.getBasicAuth()); } } @Bean public GuildDataRepo guildDataRepo() { - String backendUrl = backendConfig.getBackendUrl(); + String backendUrl = backendConfig.getHost(); if (backendUrl.isEmpty()) { return new SqlSauceGuildDataRepo(databaseManager.getMainDbWrapper()); } else { - return new RestGuildDataRepo(backendUrl, http, gson); + return new RestGuildDataRepo(backendUrl, http, gson, backendConfig.getBasicAuth()); } } @Bean public GuildModulesRepo guildModulesRepo() { - String backendUrl = backendConfig.getBackendUrl(); + String backendUrl = backendConfig.getHost(); if (backendUrl.isEmpty()) { return new SqlSauceGuildModulesRepo(databaseManager.getMainDbWrapper()); } else { - return new RestGuildModulesRepo(backendUrl, http, gson); + return new RestGuildModulesRepo(backendUrl, http, gson, backendConfig.getBasicAuth()); } } @Bean public GuildPermsRepo guildPermsRepo() { - String backendUrl = backendConfig.getBackendUrl(); + String backendUrl = backendConfig.getHost(); if (backendUrl.isEmpty()) { return new SqlSauceGuildPermsRepo(databaseManager.getMainDbWrapper()); } else { - return new RestGuildPermsRepo(backendUrl, http, gson); + return new RestGuildPermsRepo(backendUrl, http, gson, backendConfig.getBasicAuth()); } } @Bean public PrefixRepo prefixRepo() { - String backendUrl = backendConfig.getBackendUrl(); + String backendUrl = backendConfig.getHost(); if (backendUrl.isEmpty()) { return new SqlSaucePrefixRepo(databaseManager.getMainDbWrapper()); } else { - return new RestPrefixRepo(backendUrl, http, gson); + return new RestPrefixRepo(backendUrl, http, gson, backendConfig.getBasicAuth()); } } @Nullable @Bean public SearchResultRepo searchResultRepo() { - String backendUrl = backendConfig.getBackendUrl(); + String backendUrl = backendConfig.getHost(); if (backendUrl.isEmpty()) { DatabaseWrapper cacheDbWrapper = databaseManager.getCacheDbWrapper(); return cacheDbWrapper == null ? null : new SqlSauceSearchResultRepo(cacheDbWrapper); //todo noop repo for cache entities? } else { - return new RestSearchResultRepo(backendUrl, http, gson); + return new RestSearchResultRepo(backendUrl, http, gson, backendConfig.getBasicAuth()); } } } diff --git a/FredBoat/src/main/java/fredboat/config/property/BackendConfig.java b/FredBoat/src/main/java/fredboat/config/property/BackendConfig.java index 6ef3ee242..c5ec25e62 100644 --- a/FredBoat/src/main/java/fredboat/config/property/BackendConfig.java +++ b/FredBoat/src/main/java/fredboat/config/property/BackendConfig.java @@ -30,4 +30,10 @@ public interface BackendConfig { String getHost(); + + String getUser(); + + String getPass(); + + String getBasicAuth(); } diff --git a/FredBoat/src/main/java/fredboat/config/property/BackendConfigProperties.java b/FredBoat/src/main/java/fredboat/config/property/BackendConfigProperties.java index 8f954b8c8..b366c1423 100644 --- a/FredBoat/src/main/java/fredboat/config/property/BackendConfigProperties.java +++ b/FredBoat/src/main/java/fredboat/config/property/BackendConfigProperties.java @@ -35,12 +35,42 @@ public class BackendConfigProperties implements BackendConfig { private String host = ""; + private String user = ""; + private String pass = ""; + private String auth = ""; + @Override public String getHost() { return host; } + @Override + public String getUser() { + return user; + } + + @Override + public String getPass() { + return pass; + } + + @Override + public String getBasicAuth() { + if (auth.isEmpty()) { + auth = okhttp3.Credentials.basic(getUser(), getPass()); + } + return auth; + } + public void setHost(String host) { this.host = host; } + + public void setUser(String user) { + this.user = user; + } + + public void setPass(String pass) { + this.pass = pass; + } } diff --git a/Shared/src/main/java/fredboat/util/rest/Http.java b/Shared/src/main/java/fredboat/util/rest/Http.java index 269193b68..5b356d2a3 100644 --- a/Shared/src/main/java/fredboat/util/rest/Http.java +++ b/Shared/src/main/java/fredboat/util/rest/Http.java @@ -162,12 +162,20 @@ public SimpleRequest auth(@Nonnull String value) { return this; } + //set a basic authorization header + @Nonnull + @CheckReturnValue + public SimpleRequest basicAuth(@Nonnull String user, @Nonnull String pass) { + requestBuilder.header("Authorization", Credentials.basic(user, pass)); + return this; + } + //remember to close the response @Nonnull @CheckReturnValue public Response execute() throws IOException { Request req = requestBuilder.build(); - log.debug("{} {}", req.method(), req.url().toString()); + log.debug("{} {} {}", req.method(), req.url().toString(), req.body() != null ? req.body() : ""); return httpClient.newCall(req).execute(); } From addb8a96ff6032f0e277cd5798fd7710881a4155 Mon Sep 17 00:00:00 2001 From: Napster Date: Wed, 28 Feb 2018 02:31:16 +0100 Subject: [PATCH 19/41] Add and catch BackendException for RestRepos --- .../db/entity/cache/SearchResult.java | 5 ++ .../impl/rest/BackendException.java | 50 +++++++++++++++++++ .../impl/rest/RestBlacklistRepo.java | 6 +-- .../impl/rest/RestPrefixRepo.java | 5 +- .../db/repositories/impl/rest/RestRepo.java | 14 +++--- .../impl/rest/RestSearchResultRepo.java | 5 +- .../src/main/java/fredboat/db/EntityIO.java | 9 ++-- 7 files changed, 72 insertions(+), 22 deletions(-) create mode 100644 Database/src/main/java/fredboat/db/repositories/impl/rest/BackendException.java diff --git a/Database/src/main/java/fredboat/db/entity/cache/SearchResult.java b/Database/src/main/java/fredboat/db/entity/cache/SearchResult.java index deae5b409..069f9b3d9 100644 --- a/Database/src/main/java/fredboat/db/entity/cache/SearchResult.java +++ b/Database/src/main/java/fredboat/db/entity/cache/SearchResult.java @@ -190,6 +190,11 @@ public boolean equals(Object o) { SearchResultId other = (SearchResultId) o; return provider.equals(other.provider) && searchTerm.equals(other.searchTerm); } + + @Override + public String toString() { + return "Search: Provider " + provider + " Term " + searchTerm; + } } diff --git a/Database/src/main/java/fredboat/db/repositories/impl/rest/BackendException.java b/Database/src/main/java/fredboat/db/repositories/impl/rest/BackendException.java new file mode 100644 index 000000000..12bd10f66 --- /dev/null +++ b/Database/src/main/java/fredboat/db/repositories/impl/rest/BackendException.java @@ -0,0 +1,50 @@ +/* + * MIT License + * + * Copyright (c) 2017-2018 Frederik Ar. Mikkelsen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package fredboat.db.repositories.impl.rest; + +/** + * Created by napster on 28.02.18. + *

+ * Usually wraps another exception so look for the cause. + */ +public class BackendException extends RuntimeException { + + private static final long serialVersionUID = -2936856678286772706L; + + public BackendException() {//force creation with a message / cause + } + + public BackendException(String message) { + super(message); + } + + public BackendException(String message, Throwable cause) { + super(message, cause); + } + + public BackendException(Throwable cause) { + super(cause); + } +} diff --git a/Database/src/main/java/fredboat/db/repositories/impl/rest/RestBlacklistRepo.java b/Database/src/main/java/fredboat/db/repositories/impl/rest/RestBlacklistRepo.java index 2e2be85a8..aa9bbf64d 100644 --- a/Database/src/main/java/fredboat/db/repositories/impl/rest/RestBlacklistRepo.java +++ b/Database/src/main/java/fredboat/db/repositories/impl/rest/RestBlacklistRepo.java @@ -33,7 +33,6 @@ import io.prometheus.client.guava.cache.CacheMetricsCollector; import java.io.IOException; -import java.util.Collections; import java.util.List; /** @@ -60,9 +59,8 @@ public List loadBlacklist() { Http.SimpleRequest get = http.get(path + "/loadall"); return gson.fromJson(auth(get).asString(), new TypeToken>() { }.getType()); - } catch (IOException e) { //todo decide on error handling strategy - log.error("Could not load the blacklist", e); - return Collections.emptyList(); + } catch (IOException e) { + throw new BackendException("Could not load the blacklist", e); } } } diff --git a/Database/src/main/java/fredboat/db/repositories/impl/rest/RestPrefixRepo.java b/Database/src/main/java/fredboat/db/repositories/impl/rest/RestPrefixRepo.java index aa200169f..13d94858c 100644 --- a/Database/src/main/java/fredboat/db/repositories/impl/rest/RestPrefixRepo.java +++ b/Database/src/main/java/fredboat/db/repositories/impl/rest/RestPrefixRepo.java @@ -60,9 +60,8 @@ public String getPrefix(GuildBotComposite id) { log.debug("Payload: " + payload); Http.SimpleRequest getRaw = http.post(path + "/getraw", payload, "application/json"); return gson.fromJson(auth(getRaw).asString(), String.class); - } catch (IOException e) { //todo decide on error handling strategy - log.error("Could not get raw prefix", e); - return null; + } catch (IOException e) { + throw new BackendException("Could not get prefix for guild " + id.getGuildId(), e); } } } diff --git a/Database/src/main/java/fredboat/db/repositories/impl/rest/RestRepo.java b/Database/src/main/java/fredboat/db/repositories/impl/rest/RestRepo.java index f9a39e18b..cbcc552b1 100644 --- a/Database/src/main/java/fredboat/db/repositories/impl/rest/RestRepo.java +++ b/Database/src/main/java/fredboat/db/repositories/impl/rest/RestRepo.java @@ -68,8 +68,8 @@ public void delete(I id) { //todo success handling? Http.SimpleRequest delete = http.post(path + "/delete", gson.toJson(id), "application/json"); //noinspection ResultOfMethodCallIgnored auth(delete).execute(); - } catch (IOException e) { //todo decide on error handling strategy - log.error("Could not DELETE entity with id {} of class {}", id, entityClass, e); + } catch (IOException e) { + throw new BackendException(String.format("Could not delete entity with id %s of class %s", id, entityClass), e); } } @@ -78,9 +78,8 @@ public E fetch(I id) { try { Http.SimpleRequest fetch = http.post(path + "/fetch", gson.toJson(id), "application/json"); return gson.fromJson(auth(fetch).asString(), entityClass); - } catch (IOException e) { //todo decide on error handling strategy - log.error("Could not FETCH entity with id {} of class {}", id, entityClass, e); - return null; + } catch (IOException e) { + throw new BackendException(String.format("Could not fetch entity with id %s of class %s", id, entityClass), e); } } @@ -89,9 +88,8 @@ public E merge(E entity) { try { Http.SimpleRequest merge = http.post(path + "/merge", gson.toJson(entity), "application/json"); return gson.fromJson(auth(merge).asString(), entityClass); - } catch (IOException e) { //todo decide on error handling strategy - log.error("Could not MERGE entity with id {} of class {}", entity.getId(), entityClass, e); - return null; + } catch (IOException e) { + throw new BackendException(String.format("Could not merge entity with id %s of class %s", entity.getId(), entityClass), e); } } diff --git a/Database/src/main/java/fredboat/db/repositories/impl/rest/RestSearchResultRepo.java b/Database/src/main/java/fredboat/db/repositories/impl/rest/RestSearchResultRepo.java index 35d680f48..29678904f 100644 --- a/Database/src/main/java/fredboat/db/repositories/impl/rest/RestSearchResultRepo.java +++ b/Database/src/main/java/fredboat/db/repositories/impl/rest/RestSearchResultRepo.java @@ -59,9 +59,8 @@ public SearchResult getMaxAged(SearchResult.SearchResultId id, long maxAgeMillis Http.SimpleRequest getMaxAged = http.post(url, gson.toJson(id), "application/json") .url(url, Http.Params.of("millis", Long.toString(maxAgeMillis))); return gson.fromJson(auth(getMaxAged).asString(), SearchResult.class); - } catch (IOException e) { //todo decide on error handling strategy - log.error("Could not get search result", e); - return null; + } catch (IOException e) { + throw new BackendException("Could not get search result for " + id, e); } } } diff --git a/FredBoat/src/main/java/fredboat/db/EntityIO.java b/FredBoat/src/main/java/fredboat/db/EntityIO.java index d6a319401..3885c1435 100644 --- a/FredBoat/src/main/java/fredboat/db/EntityIO.java +++ b/FredBoat/src/main/java/fredboat/db/EntityIO.java @@ -30,6 +30,7 @@ import fredboat.db.entity.cache.SearchResult; import fredboat.db.entity.main.*; import fredboat.db.repositories.api.*; +import fredboat.db.repositories.impl.rest.BackendException; import fredboat.util.DiscordUtil; import fredboat.util.func.NonnullSupplier; import net.dv8tion.jda.core.entities.Guild; @@ -89,7 +90,7 @@ public EntityIO(ConfigPropertiesProvider configProvider, BlacklistRepo blacklist private static T fetchUserFriendly(NonnullSupplier operation) { try { return operation.get(); - } catch (DatabaseException e) { + } catch (DatabaseException | BackendException e) { log.error("EntityIO database operation failed", e); throw new DatabaseNotReadyException(e); } @@ -102,7 +103,7 @@ private static T fetchUserFriendly(NonnullSupplier operation) { private static T getUserFriendly(Supplier operation) { try { return operation.get(); - } catch (DatabaseException e) { + } catch (DatabaseException | BackendException e) { log.error("EntityIO database operation failed", e); throw new DatabaseNotReadyException(e); } @@ -114,7 +115,7 @@ private static T getUserFriendly(Supplier operation) { private static void doUserFriendly(Runnable operation) { try { operation.run(); - } catch (DatabaseException e) { + } catch (DatabaseException | BackendException e) { log.error("EntityIO database operation failed", e); throw new DatabaseNotReadyException(e); } @@ -225,7 +226,7 @@ public Optional getPrefix(GuildBotComposite id) { @Nullable public SearchResult merge(SearchResult searchResult) { if (searchResultRepo != null) { - return searchResultRepo.merge(searchResult); + return fetchUserFriendly(() -> searchResultRepo.merge(searchResult)); } else { return null; } From 4f40e29250c8c73f83254062179d848c48df5ff6 Mon Sep 17 00:00:00 2001 From: Napster Date: Wed, 28 Feb 2018 02:49:03 +0100 Subject: [PATCH 20/41] Rename config file, check for empty pass --- .gitignore | 1 + Backend/{application.yml.example => backend.yaml.example} | 4 ++-- Backend/src/main/java/fredboat/backend/Application.java | 1 + .../src/main/java/fredboat/backend/config/SecurityConfig.java | 3 +++ 4 files changed, 7 insertions(+), 2 deletions(-) rename Backend/{application.yml.example => backend.yaml.example} (85%) diff --git a/.gitignore b/.gitignore index e975c7b45..ec937c61d 100644 --- a/.gitignore +++ b/.gitignore @@ -145,3 +145,4 @@ fredboat.yaml fredboat.yml application.yaml application.yml +backend.yaml diff --git a/Backend/application.yml.example b/Backend/backend.yaml.example similarity index 85% rename from Backend/application.yml.example rename to Backend/backend.yaml.example index 7604914fe..edde0159a 100644 --- a/Backend/application.yml.example +++ b/Backend/backend.yaml.example @@ -11,6 +11,6 @@ fredboat: security: admins: - name: fredbotto - pass: 123 + pass: - name: patronbotto - pass: 456 + pass: diff --git a/Backend/src/main/java/fredboat/backend/Application.java b/Backend/src/main/java/fredboat/backend/Application.java index 794c47bea..45bdcfecf 100644 --- a/Backend/src/main/java/fredboat/backend/Application.java +++ b/Backend/src/main/java/fredboat/backend/Application.java @@ -54,6 +54,7 @@ public class Application { public static final String API_VERSION = "v1"; public static void main(String[] args) { + System.setProperty("spring.config.name", "backend"); SpringApplication.run(Application.class, args); } diff --git a/Backend/src/main/java/fredboat/backend/config/SecurityConfig.java b/Backend/src/main/java/fredboat/backend/config/SecurityConfig.java index fc261d8e1..61138c950 100644 --- a/Backend/src/main/java/fredboat/backend/config/SecurityConfig.java +++ b/Backend/src/main/java/fredboat/backend/config/SecurityConfig.java @@ -52,6 +52,9 @@ protected void configure(HttpSecurity http) throws Exception { public void configureGlobal(AuthenticationManagerBuilder auth, AppConfig.Security security) throws Exception { InMemoryUserDetailsManagerConfigurer inMemoryAuth = auth.inMemoryAuthentication(); for (AppConfig.Security.Admin admin : security.getAdmins()) { + if (admin.getPass().isEmpty()) { + throw new RuntimeException("Admin " + admin.getName() + " configured with empty pass."); + } //we are treating the pass as tokens right now so using the noop encoder is fine inMemoryAuth.withUser(admin.getName()).password("{noop}" + admin.getPass()).roles("ADMIN", "USER"); } From f079ba86bb44d1f83cfd4ce6c3c9c2a676f47aca Mon Sep 17 00:00:00 2001 From: Napster Date: Sun, 4 Mar 2018 17:49:18 +0100 Subject: [PATCH 21/41] Tell jitpack to build with j9 --- jitpack.yml | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 jitpack.yml diff --git a/jitpack.yml b/jitpack.yml new file mode 100644 index 000000000..e69de29bb From c1b4ff55fe0ff5b96fe0ea116b41dd0170b4e396 Mon Sep 17 00:00:00 2001 From: Napster Date: Sun, 4 Mar 2018 17:50:02 +0100 Subject: [PATCH 22/41] Actually tell jitpack to build with j9 --- jitpack.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/jitpack.yml b/jitpack.yml index e69de29bb..2e4852805 100644 --- a/jitpack.yml +++ b/jitpack.yml @@ -0,0 +1,2 @@ +jdk: + - oraclejdk9 \ No newline at end of file From 0be2804964d55d2b93480d0ef6e5ce75fb01412c Mon Sep 17 00:00:00 2001 From: Napster Date: Sun, 4 Mar 2018 18:10:16 +0100 Subject: [PATCH 23/41] Add install and publishing tasks for shared modules --- Database/build.gradle | 25 +++++++++++++++++++++++++ Shared/build.gradle | 26 ++++++++++++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/Database/build.gradle b/Database/build.gradle index 107e387ba..ee8c7f08b 100644 --- a/Database/build.gradle +++ b/Database/build.gradle @@ -3,6 +3,31 @@ version '1.0' ext { moduleName = 'Database' } + +apply plugin: 'maven-publish' + +publishing { + publications { + mavenJava(MavenPublication) { + groupId rootProject.group + artifactId moduleName + + from components.java + + artifact sourceJar { + classifier "sources" + } + } + } +} + +task install(dependsOn: 'publishToMavenLocal') +publishToMavenLocal.dependsOn 'jar' + +task sourceJar(type: Jar) { + from sourceSets.main.allJava +} + dependencies { compile project(':Shared') diff --git a/Shared/build.gradle b/Shared/build.gradle index f9543f86f..11c2ef04d 100644 --- a/Shared/build.gradle +++ b/Shared/build.gradle @@ -3,6 +3,32 @@ version '1.0' ext { moduleName = 'Shared' } + + +apply plugin: 'maven-publish' + +publishing { + publications { + mavenJava(MavenPublication) { + groupId rootProject.group + artifactId moduleName + + from components.java + + artifact sourceJar { + classifier "sources" + } + } + } +} + +task install(dependsOn: 'publishToMavenLocal') +publishToMavenLocal.dependsOn 'jar' + +task sourceJar(type: Jar) { + from sourceSets.main.allJava +} + dependencies { compile group: 'org.json', name: 'json', version: jsonOrgVersion compile group: 'com.github.spotbugs', name: 'spotbugs-annotations', version: spotbugsVersion From 7c1f49b77660431ef97619e433fd54f42a6c1285 Mon Sep 17 00:00:00 2001 From: Napster Date: Sun, 4 Mar 2018 18:22:31 +0100 Subject: [PATCH 24/41] Fix AudioSourcesConfig, set missing / wrong defaults in AppConfig --- .../config/property/AppConfigProperties.java | 6 ++-- .../AudioSourcesConfigProperties.java | 36 +++++++++---------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/FredBoat/src/main/java/fredboat/config/property/AppConfigProperties.java b/FredBoat/src/main/java/fredboat/config/property/AppConfigProperties.java index 38fc9f09d..c2c09765c 100644 --- a/FredBoat/src/main/java/fredboat/config/property/AppConfigProperties.java +++ b/FredBoat/src/main/java/fredboat/config/property/AppConfigProperties.java @@ -47,11 +47,11 @@ public class AppConfigProperties implements AppConfig { private boolean patron = true; private String prefix = "<<"; - private boolean restServerEnabled = true; + private boolean restServerEnabled = false; private List botAdmins = new ArrayList<>(); - private boolean autoBlacklist; + private boolean autoBlacklist = true; private String game = ""; - private boolean continuePlayback; + private boolean continuePlayback = false; //undocumented private int playerLimit = -1; diff --git a/FredBoat/src/main/java/fredboat/config/property/AudioSourcesConfigProperties.java b/FredBoat/src/main/java/fredboat/config/property/AudioSourcesConfigProperties.java index db4f21c93..6d855a6e0 100644 --- a/FredBoat/src/main/java/fredboat/config/property/AudioSourcesConfigProperties.java +++ b/FredBoat/src/main/java/fredboat/config/property/AudioSourcesConfigProperties.java @@ -35,15 +35,15 @@ public class AudioSourcesConfigProperties implements AudioSourcesConfig { // audio managers - private boolean youtubeEnabled; - private boolean soundcloudEnabled; - private boolean bandcampEnabled; - private boolean twitchEnabled; - private boolean vimeoEnabled; - private boolean mixerEnabled; - private boolean spotifyEnabled; - private boolean localEnabled; - private boolean httpEnabled; + private boolean youtubeEnabled = true; + private boolean soundcloudEnabled = true; + private boolean bandcampEnabled = true; + private boolean twitchEnabled = true; + private boolean vimeoEnabled = true; + private boolean mixerEnabled = true; + private boolean spotifyEnabled = true; + private boolean localEnabled = false; + private boolean httpEnabled = false; @Override public boolean isYouTubeEnabled() { @@ -90,39 +90,39 @@ public boolean isHttpEnabled() { return httpEnabled; } - public void setYoutubeEnabled(boolean youtubeEnabled) { + public void setEnableYoutube(boolean youtubeEnabled) { this.youtubeEnabled = youtubeEnabled; } - public void setSoundcloudEnabled(boolean soundcloudEnabled) { + public void setEnableSoundcloud(boolean soundcloudEnabled) { this.soundcloudEnabled = soundcloudEnabled; } - public void setBandcampEnabled(boolean bandcampEnabled) { + public void setEnableBandcamp(boolean bandcampEnabled) { this.bandcampEnabled = bandcampEnabled; } - public void setTwitchEnabled(boolean twitchEnabled) { + public void setEnableTwitch(boolean twitchEnabled) { this.twitchEnabled = twitchEnabled; } - public void setVimeoEnabled(boolean vimeoEnabled) { + public void setEnableVimeo(boolean vimeoEnabled) { this.vimeoEnabled = vimeoEnabled; } - public void setMixerEnabled(boolean mixerEnabled) { + public void setEnableMixer(boolean mixerEnabled) { this.mixerEnabled = mixerEnabled; } - public void setSpotifyEnabled(boolean spotifyEnabled) { + public void setEnableSpotify(boolean spotifyEnabled) { this.spotifyEnabled = spotifyEnabled; } - public void setLocalEnabled(boolean localEnabled) { + public void setEnableLocal(boolean localEnabled) { this.localEnabled = localEnabled; } - public void setHttpEnabled(boolean httpEnabled) { + public void setEnableHttp(boolean httpEnabled) { this.httpEnabled = httpEnabled; } } From 7b2852ba53cfb92ddd9181224b09204c29aec491 Mon Sep 17 00:00:00 2001 From: Napster Date: Sun, 4 Mar 2018 18:36:53 +0100 Subject: [PATCH 25/41] Properly configure bootJar and bootRun tasks --- Backend/build.gradle | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/Backend/build.gradle b/Backend/build.gradle index 70675bbc4..fc93f3384 100644 --- a/Backend/build.gradle +++ b/Backend/build.gradle @@ -9,6 +9,29 @@ ext { moduleName = 'Backend' } +bootRun { + //compiling tests during bootRun increases the likelyhood of catching broken tests locally instead of on the CI + dependsOn compileTestJava + + //pass in custom jvm args + // source: https://stackoverflow.com/a/25079415 + // example: ./gradlew bootRun -PjvmArgs="--illegal-access=debug -Dwhatever=value" + if (project.hasProperty('jvmArgs')) { + jvmArgs project.jvmArgs.split('\\s+') + } +} + +bootJar { + archiveName = "Backend.jar" + doLast { + //copies the jar into a place where the Dockerfile can find it easily (and users maybe too) + copy { + from 'build/libs/Backend.jar' + into '.' + } + } +} + dependencies { compile project(':Database') From 5d194d706a5e9cadeb76c442a4141ca7e6c14e8f Mon Sep 17 00:00:00 2001 From: Napster Date: Sun, 4 Mar 2018 22:11:22 +0100 Subject: [PATCH 26/41] WTF is REST Move the database connection to the backend, always use the REST repos instead --- .../impl/rest/RestBlacklistRepo.java | 4 +- FredBoat/fredboat.example.yaml | 55 +---- .../fredboat/command/admin/TestCommand.java | 223 ------------------ .../commandmeta/CommandInitializer.java | 3 +- .../config/DatabaseConfiguration.java | 157 ------------ .../fredboat/config/RepoConfiguration.java | 57 +---- .../property/BackendConfigProperties.java | 27 +++ .../property/ConfigPropertiesProvider.java | 2 - .../config/property/DatabaseConfig.java | 67 ------ .../property/DatabaseConfigProperties.java | 212 ----------------- .../SpringConfigPropertiesProvider.java | 10 +- .../java/fredboat/main/BotController.java | 9 +- .../test/java/fredboat/test/MockConfig.java | 32 +-- docker-compose.yml | 24 +- 14 files changed, 66 insertions(+), 816 deletions(-) delete mode 100644 FredBoat/src/main/java/fredboat/command/admin/TestCommand.java delete mode 100644 FredBoat/src/main/java/fredboat/config/DatabaseConfiguration.java delete mode 100644 FredBoat/src/main/java/fredboat/config/property/DatabaseConfig.java delete mode 100644 FredBoat/src/main/java/fredboat/config/property/DatabaseConfigProperties.java diff --git a/Database/src/main/java/fredboat/db/repositories/impl/rest/RestBlacklistRepo.java b/Database/src/main/java/fredboat/db/repositories/impl/rest/RestBlacklistRepo.java index aa9bbf64d..0752af982 100644 --- a/Database/src/main/java/fredboat/db/repositories/impl/rest/RestBlacklistRepo.java +++ b/Database/src/main/java/fredboat/db/repositories/impl/rest/RestBlacklistRepo.java @@ -57,7 +57,9 @@ public RestBlacklistRepo registerCacheStats(CacheMetricsCollector cacheMetrics, public List loadBlacklist() { try { Http.SimpleRequest get = http.get(path + "/loadall"); - return gson.fromJson(auth(get).asString(), new TypeToken>() { + String answer = auth(get).asString(); + log.debug(answer); + return gson.fromJson(answer, new TypeToken>() { }.getType()); } catch (IOException e) { throw new BackendException("Could not load the blacklist", e); diff --git a/FredBoat/fredboat.example.yaml b/FredBoat/fredboat.example.yaml index 8d354f635..4f20d6a16 100644 --- a/FredBoat/fredboat.example.yaml +++ b/FredBoat/fredboat.example.yaml @@ -132,63 +132,16 @@ event-logger: -################################################################ -### Developers and very experienced users only -################################################################ - backend: + # Host address of your backend, including port. Example: https://such.example.com:4269/ + # No need set the host when running in docker. host: "" + # Admin username and pass that you configured in the backend.yaml. + # Do not leave any of them blank or empty. user: "" pass: "" -database: - main: - # FredBoat was written to work with PostgreSQL. - # If you are running with docker-compose then you don't need to change the jdbcUrl here. - # In PostgreSQL, role means user and vice versa. Keep that in mind when reading the following help and the provided links. - # If you are running your own PostgreSQL database, you will need to provide a role and a database belonging to that role. - # The role needs at least the permission to log in. - # All postgres databases used by FredBoat are required to have the Hstore extension enabled. - # Learn more about roles here: https://www.postgresql.org/docs/10/static/database-roles.html - # Learn more about creating databases here: https://www.postgresql.org/docs/10/static/manage-ag-createdb.html - # Learn more about the postgres jdbc url here: https://jdbc.postgresql.org/documentation/head/connect.html - # Learn more about creating extensions here: https://www.postgresql.org/docs/current/static/sql-createextension.html - # If you are using an SSH tunnel, you need to point your jdbc url to localhost and the configured tunnelLocalPort - # Example jdbc: "jdbc:postgresql://localhost:5432/fredboat?user=fredboat&password=youshallnotpass" - jdbcUrl: "" - - # Ssh tunnel for a remote database. this is useful for when you don't want to expose your database on the remote server - # and instead use ssh tunneling to access it - # If you are running with docker-compose then you don't need to change any ssh value here. - # If you are using an SSH tunnel, you need to point your jdbc url to localhost and the configured tunnelLocalPort - # Keep the sshHost an empty string for no tunnel. - tunnel: - host: "" # add the ssh port to the ip / url, usually 22, for example: "db.example.com:22" - user: "" # user on the remote machine - privateKeyFile: "" # path to an ssh private key file which is authorized to log in to the sshUser on the remote machine. learn how to create these: https://www.digitalocean.com/community/tutorials/initial-server-setup-with-ubuntu-16-04#step-four-—-add-public-key-authentication-(recommended) - keyPass: "" # optional passphrase for the ssh key file - localPort: 5432 # endpoint port of the tunnel on the machine running fredboat; makes sure these dont collide; this one needs to be used in the jdbc url - remotePort: 5432 # port of the PostgreSQL on the remote machine, 5432 by default - - cache: - # Database for caching things, see config of main database above for details about the individual values. - # If you are running with docker-compose then you don't need to change the cache jdbcUrl here. - # The main and cache databases can be two databases inside a single postgres instance. - # They CANNOT be the same database due to the way flyway migrations work. - # The main benefit is that you don't have to backup/migrate the cache database, it can just be dropped/recreated - # If you do not provide a jdbc url for the cache database, FredBoat will still work (most likely), but may have a degraded - # performance, especially in high usage environments and when using Spotify playlists. - # If you are going to use two different ssh tunnels for both database connections, make sure that the local tunnel ports don't collide - jdbcUrl: "" - tunnel: - host: "" - user: "" - privateKeyFile: "" - keyPass: "" - localPort: 5433 - remotePort: 5432 - # If you are running lavalink nodes this is the place to add them. # Examples shown below, don't forget to uncomment them properly. diff --git a/FredBoat/src/main/java/fredboat/command/admin/TestCommand.java b/FredBoat/src/main/java/fredboat/command/admin/TestCommand.java deleted file mode 100644 index 1abdd6257..000000000 --- a/FredBoat/src/main/java/fredboat/command/admin/TestCommand.java +++ /dev/null @@ -1,223 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2017 Frederik Ar. Mikkelsen - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - -package fredboat.command.admin; - -import fredboat.commandmeta.abs.Command; -import fredboat.commandmeta.abs.CommandContext; -import fredboat.commandmeta.abs.ICommandRestricted; -import fredboat.db.DatabaseNotReadyException; -import fredboat.definitions.PermissionLevel; -import fredboat.main.Launcher; -import fredboat.messaging.internal.Context; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import space.npstr.sqlsauce.DatabaseConnection; -import space.npstr.sqlsauce.DatabaseException; - -import javax.annotation.Nonnull; -import javax.persistence.EntityManager; -import javax.persistence.PersistenceException; - -/** - * Stress tests the database - */ -public class TestCommand extends Command implements ICommandRestricted { - - private static final Logger log = LoggerFactory.getLogger(TestCommand.class); - - private enum Result {WORKING, SUCCESS, FAILED} - - private final String DROP_TEST_TABLE = "DROP TABLE IF EXISTS test;"; - private final String CREATE_TEST_TABLE = "CREATE TABLE IF NOT EXISTS test (id serial, val integer, PRIMARY KEY (id));"; - private final String INSERT_TEST_TABLE = "INSERT INTO test (val) VALUES (:val) "; - - public TestCommand(String name, String... aliases) { - super(name, aliases); - } - - @Override - public void onInvoke(@Nonnull CommandContext context) { - if (Launcher.getBotController().getBackendConfig().getHost().isEmpty()) { - Launcher.getBotController().getExecutor().submit( - () -> invoke(Launcher.getBotController().getDatabaseManager().getMainDbConn(), context, context.args) - ); - } else {//todo test rest repos instead? - context.reply("No direct database connection has been set up for this bot that could be stress tested."); - return; - } - } - - boolean invoke(DatabaseConnection dbConn, Context context, String args[]) { - - boolean result = false; - - int t = 20; - int o = 2000; - if (args.length > 1) { - t = Integer.valueOf(args[0]); - o = Integer.valueOf(args[1]); - } - final int threads = t; - final int operations = o; - if (context.getTextChannel() != null && context.getMember() != null) { - context.replyWithName("Beginning stress test with " + threads + " threads each doing " + operations + " operations"); - } - - prepareStressTest(dbConn); - long started = System.currentTimeMillis(); - Result[] results = new Result[threads]; - Throwable[] exceptions = new Throwable[threads]; - - for (int i = 0; i < threads; i++) { - results[i] = Result.WORKING; - new StressTestThread(i, operations, results, exceptions, dbConn).start(); - } - - //wait for when it's done and report the results - int maxTime = 600000; //give it max 10 mins to run - int sleep = 10; //ms - int maxChecks = maxTime / sleep; - int c = 0; - while (!doneYet(results) || c >= maxChecks) { - c++; - try { - Thread.sleep(sleep); - } catch (InterruptedException e) { - //duh - } - } - - String out = "`DB stress test results:"; - for (int i = 0; i < results.length; i++) { - out += "\nThread #" + i + ": "; - if (results[i] == Result.WORKING) { - out += "failed to get it done in " + maxTime / 1000 + " seconds"; - result = false; - } else if (results[i] == Result.FAILED) { - exceptions[i].printStackTrace(); - out += "failed with an exception: " + exceptions[i].toString(); - result = false; - } else if (results[i] == Result.SUCCESS) { - out += "successful"; - result = true; - } - } - out += "\n Time taken: " + ((System.currentTimeMillis() - started)) + "ms for " + (threads * operations) + " requested operations.`"; - log.info(out); - if (context.getTextChannel() != null && context.getMember() != null) { - context.replyWithName(out); - } - - return result; - } - - private boolean doneYet(Result[] results) { - for (int i = 0; i < results.length; i++) { - if (results[i] == Result.WORKING) { - return false; - } - } - return true; - } - - private void prepareStressTest(DatabaseConnection dbConn) { - //drop and recreate the test table - EntityManager em = null; - try { - em = dbConn.getEntityManager(); - em.getTransaction().begin(); - em.createNativeQuery(DROP_TEST_TABLE).executeUpdate(); - em.createNativeQuery(CREATE_TEST_TABLE).executeUpdate(); - em.getTransaction().commit(); - } catch (DatabaseException | PersistenceException e) { - throw new DatabaseNotReadyException(e); - } finally { - if (em != null) { - em.close(); - } - } - } - - private class StressTestThread extends Thread { - - private int number; - private int operations; - private Result[] results; - private Throwable[] exceptions; - private DatabaseConnection dbConn; - - - StressTestThread(int number, int operations, Result[] results, Throwable[] exceptions, DatabaseConnection dbConn) { - super(StressTestThread.class.getSimpleName() + " number"); - this.number = number; - this.operations = operations; - this.results = results; - this.exceptions = exceptions; - this.dbConn = dbConn; - } - - @Override - public void run() { - boolean failed = false; - EntityManager em = null; - try { - for (int i = 0; i < operations; i++) { - em = dbConn.getEntityManager(); - try { - em.getTransaction().begin(); - em.createNativeQuery(INSERT_TEST_TABLE) - .setParameter("val", (int) (Math.random() * 10000)) - .executeUpdate(); - em.getTransaction().commit(); - } finally { - em.close(); //go crazy and request and close the EM for every single operation, this is a stress test after all - } - } - } catch (Exception e) { - results[number] = Result.FAILED; - exceptions[number] = e; - failed = true; - if (em != null) - em.close(); - } - - if (!failed) - results[number] = Result.SUCCESS; - } - } - - @Nonnull - @Override - public String help(@Nonnull Context context) { - return "{0}{1} [n m]\n#Stress test the database with n threads each doing m operations. Results will be shown after max 10 minutes."; - } - - @Nonnull - @Override - public PermissionLevel getMinimumPerms() { - return PermissionLevel.BOT_OWNER; - } -} diff --git a/FredBoat/src/main/java/fredboat/commandmeta/CommandInitializer.java b/FredBoat/src/main/java/fredboat/commandmeta/CommandInitializer.java index 40b279879..00b4057ae 100644 --- a/FredBoat/src/main/java/fredboat/commandmeta/CommandInitializer.java +++ b/FredBoat/src/main/java/fredboat/commandmeta/CommandInitializer.java @@ -88,7 +88,6 @@ public static void initCommands(@Nullable CacheMetricsCollector cacheMetrics, We adminModule.registerCommand(new ReviveCommand("revive")); adminModule.registerCommand(new SentryDsnCommand("sentrydsn")); adminModule.registerCommand(new SetAvatarCommand("setavatar")); - adminModule.registerCommand(new TestCommand("test")); adminModule.registerCommand(new UnblacklistCommand("unblacklist", "unlimit")); @@ -174,7 +173,7 @@ public static void initCommands(@Nullable CacheMetricsCollector cacheMetrics, We funModule.registerCommand(new RemoteFileCommand("http://i.imgur.com/93VahIh.png", "anime")); funModule.registerCommand(new RemoteFileCommand("http://i.imgur.com/qz6g1vj.gif", "explosion")); funModule.registerCommand(new RemoteFileCommand("http://i.imgur.com/84nbpQe.png", "internetspeed")); - + /* Text Faces & Unicode 'Art' & ASCII 'Art' and Stuff */ funModule.registerCommand(new TextCommand("¯\\_(ツ)_/¯", "shrug", "shr")); funModule.registerCommand(new TextCommand("ಠ_ಠ", "faceofdisapproval", "fod", "disapproving")); diff --git a/FredBoat/src/main/java/fredboat/config/DatabaseConfiguration.java b/FredBoat/src/main/java/fredboat/config/DatabaseConfiguration.java deleted file mode 100644 index 9559fa1d2..000000000 --- a/FredBoat/src/main/java/fredboat/config/DatabaseConfiguration.java +++ /dev/null @@ -1,157 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2017-2018 Frederik Ar. Mikkelsen - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package fredboat.config; - -import com.zaxxer.hikari.metrics.prometheus.PrometheusMetricsTrackerFactory; -import fredboat.agent.DBConnectionWatchdogAgent; -import fredboat.agent.FredBoatAgent; -import fredboat.config.property.DatabaseConfig; -import fredboat.config.property.ConfigPropertiesProvider; -import fredboat.db.DatabaseManager; -import fredboat.main.ShutdownHandler; -import fredboat.shared.constant.BotConstants; -import fredboat.shared.constant.ExitCodes; -import fredboat.util.DiscordUtil; -import io.prometheus.client.hibernate.HibernateStatisticsCollector; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Primary; -import org.springframework.orm.jpa.JpaVendorAdapter; -import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; -import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; -import space.npstr.sqlsauce.DatabaseConnection; -import space.npstr.sqlsauce.DatabaseWrapper; - -import javax.annotation.Nullable; - -/** - * Created by napster on 23.02.18. - *

- * Provides database related beans - */ -@Configuration -public class DatabaseConfiguration { - - private static final Logger log = LoggerFactory.getLogger(DatabaseConfiguration.class); - - @Primary - @Bean - public DatabaseWrapper mainDbWrapper(DatabaseConnection mainDbConn) { - return new DatabaseWrapper(mainDbConn); - } - - @Bean - @Nullable - public DatabaseWrapper cacheDbWrapper(@Nullable @Qualifier("cacheDbConn") DatabaseConnection cacheDbConn) { - return cacheDbConn == null ? null : new DatabaseWrapper(cacheDbConn); - } - - @Primary - @Bean - public DatabaseConnection mainDbConn(DatabaseManager databaseManager, ShutdownHandler shutdownHandler) - throws InterruptedException { - //attempt to connect to the database a few times - // this is relevant in a dockerized environment because after a reboot there is no guarantee that the db - // container will be started before the fredboat one - int dbConnectionAttempts = 0; - DatabaseConnection mainDbConn = null; - while ((mainDbConn == null || !mainDbConn.isAvailable()) && dbConnectionAttempts++ < 10) { - try { - if (mainDbConn != null) { - mainDbConn.shutdown(); - } - mainDbConn = databaseManager.getMainDbConn(); - } catch (Exception e) { - log.info("Could not connect to the database. Retrying in a moment...", e); - Thread.sleep(6000); - } - } - if (mainDbConn == null || !mainDbConn.isAvailable()) { - String message = "Could not establish database connection. Exiting..."; - log.error(message); - shutdownHandler.shutdown(ExitCodes.EXIT_CODE_ERROR); //a "hard" shutdown is kinda necessary in docker environments - throw new RuntimeException(message); - } - - FredBoatAgent.start(new DBConnectionWatchdogAgent(mainDbConn)); - return mainDbConn; - } - - @Bean - @Nullable - public DatabaseConnection cacheDbConn(DatabaseManager databaseManager, ShutdownHandler shutdownHandler) { - try { - return databaseManager.getCacheDbConn(); - } catch (Exception e) { - String message = "Exception when connecting to cache db"; - log.error(message, e); - shutdownHandler.shutdown(ExitCodes.EXIT_CODE_ERROR); //a "hard" shutdown is kinda necessary in docker environments - throw new RuntimeException(message); - } - } - - @Bean - public DatabaseManager databaseManager(ConfigPropertiesProvider configProvider, HibernateStatisticsCollector hibernateStats, - PrometheusMetricsTrackerFactory hikariStats) { - //run migrations except when its the patron boat - boolean migrateAndValidate = DiscordUtil.getBotId(configProvider.getCredentials()) != BotConstants.PATRON_BOT_ID; - - DatabaseConfig dbConf = configProvider.getDatabaseConfig(); - - DatabaseManager databaseManager = new DatabaseManager(hibernateStats, hikariStats, - dbConf.getHikariPoolSize(), configProvider.getAppConfig().getDistribution().name(), migrateAndValidate, - dbConf.getMainJdbcUrl(), dbConf.getMainSshTunnelConfig(), - dbConf.getCacheJdbcUrl(), dbConf.getCacheSshTunnelConfig(), - (puName, dataSource, properties, entityPackages) -> { - LocalContainerEntityManagerFactoryBean emfb = new LocalContainerEntityManagerFactoryBean(); - emfb.setDataSource(dataSource); - emfb.setPackagesToScan(entityPackages.toArray(new String[entityPackages.size()])); - - JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter(); - emfb.setJpaVendorAdapter(vendorAdapter); - emfb.setJpaProperties(properties); - - emfb.afterPropertiesSet(); //initiate creation of the native emf - return emfb.getNativeEntityManagerFactory(); - }); - - Runtime.getRuntime().addShutdownHook(new Thread(() -> { - if (databaseManager.isCacheConnBuilt()) { - DatabaseConnection cacheDbConn = databaseManager.getCacheDbConn(); - if (cacheDbConn != null) { - cacheDbConn.shutdown(); - } - } - if (databaseManager.isMainConnBuilt()) { - databaseManager.getMainDbConn().shutdown(); - } - }, "databasemanager-shutdown-hook")); - - return databaseManager; - } -} diff --git a/FredBoat/src/main/java/fredboat/config/RepoConfiguration.java b/FredBoat/src/main/java/fredboat/config/RepoConfiguration.java index 105574865..b81e6068f 100644 --- a/FredBoat/src/main/java/fredboat/config/RepoConfiguration.java +++ b/FredBoat/src/main/java/fredboat/config/RepoConfiguration.java @@ -26,15 +26,12 @@ import com.google.gson.Gson; import fredboat.config.property.BackendConfig; -import fredboat.db.DatabaseManager; import fredboat.db.repositories.api.*; -import fredboat.db.repositories.impl.*; import fredboat.db.repositories.impl.rest.*; import fredboat.main.BotController; import fredboat.util.rest.Http; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import space.npstr.sqlsauce.DatabaseWrapper; import javax.annotation.Nullable; @@ -47,84 +44,46 @@ public class RepoConfiguration { private final BackendConfig backendConfig; - private final DatabaseManager databaseManager; private final Gson gson = new Gson(); private final Http http = BotController.HTTP; //todo replace - public RepoConfiguration(BackendConfig backendConfig, DatabaseManager databaseManager) { + public RepoConfiguration(BackendConfig backendConfig) { this.backendConfig = backendConfig; - this.databaseManager = databaseManager; } @Bean public BlacklistRepo blacklistRepo() { - String backendUrl = backendConfig.getHost(); - if (backendUrl.isEmpty()) { - return new SqlSauceBlacklistRepo(databaseManager.getMainDbWrapper()); - } else { - return new RestBlacklistRepo(backendUrl, http, gson, backendConfig.getBasicAuth()); - } + return new RestBlacklistRepo(backendConfig.getHost(), http, gson, backendConfig.getBasicAuth()); } @Bean public GuildConfigRepo guildConfigRepo() { - String backendUrl = backendConfig.getHost(); - if (backendUrl.isEmpty()) { - return new SqlSauceGuildConfigRepo(databaseManager.getMainDbWrapper()); - } else { - return new RestGuildConfigRepo(backendUrl, http, gson, backendConfig.getBasicAuth()); - } + return new RestGuildConfigRepo(backendConfig.getHost(), http, gson, backendConfig.getBasicAuth()); } @Bean public GuildDataRepo guildDataRepo() { - String backendUrl = backendConfig.getHost(); - if (backendUrl.isEmpty()) { - return new SqlSauceGuildDataRepo(databaseManager.getMainDbWrapper()); - } else { - return new RestGuildDataRepo(backendUrl, http, gson, backendConfig.getBasicAuth()); - } + return new RestGuildDataRepo(backendConfig.getHost(), http, gson, backendConfig.getBasicAuth()); } @Bean public GuildModulesRepo guildModulesRepo() { - String backendUrl = backendConfig.getHost(); - if (backendUrl.isEmpty()) { - return new SqlSauceGuildModulesRepo(databaseManager.getMainDbWrapper()); - } else { - return new RestGuildModulesRepo(backendUrl, http, gson, backendConfig.getBasicAuth()); - } + return new RestGuildModulesRepo(backendConfig.getHost(), http, gson, backendConfig.getBasicAuth()); } @Bean public GuildPermsRepo guildPermsRepo() { - String backendUrl = backendConfig.getHost(); - if (backendUrl.isEmpty()) { - return new SqlSauceGuildPermsRepo(databaseManager.getMainDbWrapper()); - } else { - return new RestGuildPermsRepo(backendUrl, http, gson, backendConfig.getBasicAuth()); - } + return new RestGuildPermsRepo(backendConfig.getHost(), http, gson, backendConfig.getBasicAuth()); } @Bean public PrefixRepo prefixRepo() { - String backendUrl = backendConfig.getHost(); - if (backendUrl.isEmpty()) { - return new SqlSaucePrefixRepo(databaseManager.getMainDbWrapper()); - } else { - return new RestPrefixRepo(backendUrl, http, gson, backendConfig.getBasicAuth()); - } + return new RestPrefixRepo(backendConfig.getHost(), http, gson, backendConfig.getBasicAuth()); } @Nullable @Bean public SearchResultRepo searchResultRepo() { - String backendUrl = backendConfig.getHost(); - if (backendUrl.isEmpty()) { - DatabaseWrapper cacheDbWrapper = databaseManager.getCacheDbWrapper(); - return cacheDbWrapper == null ? null : new SqlSauceSearchResultRepo(cacheDbWrapper); //todo noop repo for cache entities? - } else { - return new RestSearchResultRepo(backendUrl, http, gson, backendConfig.getBasicAuth()); - } + return new RestSearchResultRepo(backendConfig.getHost(), http, gson, backendConfig.getBasicAuth()); } } diff --git a/FredBoat/src/main/java/fredboat/config/property/BackendConfigProperties.java b/FredBoat/src/main/java/fredboat/config/property/BackendConfigProperties.java index b366c1423..c50e0c789 100644 --- a/FredBoat/src/main/java/fredboat/config/property/BackendConfigProperties.java +++ b/FredBoat/src/main/java/fredboat/config/property/BackendConfigProperties.java @@ -24,6 +24,8 @@ package fredboat.config.property; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; @@ -34,6 +36,8 @@ @ConfigurationProperties(prefix = "backend") public class BackendConfigProperties implements BackendConfig { + private static final Logger log = LoggerFactory.getLogger(BackendConfigProperties.class); + private String host = ""; private String user = ""; private String pass = ""; @@ -64,13 +68,36 @@ public String getBasicAuth() { public void setHost(String host) { this.host = host; + //noinspection ConstantConditions + if (host == null || host.isEmpty()) { + if ("docker".equals(System.getenv("ENV"))) { + log.info("No backend host found, docker environment detected. Using default backend url"); + this.host = "http://backend:4269/v1"; + } else { + String message = "No backend host provided in a non-docker environment. FredBoat cannot work without a backend."; + log.error(message); + throw new RuntimeException(message); + } + } } public void setUser(String user) { this.user = user; + //noinspection ConstantConditions + if (user == null || user.isEmpty()) { + String message = "No backend user provided."; + log.error(message); + throw new RuntimeException(message); + } } public void setPass(String pass) { this.pass = pass; + //noinspection ConstantConditions + if (pass == null || pass.isEmpty()) { + String message = "No backend pass provided."; + log.error(message); + throw new RuntimeException(message); + } } } diff --git a/FredBoat/src/main/java/fredboat/config/property/ConfigPropertiesProvider.java b/FredBoat/src/main/java/fredboat/config/property/ConfigPropertiesProvider.java index 9a2e5686e..e28c8304a 100644 --- a/FredBoat/src/main/java/fredboat/config/property/ConfigPropertiesProvider.java +++ b/FredBoat/src/main/java/fredboat/config/property/ConfigPropertiesProvider.java @@ -39,8 +39,6 @@ public interface ConfigPropertiesProvider { Credentials getCredentials(); - DatabaseConfig getDatabaseConfig(); - EventLoggerConfig getEventLoggerConfig(); LavalinkConfig getLavalinkConfig(); diff --git a/FredBoat/src/main/java/fredboat/config/property/DatabaseConfig.java b/FredBoat/src/main/java/fredboat/config/property/DatabaseConfig.java deleted file mode 100644 index f53763f82..000000000 --- a/FredBoat/src/main/java/fredboat/config/property/DatabaseConfig.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2017-2018 Frederik Ar. Mikkelsen - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package fredboat.config.property; - -import space.npstr.sqlsauce.ssh.SshTunnel; - -import javax.annotation.Nullable; - -/** - * Created by napster on 19.02.18. - */ -public interface DatabaseConfig { - - /** - * JdbcUrl of the main database - */ - String getMainJdbcUrl(); - - /** - * @return may return null if no tunnel shall be created for the main database connection - */ - @Nullable - SshTunnel.SshDetails getMainSshTunnelConfig(); - - /** - * @return JdbcUrl of the cache database, may return null if no cache database was provided. - */ - @Nullable - String getCacheJdbcUrl(); - - /** - * @return may return null if no tunnel shall be created for the cache database connection - */ - @Nullable - SshTunnel.SshDetails getCacheSshTunnelConfig(); - - /** - * @return database connection poolsize - */ - default int getHikariPoolSize() { - //more database connections don't help with performance, so use a value based on available cores, but not too low - //http://www.dailymotion.com/video/x2s8uec_oltp-performance-concurrent-mid-tier-connections_tech - return Math.max(4, Runtime.getRuntime().availableProcessors()); - } -} diff --git a/FredBoat/src/main/java/fredboat/config/property/DatabaseConfigProperties.java b/FredBoat/src/main/java/fredboat/config/property/DatabaseConfigProperties.java deleted file mode 100644 index 3acc6e96b..000000000 --- a/FredBoat/src/main/java/fredboat/config/property/DatabaseConfigProperties.java +++ /dev/null @@ -1,212 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2017-2018 Frederik Ar. Mikkelsen - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package fredboat.config.property; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.stereotype.Component; -import space.npstr.sqlsauce.ssh.SshTunnel; - -import javax.annotation.Nullable; - -/** - * Created by napster on 03.03.18. - */ -@Component -@ConfigurationProperties(prefix = "database") -@SuppressWarnings("unused") -public class DatabaseConfigProperties implements DatabaseConfig { - - private static final Logger log = LoggerFactory.getLogger(DatabaseConfigProperties.class); - - private Db main = new Db(); - private Db cache = new Db(); - - @Override - public String getMainJdbcUrl() { - String jdbcUrl = main.getJdbcUrl(); - //noinspection ConstantConditions - if (jdbcUrl == null || jdbcUrl.isEmpty()) { - if ("docker".equals(System.getenv("ENV"))) { - log.info("No main JDBC URL found, docker environment detected. Using default docker main JDBC url"); - jdbcUrl = "jdbc:postgresql://db:5432/fredboat?user=fredboat"; - main.setJdbcUrl(jdbcUrl); - } else { - String message = "No main jdbcUrl provided in a non-docker environment. FredBoat cannot work without a database."; - log.error(message); - throw new RuntimeException(message); - } - } - return jdbcUrl; - } - - @Nullable - @Override - public SshTunnel.SshDetails getMainSshTunnelConfig() { - return main.getTunnel().toDetails(); - } - - private boolean hasWarnedEmptyCacheJdbc = false; - private boolean hasWarnedSameJdbcs = false; - - - @Nullable - @Override - public String getCacheJdbcUrl() { - String jdbcUrl = cache.getJdbcUrl(); - //noinspection ConstantConditions - if (jdbcUrl == null || jdbcUrl.isEmpty()) { - if ("docker".equals(System.getenv("ENV"))) { - log.info("No cache jdbcUrl found, docker environment detected. Using default docker cache JDBC url"); - jdbcUrl = "jdbc:postgresql://db:5432/fredboat_cache?user=fredboat"; - cache.setJdbcUrl(jdbcUrl); - } else { - if (!hasWarnedEmptyCacheJdbc) { - log.warn("No cache jdbcUrl provided in a non-docker environment. This may lead to a degraded performance, " - + "especially in a high usage environment, or when using Spotify playlists."); - hasWarnedEmptyCacheJdbc = true; - } - jdbcUrl = ""; - } - } - - if (!jdbcUrl.isEmpty() && jdbcUrl.equals(getMainJdbcUrl())) { - if (!hasWarnedSameJdbcs) { - log.warn("The main and cache jdbc urls may not point to the same database due to how flyway handles migrations. " - + "The cache database will not be available in this execution of FredBoat. This may lead to a degraded performance, " - + "especially in a high usage environment, or when using Spotify playlists."); - hasWarnedSameJdbcs = true; - } - jdbcUrl = ""; - } - - return !jdbcUrl.isEmpty() ? jdbcUrl : null; - } - - @Nullable - @Override - public SshTunnel.SshDetails getCacheSshTunnelConfig() { - return cache.getTunnel().toDetails(); - } - - public void setMain(Db main) { - this.main = main; - } - - public void setCache(Db cache) { - this.cache = cache; - } - - private static class Db { - private String jdbcUrl = ""; - private TunnelProperties tunnel = new TunnelProperties(); - - public String getJdbcUrl() { - return jdbcUrl; - } - - public void setJdbcUrl(String jdbcUrl) { - this.jdbcUrl = jdbcUrl; - } - - public TunnelProperties getTunnel() { - return tunnel; - } - - public void setTunnel(TunnelProperties tunnel) { - this.tunnel = tunnel; - } - } - - private static class TunnelProperties { - - private String host = ""; - private String user = ""; - private String privateKeyFile = ""; - private String keyPass = ""; - private int localPort = 9333; - private int remotePort = 5432; - - @Nullable - public SshTunnel.SshDetails toDetails() { - return host.isEmpty() - ? null - : new SshTunnel.SshDetails(host, user) - .setKeyFile(privateKeyFile) - .setPassphrase(keyPass) - .setLocalPort(localPort) - .setRemotePort(remotePort); - } - - public String getHost() { - return host; - } - - public void setHost(String host) { - this.host = host; - } - - public String getUser() { - return user; - } - - public void setUser(String user) { - this.user = user; - } - - public String getPrivateKeyFile() { - return privateKeyFile; - } - - public void setPrivateKeyFile(String privateKeyFile) { - this.privateKeyFile = privateKeyFile; - } - - public String getKeyPass() { - return keyPass; - } - - public void setKeyPass(String keyPass) { - this.keyPass = keyPass; - } - - public int getLocalPort() { - return localPort; - } - - public void setLocalPort(int localPort) { - this.localPort = localPort; - } - - public int getRemotePort() { - return remotePort; - } - - public void setRemotePort(int remotePort) { - this.remotePort = remotePort; - } - } -} diff --git a/FredBoat/src/main/java/fredboat/config/property/SpringConfigPropertiesProvider.java b/FredBoat/src/main/java/fredboat/config/property/SpringConfigPropertiesProvider.java index 58484f417..fbb924383 100644 --- a/FredBoat/src/main/java/fredboat/config/property/SpringConfigPropertiesProvider.java +++ b/FredBoat/src/main/java/fredboat/config/property/SpringConfigPropertiesProvider.java @@ -36,18 +36,15 @@ public class SpringConfigPropertiesProvider implements ConfigPropertiesProvider private final BackendConfig backendConfig; private final AudioSourcesConfig audioSourcesConfig; private final Credentials credentials; - private final DatabaseConfig databaseConfig; private final EventLoggerConfig eventLoggerConfig; private final LavalinkConfig lavalinkConfig; public SpringConfigPropertiesProvider(AppConfig appConfig, BackendConfig backendConfig, AudioSourcesConfig audioSourcesConfig, - Credentials credentials, DatabaseConfig databaseConfig, - EventLoggerConfig eventLoggerConfig, LavalinkConfig lavalinkConfig) { + Credentials credentials, EventLoggerConfig eventLoggerConfig, LavalinkConfig lavalinkConfig) { this.appConfig = appConfig; this.backendConfig = backendConfig; this.audioSourcesConfig = audioSourcesConfig; this.credentials = credentials; - this.databaseConfig = databaseConfig; this.eventLoggerConfig = eventLoggerConfig; this.lavalinkConfig = lavalinkConfig; } @@ -72,11 +69,6 @@ public Credentials getCredentials() { return credentials; } - @Override - public DatabaseConfig getDatabaseConfig() { - return databaseConfig; - } - @Override public EventLoggerConfig getEventLoggerConfig() { return eventLoggerConfig; diff --git a/FredBoat/src/main/java/fredboat/main/BotController.java b/FredBoat/src/main/java/fredboat/main/BotController.java index b22a49511..35ead96b6 100644 --- a/FredBoat/src/main/java/fredboat/main/BotController.java +++ b/FredBoat/src/main/java/fredboat/main/BotController.java @@ -5,7 +5,6 @@ import fredboat.audio.player.AudioConnectionFacade; import fredboat.audio.player.PlayerRegistry; import fredboat.config.property.*; -import fredboat.db.DatabaseManager; import fredboat.db.EntityIO; import fredboat.event.EventListenerBoat; import fredboat.feature.metrics.BotMetrics; @@ -38,7 +37,6 @@ public class BotController { //central event listener that all events by all shards pass through private final EventListenerBoat mainEventListener; private final ShutdownHandler shutdownHandler; - private final DatabaseManager databaseManager; private final EntityIO entityIO; private final PlayerRegistry playerRegistry; private final JdaEntityProvider jdaEntityProvider; @@ -49,7 +47,7 @@ public class BotController { public BotController(ConfigPropertiesProvider configProvider, AudioConnectionFacade audioConnectionFacade, ShardManager shardManager, - EventListenerBoat eventListenerBoat, ShutdownHandler shutdownHandler, DatabaseManager databaseManager, + EventListenerBoat eventListenerBoat, ShutdownHandler shutdownHandler, EntityIO entityIO, ExecutorService executor, HibernateStatisticsCollector hibernateStats, PlayerRegistry playerRegistry, JdaEntityProvider jdaEntityProvider, BotMetrics botMetrics, @Qualifier("loadAudioPlayerManager") AudioPlayerManager audioPlayerManager, @@ -59,7 +57,6 @@ public BotController(ConfigPropertiesProvider configProvider, AudioConnectionFac this.shardManager = shardManager; this.mainEventListener = eventListenerBoat; this.shutdownHandler = shutdownHandler; - this.databaseManager = databaseManager; this.entityIO = entityIO; try { hibernateStats.register(); //call this exactly once after all db connections have been created @@ -98,10 +95,6 @@ public ShutdownHandler getShutdownHandler() { return shutdownHandler; } - public DatabaseManager getDatabaseManager() { - return databaseManager; - } - @Nonnull public ExecutorService getExecutor() { return executor; diff --git a/FredBoat/src/test/java/fredboat/test/MockConfig.java b/FredBoat/src/test/java/fredboat/test/MockConfig.java index 0842b6410..c37462876 100644 --- a/FredBoat/src/test/java/fredboat/test/MockConfig.java +++ b/FredBoat/src/test/java/fredboat/test/MockConfig.java @@ -30,9 +30,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.yaml.snakeyaml.Yaml; -import space.npstr.sqlsauce.ssh.SshTunnel; -import javax.annotation.Nullable; import java.io.File; import java.util.Collections; import java.util.List; @@ -43,7 +41,7 @@ *

* A default fake config to be used in tests. */ -public class MockConfig implements AppConfig, AudioSourcesConfig, Credentials, DatabaseConfig, EventLoggerConfig, +public class MockConfig implements AppConfig, AudioSourcesConfig, Credentials, EventLoggerConfig, LavalinkConfig, TestingConfig { private static final Logger log = LoggerFactory.getLogger(MockConfig.class); @@ -209,29 +207,6 @@ public String getSentryDsn() { return ""; } - @Override - public String getMainJdbcUrl() { - return ""; - } - - @Nullable - @Override - public SshTunnel.SshDetails getMainSshTunnelConfig() { - return null; - } - - @Nullable - @Override - public String getCacheJdbcUrl() { - return null; - } - - @Nullable - @Override - public SshTunnel.SshDetails getCacheSshTunnelConfig() { - return null; - } - @Override public List getNodes() { return Collections.emptyList(); @@ -257,11 +232,6 @@ public int getGuildStatsInterval() { return 1; } - @Override - public int getHikariPoolSize() { - return 4; - } - @Override public String getCarbonKey() { return ""; diff --git a/docker-compose.yml b/docker-compose.yml index 05e67fe69..ad866155a 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -33,16 +33,32 @@ services: #volumes: #- postgres-data-volume:/var/lib/postgresql/data - ################################################################################ - ## FredBoat + ## Backend ################################################################################ - bot: + backend: # pick one of these: stable or dev # dev receives more frequent updates than stable but may have more bugs / things breaking # versions (example: v2) receive continous non-breaking (best effort) updates via watchtower. switching between versions # (example: going from v2 to v3) usually requires manual migration. what exactly is needed is published on the # FredBoat selfhosting website and/or the selfhosters channel (see top of this file for how to get to these places) + # Once you use the dev branch, you may not be able to go back to stable without deleting your database. + image: fredboat/backend:stable-v1 + #image: fredboat/backend:dev-v1 + restart: always + labels: + - "com.centurylinklabs.watchtower.enable=true" + depends_on: + - db + # Need a bigger memory size or any other custom JVM args? uncomment and edit the line below accordingly + #entrypoint: java -Xmx128m -jar Backend.jar + + ################################################################################ + ## FredBoat + ################################################################################ + bot: + # for choosing between stable or dev, read the paragraph above in the backend + # IMPORTANT: both backend and fredboat need to either be on the stable, or on the dev branch image: fredboat/fredboat:stable-v3 #image: fredboat/fredboat:dev-v3 #build: ./FredBoat #useful alternative for developers @@ -51,7 +67,7 @@ services: labels: - "com.centurylinklabs.watchtower.enable=true" depends_on: - - db + - backend ports: - 1356:1356 volumes: From ba5430ee5091381350b0fe8e8c5a29a53405d357 Mon Sep 17 00:00:00 2001 From: Napster Date: Sun, 4 Mar 2018 22:25:37 +0100 Subject: [PATCH 27/41] Adjust resource paths --- .../db/repositories/impl/rest/RestBlacklistRepo.java | 6 +++--- .../repositories/impl/rest/RestGuildConfigRepo.java | 4 ++-- .../db/repositories/impl/rest/RestGuildDataRepo.java | 4 ++-- .../repositories/impl/rest/RestGuildModulesRepo.java | 4 ++-- .../db/repositories/impl/rest/RestGuildPermsRepo.java | 4 ++-- .../db/repositories/impl/rest/RestPrefixRepo.java | 6 +++--- .../fredboat/db/repositories/impl/rest/RestRepo.java | 11 ++++++++--- .../repositories/impl/rest/RestSearchResultRepo.java | 6 +++--- .../config/property/BackendConfigProperties.java | 7 ++++++- 9 files changed, 31 insertions(+), 21 deletions(-) diff --git a/Database/src/main/java/fredboat/db/repositories/impl/rest/RestBlacklistRepo.java b/Database/src/main/java/fredboat/db/repositories/impl/rest/RestBlacklistRepo.java index 0752af982..053a3daab 100644 --- a/Database/src/main/java/fredboat/db/repositories/impl/rest/RestBlacklistRepo.java +++ b/Database/src/main/java/fredboat/db/repositories/impl/rest/RestBlacklistRepo.java @@ -40,10 +40,10 @@ */ public class RestBlacklistRepo extends CachedRestRepo implements BlacklistRepo { - public static final String PATH = "/blacklist"; + public static final String PATH = "blacklist/"; public RestBlacklistRepo(String apiBasePath, Http http, Gson gson, String auth) { - super(apiBasePath + PATH, BlacklistEntry.class, http, gson, auth); + super(apiBasePath + V1 + PATH, BlacklistEntry.class, http, gson, auth); } @@ -56,7 +56,7 @@ public RestBlacklistRepo registerCacheStats(CacheMetricsCollector cacheMetrics, @Override public List loadBlacklist() { try { - Http.SimpleRequest get = http.get(path + "/loadall"); + Http.SimpleRequest get = http.get(path + "loadall"); String answer = auth(get).asString(); log.debug(answer); return gson.fromJson(answer, new TypeToken>() { diff --git a/Database/src/main/java/fredboat/db/repositories/impl/rest/RestGuildConfigRepo.java b/Database/src/main/java/fredboat/db/repositories/impl/rest/RestGuildConfigRepo.java index 7eb5aab92..b95c46bb4 100644 --- a/Database/src/main/java/fredboat/db/repositories/impl/rest/RestGuildConfigRepo.java +++ b/Database/src/main/java/fredboat/db/repositories/impl/rest/RestGuildConfigRepo.java @@ -36,10 +36,10 @@ */ public class RestGuildConfigRepo extends CachedRestRepo implements GuildConfigRepo { - public static final String PATH = "/guildconfig"; + public static final String PATH = "guildconfig/"; public RestGuildConfigRepo(String apiBasePath, Http http, Gson gson, String auth) { - super(apiBasePath + PATH, GuildConfig.class, http, gson, auth); + super(apiBasePath + V1 + PATH, GuildConfig.class, http, gson, auth); } @Override diff --git a/Database/src/main/java/fredboat/db/repositories/impl/rest/RestGuildDataRepo.java b/Database/src/main/java/fredboat/db/repositories/impl/rest/RestGuildDataRepo.java index 49a728b96..b823bd79e 100644 --- a/Database/src/main/java/fredboat/db/repositories/impl/rest/RestGuildDataRepo.java +++ b/Database/src/main/java/fredboat/db/repositories/impl/rest/RestGuildDataRepo.java @@ -36,10 +36,10 @@ */ public class RestGuildDataRepo extends CachedRestRepo implements GuildDataRepo { - public static final String PATH = "/guilddata"; + public static final String PATH = "guilddata/"; public RestGuildDataRepo(String apiBasePath, Http http, Gson gson, String auth) { - super(apiBasePath + PATH, GuildData.class, http, gson, auth); + super(apiBasePath + V1 + PATH, GuildData.class, http, gson, auth); } @Override diff --git a/Database/src/main/java/fredboat/db/repositories/impl/rest/RestGuildModulesRepo.java b/Database/src/main/java/fredboat/db/repositories/impl/rest/RestGuildModulesRepo.java index 421aa26da..1663985b8 100644 --- a/Database/src/main/java/fredboat/db/repositories/impl/rest/RestGuildModulesRepo.java +++ b/Database/src/main/java/fredboat/db/repositories/impl/rest/RestGuildModulesRepo.java @@ -36,10 +36,10 @@ */ public class RestGuildModulesRepo extends CachedRestRepo implements GuildModulesRepo { - public static final String PATH = "/guildmodules"; + public static final String PATH = "guildmodules/"; public RestGuildModulesRepo(String apiBasePath, Http http, Gson gson, String auth) { - super(apiBasePath + PATH, GuildModules.class, http, gson, auth); + super(apiBasePath + V1 + PATH, GuildModules.class, http, gson, auth); } @Override diff --git a/Database/src/main/java/fredboat/db/repositories/impl/rest/RestGuildPermsRepo.java b/Database/src/main/java/fredboat/db/repositories/impl/rest/RestGuildPermsRepo.java index 765a9fad2..eab7ca18d 100644 --- a/Database/src/main/java/fredboat/db/repositories/impl/rest/RestGuildPermsRepo.java +++ b/Database/src/main/java/fredboat/db/repositories/impl/rest/RestGuildPermsRepo.java @@ -36,10 +36,10 @@ */ public class RestGuildPermsRepo extends CachedRestRepo implements GuildPermsRepo { - public static final String PATH = "/guildperms"; + public static final String PATH = "guildperms/"; public RestGuildPermsRepo(String apiBasePath, Http http, Gson gson, String auth) { - super(apiBasePath + PATH, GuildPermissions.class, http, gson, auth); + super(apiBasePath + V1 + PATH, GuildPermissions.class, http, gson, auth); } @Override diff --git a/Database/src/main/java/fredboat/db/repositories/impl/rest/RestPrefixRepo.java b/Database/src/main/java/fredboat/db/repositories/impl/rest/RestPrefixRepo.java index 13d94858c..cd466b2ee 100644 --- a/Database/src/main/java/fredboat/db/repositories/impl/rest/RestPrefixRepo.java +++ b/Database/src/main/java/fredboat/db/repositories/impl/rest/RestPrefixRepo.java @@ -40,10 +40,10 @@ */ public class RestPrefixRepo extends CachedRestRepo implements PrefixRepo { - public static final String PATH = "/prefix"; + public static final String PATH = "prefix/"; public RestPrefixRepo(String apiBasePath, Http http, Gson gson, String auth) { - super(apiBasePath + PATH, Prefix.class, http, gson, auth); + super(apiBasePath + V1 + PATH, Prefix.class, http, gson, auth); } @Override @@ -58,7 +58,7 @@ public String getPrefix(GuildBotComposite id) { try { String payload = gson.toJson(id); log.debug("Payload: " + payload); - Http.SimpleRequest getRaw = http.post(path + "/getraw", payload, "application/json"); + Http.SimpleRequest getRaw = http.post(path + "getraw", payload, "application/json"); return gson.fromJson(auth(getRaw).asString(), String.class); } catch (IOException e) { throw new BackendException("Could not get prefix for guild " + id.getGuildId(), e); diff --git a/Database/src/main/java/fredboat/db/repositories/impl/rest/RestRepo.java b/Database/src/main/java/fredboat/db/repositories/impl/rest/RestRepo.java index cbcc552b1..225f28742 100644 --- a/Database/src/main/java/fredboat/db/repositories/impl/rest/RestRepo.java +++ b/Database/src/main/java/fredboat/db/repositories/impl/rest/RestRepo.java @@ -43,6 +43,7 @@ public abstract class RestRepo> implements Repo { protected static final Logger log = LoggerFactory.getLogger(RestRepo.class); + protected static final String V1 = "v1/"; protected final String path; protected final Class entityClass; @@ -50,6 +51,10 @@ public abstract class RestRepo entityClass, Http http, Gson gson, String auth) { this.path = path; this.entityClass = entityClass; @@ -65,7 +70,7 @@ public Class getEntityClass() { @Override public void delete(I id) { //todo success handling? try { - Http.SimpleRequest delete = http.post(path + "/delete", gson.toJson(id), "application/json"); + Http.SimpleRequest delete = http.post(path + "delete", gson.toJson(id), "application/json"); //noinspection ResultOfMethodCallIgnored auth(delete).execute(); } catch (IOException e) { @@ -76,7 +81,7 @@ public void delete(I id) { //todo success handling? @Override public E fetch(I id) { try { - Http.SimpleRequest fetch = http.post(path + "/fetch", gson.toJson(id), "application/json"); + Http.SimpleRequest fetch = http.post(path + "fetch", gson.toJson(id), "application/json"); return gson.fromJson(auth(fetch).asString(), entityClass); } catch (IOException e) { throw new BackendException(String.format("Could not fetch entity with id %s of class %s", id, entityClass), e); @@ -86,7 +91,7 @@ public E fetch(I id) { @Override public E merge(E entity) { try { - Http.SimpleRequest merge = http.post(path + "/merge", gson.toJson(entity), "application/json"); + Http.SimpleRequest merge = http.post(path + "merge", gson.toJson(entity), "application/json"); return gson.fromJson(auth(merge).asString(), entityClass); } catch (IOException e) { throw new BackendException(String.format("Could not merge entity with id %s of class %s", entity.getId(), entityClass), e); diff --git a/Database/src/main/java/fredboat/db/repositories/impl/rest/RestSearchResultRepo.java b/Database/src/main/java/fredboat/db/repositories/impl/rest/RestSearchResultRepo.java index 29678904f..46919e667 100644 --- a/Database/src/main/java/fredboat/db/repositories/impl/rest/RestSearchResultRepo.java +++ b/Database/src/main/java/fredboat/db/repositories/impl/rest/RestSearchResultRepo.java @@ -39,10 +39,10 @@ */ public class RestSearchResultRepo extends CachedRestRepo implements SearchResultRepo { - public static final String PATH = "/searchresult"; + public static final String PATH = "searchresult/"; public RestSearchResultRepo(String apiBasePath, Http http, Gson gson, String auth) { - super(apiBasePath + PATH, SearchResult.class, http, gson, auth); + super(apiBasePath + V1 + PATH, SearchResult.class, http, gson, auth); } @Override @@ -55,7 +55,7 @@ public RestSearchResultRepo registerCacheStats(CacheMetricsCollector cacheMetric @Override public SearchResult getMaxAged(SearchResult.SearchResultId id, long maxAgeMillis) { try { - String url = path + "/getmaxaged"; + String url = path + "getmaxaged"; Http.SimpleRequest getMaxAged = http.post(url, gson.toJson(id), "application/json") .url(url, Http.Params.of("millis", Long.toString(maxAgeMillis))); return gson.fromJson(auth(getMaxAged).asString(), SearchResult.class); diff --git a/FredBoat/src/main/java/fredboat/config/property/BackendConfigProperties.java b/FredBoat/src/main/java/fredboat/config/property/BackendConfigProperties.java index c50e0c789..75218979a 100644 --- a/FredBoat/src/main/java/fredboat/config/property/BackendConfigProperties.java +++ b/FredBoat/src/main/java/fredboat/config/property/BackendConfigProperties.java @@ -72,13 +72,18 @@ public void setHost(String host) { if (host == null || host.isEmpty()) { if ("docker".equals(System.getenv("ENV"))) { log.info("No backend host found, docker environment detected. Using default backend url"); - this.host = "http://backend:4269/v1"; + this.host = "http://backend:4269/"; } else { String message = "No backend host provided in a non-docker environment. FredBoat cannot work without a backend."; log.error(message); throw new RuntimeException(message); } } + + //fix up a missing trailing slash + if (!this.host.endsWith("/")) { + this.host += "/"; + } } public void setUser(String user) { From cd6a1c74dbc60cd390d17f5a9314a121c765660d Mon Sep 17 00:00:00 2001 From: Napster Date: Sun, 4 Mar 2018 22:43:37 +0100 Subject: [PATCH 28/41] Catch and rebrand JSON parsing exceptions --- .../db/repositories/impl/rest/RestBlacklistRepo.java | 3 ++- .../fredboat/db/repositories/impl/rest/RestPrefixRepo.java | 3 ++- .../java/fredboat/db/repositories/impl/rest/RestRepo.java | 7 ++++--- .../db/repositories/impl/rest/RestSearchResultRepo.java | 3 ++- 4 files changed, 10 insertions(+), 6 deletions(-) diff --git a/Database/src/main/java/fredboat/db/repositories/impl/rest/RestBlacklistRepo.java b/Database/src/main/java/fredboat/db/repositories/impl/rest/RestBlacklistRepo.java index 053a3daab..c1539dd25 100644 --- a/Database/src/main/java/fredboat/db/repositories/impl/rest/RestBlacklistRepo.java +++ b/Database/src/main/java/fredboat/db/repositories/impl/rest/RestBlacklistRepo.java @@ -26,6 +26,7 @@ package fredboat.db.repositories.impl.rest; import com.google.gson.Gson; +import com.google.gson.JsonSyntaxException; import com.google.gson.reflect.TypeToken; import fredboat.db.entity.main.BlacklistEntry; import fredboat.db.repositories.api.BlacklistRepo; @@ -61,7 +62,7 @@ public List loadBlacklist() { log.debug(answer); return gson.fromJson(answer, new TypeToken>() { }.getType()); - } catch (IOException e) { + } catch (IOException | JsonSyntaxException e) { throw new BackendException("Could not load the blacklist", e); } } diff --git a/Database/src/main/java/fredboat/db/repositories/impl/rest/RestPrefixRepo.java b/Database/src/main/java/fredboat/db/repositories/impl/rest/RestPrefixRepo.java index cd466b2ee..1f9970298 100644 --- a/Database/src/main/java/fredboat/db/repositories/impl/rest/RestPrefixRepo.java +++ b/Database/src/main/java/fredboat/db/repositories/impl/rest/RestPrefixRepo.java @@ -26,6 +26,7 @@ package fredboat.db.repositories.impl.rest; import com.google.gson.Gson; +import com.google.gson.JsonSyntaxException; import fredboat.db.entity.main.Prefix; import fredboat.db.repositories.api.PrefixRepo; import fredboat.util.rest.Http; @@ -60,7 +61,7 @@ public String getPrefix(GuildBotComposite id) { log.debug("Payload: " + payload); Http.SimpleRequest getRaw = http.post(path + "getraw", payload, "application/json"); return gson.fromJson(auth(getRaw).asString(), String.class); - } catch (IOException e) { + } catch (IOException | JsonSyntaxException e) { throw new BackendException("Could not get prefix for guild " + id.getGuildId(), e); } } diff --git a/Database/src/main/java/fredboat/db/repositories/impl/rest/RestRepo.java b/Database/src/main/java/fredboat/db/repositories/impl/rest/RestRepo.java index 225f28742..da11a9f84 100644 --- a/Database/src/main/java/fredboat/db/repositories/impl/rest/RestRepo.java +++ b/Database/src/main/java/fredboat/db/repositories/impl/rest/RestRepo.java @@ -26,6 +26,7 @@ package fredboat.db.repositories.impl.rest; import com.google.gson.Gson; +import com.google.gson.JsonSyntaxException; import fredboat.db.repositories.api.Repo; import fredboat.util.rest.Http; import org.slf4j.Logger; @@ -73,7 +74,7 @@ public void delete(I id) { //todo success handling? Http.SimpleRequest delete = http.post(path + "delete", gson.toJson(id), "application/json"); //noinspection ResultOfMethodCallIgnored auth(delete).execute(); - } catch (IOException e) { + } catch (IOException | JsonSyntaxException e) { throw new BackendException(String.format("Could not delete entity with id %s of class %s", id, entityClass), e); } } @@ -83,7 +84,7 @@ public E fetch(I id) { try { Http.SimpleRequest fetch = http.post(path + "fetch", gson.toJson(id), "application/json"); return gson.fromJson(auth(fetch).asString(), entityClass); - } catch (IOException e) { + } catch (IOException | JsonSyntaxException e) { throw new BackendException(String.format("Could not fetch entity with id %s of class %s", id, entityClass), e); } } @@ -93,7 +94,7 @@ public E merge(E entity) { try { Http.SimpleRequest merge = http.post(path + "merge", gson.toJson(entity), "application/json"); return gson.fromJson(auth(merge).asString(), entityClass); - } catch (IOException e) { + } catch (IOException | JsonSyntaxException e) { throw new BackendException(String.format("Could not merge entity with id %s of class %s", entity.getId(), entityClass), e); } } diff --git a/Database/src/main/java/fredboat/db/repositories/impl/rest/RestSearchResultRepo.java b/Database/src/main/java/fredboat/db/repositories/impl/rest/RestSearchResultRepo.java index 46919e667..c2ee54015 100644 --- a/Database/src/main/java/fredboat/db/repositories/impl/rest/RestSearchResultRepo.java +++ b/Database/src/main/java/fredboat/db/repositories/impl/rest/RestSearchResultRepo.java @@ -26,6 +26,7 @@ package fredboat.db.repositories.impl.rest; import com.google.gson.Gson; +import com.google.gson.JsonSyntaxException; import fredboat.db.entity.cache.SearchResult; import fredboat.db.repositories.api.SearchResultRepo; import fredboat.util.rest.Http; @@ -59,7 +60,7 @@ public SearchResult getMaxAged(SearchResult.SearchResultId id, long maxAgeMillis Http.SimpleRequest getMaxAged = http.post(url, gson.toJson(id), "application/json") .url(url, Http.Params.of("millis", Long.toString(maxAgeMillis))); return gson.fromJson(auth(getMaxAged).asString(), SearchResult.class); - } catch (IOException e) { + } catch (IOException | JsonSyntaxException e) { throw new BackendException("Could not get search result for " + id, e); } } From dd7608d0f61dffa31a4fc8cc53153d6356e5dfeb Mon Sep 17 00:00:00 2001 From: Napster Date: Mon, 5 Mar 2018 00:18:54 +0100 Subject: [PATCH 29/41] Wait on backend to start, simple api version check --- .../impl/rest/RestBlacklistRepo.java | 2 +- .../impl/rest/RestGuildConfigRepo.java | 2 +- .../impl/rest/RestGuildDataRepo.java | 2 +- .../impl/rest/RestGuildModulesRepo.java | 2 +- .../impl/rest/RestGuildPermsRepo.java | 2 +- .../impl/rest/RestPrefixRepo.java | 2 +- .../db/repositories/impl/rest/RestRepo.java | 4 +- .../impl/rest/RestSearchResultRepo.java | 2 +- .../fredboat/config/RepoConfiguration.java | 48 ++++++++++++++++++- 9 files changed, 57 insertions(+), 9 deletions(-) diff --git a/Database/src/main/java/fredboat/db/repositories/impl/rest/RestBlacklistRepo.java b/Database/src/main/java/fredboat/db/repositories/impl/rest/RestBlacklistRepo.java index c1539dd25..1a98d3c8e 100644 --- a/Database/src/main/java/fredboat/db/repositories/impl/rest/RestBlacklistRepo.java +++ b/Database/src/main/java/fredboat/db/repositories/impl/rest/RestBlacklistRepo.java @@ -44,7 +44,7 @@ public class RestBlacklistRepo extends CachedRestRepo impl public static final String PATH = "blacklist/"; public RestBlacklistRepo(String apiBasePath, Http http, Gson gson, String auth) { - super(apiBasePath + V1 + PATH, BlacklistEntry.class, http, gson, auth); + super(apiBasePath + VERSION_PATH + PATH, BlacklistEntry.class, http, gson, auth); } diff --git a/Database/src/main/java/fredboat/db/repositories/impl/rest/RestGuildConfigRepo.java b/Database/src/main/java/fredboat/db/repositories/impl/rest/RestGuildConfigRepo.java index b95c46bb4..9dc05a753 100644 --- a/Database/src/main/java/fredboat/db/repositories/impl/rest/RestGuildConfigRepo.java +++ b/Database/src/main/java/fredboat/db/repositories/impl/rest/RestGuildConfigRepo.java @@ -39,7 +39,7 @@ public class RestGuildConfigRepo extends CachedRestRepo imp public static final String PATH = "guildconfig/"; public RestGuildConfigRepo(String apiBasePath, Http http, Gson gson, String auth) { - super(apiBasePath + V1 + PATH, GuildConfig.class, http, gson, auth); + super(apiBasePath + VERSION_PATH + PATH, GuildConfig.class, http, gson, auth); } @Override diff --git a/Database/src/main/java/fredboat/db/repositories/impl/rest/RestGuildDataRepo.java b/Database/src/main/java/fredboat/db/repositories/impl/rest/RestGuildDataRepo.java index b823bd79e..db54b7af8 100644 --- a/Database/src/main/java/fredboat/db/repositories/impl/rest/RestGuildDataRepo.java +++ b/Database/src/main/java/fredboat/db/repositories/impl/rest/RestGuildDataRepo.java @@ -39,7 +39,7 @@ public class RestGuildDataRepo extends CachedRestRepo implement public static final String PATH = "guilddata/"; public RestGuildDataRepo(String apiBasePath, Http http, Gson gson, String auth) { - super(apiBasePath + V1 + PATH, GuildData.class, http, gson, auth); + super(apiBasePath + VERSION_PATH + PATH, GuildData.class, http, gson, auth); } @Override diff --git a/Database/src/main/java/fredboat/db/repositories/impl/rest/RestGuildModulesRepo.java b/Database/src/main/java/fredboat/db/repositories/impl/rest/RestGuildModulesRepo.java index 1663985b8..f072c6824 100644 --- a/Database/src/main/java/fredboat/db/repositories/impl/rest/RestGuildModulesRepo.java +++ b/Database/src/main/java/fredboat/db/repositories/impl/rest/RestGuildModulesRepo.java @@ -39,7 +39,7 @@ public class RestGuildModulesRepo extends CachedRestRepo imp public static final String PATH = "guildmodules/"; public RestGuildModulesRepo(String apiBasePath, Http http, Gson gson, String auth) { - super(apiBasePath + V1 + PATH, GuildModules.class, http, gson, auth); + super(apiBasePath + VERSION_PATH + PATH, GuildModules.class, http, gson, auth); } @Override diff --git a/Database/src/main/java/fredboat/db/repositories/impl/rest/RestGuildPermsRepo.java b/Database/src/main/java/fredboat/db/repositories/impl/rest/RestGuildPermsRepo.java index eab7ca18d..43aedc3a5 100644 --- a/Database/src/main/java/fredboat/db/repositories/impl/rest/RestGuildPermsRepo.java +++ b/Database/src/main/java/fredboat/db/repositories/impl/rest/RestGuildPermsRepo.java @@ -39,7 +39,7 @@ public class RestGuildPermsRepo extends CachedRestRepo public static final String PATH = "guildperms/"; public RestGuildPermsRepo(String apiBasePath, Http http, Gson gson, String auth) { - super(apiBasePath + V1 + PATH, GuildPermissions.class, http, gson, auth); + super(apiBasePath + VERSION_PATH + PATH, GuildPermissions.class, http, gson, auth); } @Override diff --git a/Database/src/main/java/fredboat/db/repositories/impl/rest/RestPrefixRepo.java b/Database/src/main/java/fredboat/db/repositories/impl/rest/RestPrefixRepo.java index 1f9970298..d4ab05f2a 100644 --- a/Database/src/main/java/fredboat/db/repositories/impl/rest/RestPrefixRepo.java +++ b/Database/src/main/java/fredboat/db/repositories/impl/rest/RestPrefixRepo.java @@ -44,7 +44,7 @@ public class RestPrefixRepo extends CachedRestRepo im public static final String PATH = "prefix/"; public RestPrefixRepo(String apiBasePath, Http http, Gson gson, String auth) { - super(apiBasePath + V1 + PATH, Prefix.class, http, gson, auth); + super(apiBasePath + VERSION_PATH + PATH, Prefix.class, http, gson, auth); } @Override diff --git a/Database/src/main/java/fredboat/db/repositories/impl/rest/RestRepo.java b/Database/src/main/java/fredboat/db/repositories/impl/rest/RestRepo.java index da11a9f84..e0cf315ea 100644 --- a/Database/src/main/java/fredboat/db/repositories/impl/rest/RestRepo.java +++ b/Database/src/main/java/fredboat/db/repositories/impl/rest/RestRepo.java @@ -44,7 +44,9 @@ public abstract class RestRepo> implements Repo { protected static final Logger log = LoggerFactory.getLogger(RestRepo.class); - protected static final String V1 = "v1/"; + + public static final int API_VERSION = 0; + public static final String VERSION_PATH = "v" + API_VERSION + "/"; protected final String path; protected final Class entityClass; diff --git a/Database/src/main/java/fredboat/db/repositories/impl/rest/RestSearchResultRepo.java b/Database/src/main/java/fredboat/db/repositories/impl/rest/RestSearchResultRepo.java index c2ee54015..fd06c4953 100644 --- a/Database/src/main/java/fredboat/db/repositories/impl/rest/RestSearchResultRepo.java +++ b/Database/src/main/java/fredboat/db/repositories/impl/rest/RestSearchResultRepo.java @@ -43,7 +43,7 @@ public class RestSearchResultRepo extends CachedRestRepo= RestRepo.API_VERSION) { + log.info("Backend API version is v{}", apiVersion.getNumber()); + } else { + log.error("Backend API is version v{}, but this FredBoat expects at least v{}", apiVersion.getNumber(), RestRepo.API_VERSION); + shutdownHandler.shutdown(ExitCodes.EXIT_CODE_ERROR); + } } @Bean @@ -86,4 +120,16 @@ public PrefixRepo prefixRepo() { public SearchResultRepo searchResultRepo() { return new RestSearchResultRepo(backendConfig.getHost(), http, gson, backendConfig.getBasicAuth()); } + + private static class Version { + private int number = -1; + + public void setNumber(int number) { + this.number = number; + } + + public int getNumber() { + return number; + } + } } From eacbc3525efe020a3ed44f0c7fcd376fa9ae7769 Mon Sep 17 00:00:00 2001 From: Napster Date: Mon, 5 Mar 2018 00:55:08 +0100 Subject: [PATCH 30/41] Put important values up top, add a few more docs --- FredBoat/fredboat.example.yaml | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/FredBoat/fredboat.example.yaml b/FredBoat/fredboat.example.yaml index 4f20d6a16..8f3d77e36 100644 --- a/FredBoat/fredboat.example.yaml +++ b/FredBoat/fredboat.example.yaml @@ -15,6 +15,13 @@ ### key: value ### ### +### Never edit or add a value to lines that have no default value, like: +### +### credentials: +### +### Just leave them be. A default value may be an empty string like so: "" +### +### ### You can wrap most values into quotation marks, except numbers and booleans: ### ### someUrl: "http://example.com" @@ -74,6 +81,17 @@ audio-sources: ################################################################ ### Essential credentials ################################################################ + +backend: + # Host address of your backend, including port. Example: https://such.example.com:4269/ + # No need set the host when running the whole FredBoat in docker. + host: "" + # Admin username and pass that you configured in the backend.yaml. + # Do not leave any of them empty. + user: "" + pass: "" + + credentials: # Add your discord bot token below, between the quotation marks # Find the token of your bot on https://discordapp.com/developers/applications/me @@ -132,17 +150,6 @@ event-logger: -backend: - # Host address of your backend, including port. Example: https://such.example.com:4269/ - # No need set the host when running in docker. - host: "" - # Admin username and pass that you configured in the backend.yaml. - # Do not leave any of them blank or empty. - user: "" - pass: "" - - - # If you are running lavalink nodes this is the place to add them. # Examples shown below, don't forget to uncomment them properly. # More on Lavalink: https://github.com/Frederikam/Lavalink From 230c66ee76a3b7e26d73a6dab6fb2cf473cdee85 Mon Sep 17 00:00:00 2001 From: Napster Date: Mon, 5 Mar 2018 00:55:53 +0100 Subject: [PATCH 31/41] Add a missing volume, set a higher than default xmx value on the commented out custom line --- docker-compose.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index ad866155a..f238acd6c 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -50,6 +50,8 @@ services: - "com.centurylinklabs.watchtower.enable=true" depends_on: - db + volumes: + - ./backend.yaml:/opt/Backend/backend.yaml # Need a bigger memory size or any other custom JVM args? uncomment and edit the line below accordingly #entrypoint: java -Xmx128m -jar Backend.jar @@ -83,7 +85,7 @@ services: #- C:\Users\your_user_name\Music:/opt/FredBoat/music # Need a bigger memory size or any other custom JVM args? uncomment and edit the line below accordingly - #entrypoint: java -Xmx128m -jar FredBoat.jar + #entrypoint: java -Xmx256m -jar FredBoat.jar ################################################################################ From f4c069c7edaccc0e35e4c81c37235fa6f006c178 Mon Sep 17 00:00:00 2001 From: Napster Date: Tue, 6 Mar 2018 03:33:06 +0100 Subject: [PATCH 32/41] Rename EntityIO -> EntityService --- ...BlacklistIO.java => BlacklistService.java} | 2 +- ...dConfigIO.java => GuildConfigService.java} | 2 +- ...GuildDataIO.java => GuildDataService.java} | 2 +- ...odulesIO.java => GuildModulesService.java} | 2 +- ...ildPermsIO.java => GuildPermsService.java} | 2 +- .../api/{PrefixIO.java => PrefixService.java} | 2 +- ...ResultIO.java => SearchResultService.java} | 2 +- .../fredboat/audio/player/GuildPlayer.java | 12 ++++---- .../fredboat/audio/player/PlayerRegistry.java | 10 +++---- .../command/config/ConfigCommand.java | 6 ++-- .../command/config/ModulesCommand.java | 4 +-- .../command/config/PermissionsCommand.java | 6 ++-- .../command/config/PrefixCommand.java | 4 +-- .../commandmeta/abs/CommandContext.java | 2 +- .../db/{EntityIO.java => EntityService.java} | 22 +++++++------- .../fredboat/event/EventListenerBoat.java | 22 +++++++------- .../src/main/java/fredboat/feature/I18n.java | 4 +-- .../java/fredboat/main/BotController.java | 30 ++++++++++++++----- .../main/java/fredboat/perms/PermsUtil.java | 2 +- .../fredboat/util/ratelimit/Blacklist.java | 14 ++++----- .../fredboat/util/ratelimit/Ratelimiter.java | 6 ++-- .../fredboat/util/rest/TrackSearcher.java | 6 ++-- 22 files changed, 90 insertions(+), 74 deletions(-) rename Database/src/main/java/fredboat/db/api/{BlacklistIO.java => BlacklistService.java} (97%) rename Database/src/main/java/fredboat/db/api/{GuildConfigIO.java => GuildConfigService.java} (97%) rename Database/src/main/java/fredboat/db/api/{GuildDataIO.java => GuildDataService.java} (97%) rename Database/src/main/java/fredboat/db/api/{GuildModulesIO.java => GuildModulesService.java} (97%) rename Database/src/main/java/fredboat/db/api/{GuildPermsIO.java => GuildPermsService.java} (97%) rename Database/src/main/java/fredboat/db/api/{PrefixIO.java => PrefixService.java} (97%) rename Database/src/main/java/fredboat/db/api/{SearchResultIO.java => SearchResultService.java} (97%) rename FredBoat/src/main/java/fredboat/db/{EntityIO.java => EntityService.java} (89%) diff --git a/Database/src/main/java/fredboat/db/api/BlacklistIO.java b/Database/src/main/java/fredboat/db/api/BlacklistService.java similarity index 97% rename from Database/src/main/java/fredboat/db/api/BlacklistIO.java rename to Database/src/main/java/fredboat/db/api/BlacklistService.java index 4580d8653..5d691b426 100644 --- a/Database/src/main/java/fredboat/db/api/BlacklistIO.java +++ b/Database/src/main/java/fredboat/db/api/BlacklistService.java @@ -32,7 +32,7 @@ /** * Created by napster on 07.02.18. */ -public interface BlacklistIO { +public interface BlacklistService { /** * @return the whole blacklist aka all entries. Not a lightweight operation, and shouldn't be called outside diff --git a/Database/src/main/java/fredboat/db/api/GuildConfigIO.java b/Database/src/main/java/fredboat/db/api/GuildConfigService.java similarity index 97% rename from Database/src/main/java/fredboat/db/api/GuildConfigIO.java rename to Database/src/main/java/fredboat/db/api/GuildConfigService.java index f2804cdfa..5596e6bc0 100644 --- a/Database/src/main/java/fredboat/db/api/GuildConfigIO.java +++ b/Database/src/main/java/fredboat/db/api/GuildConfigService.java @@ -33,7 +33,7 @@ /** * Created by napster on 07.02.18. */ -public interface GuildConfigIO { +public interface GuildConfigService { GuildConfig fetchGuildConfig(Guild guild); diff --git a/Database/src/main/java/fredboat/db/api/GuildDataIO.java b/Database/src/main/java/fredboat/db/api/GuildDataService.java similarity index 97% rename from Database/src/main/java/fredboat/db/api/GuildDataIO.java rename to Database/src/main/java/fredboat/db/api/GuildDataService.java index af8f1fc0a..f3050a665 100644 --- a/Database/src/main/java/fredboat/db/api/GuildDataIO.java +++ b/Database/src/main/java/fredboat/db/api/GuildDataService.java @@ -33,7 +33,7 @@ /** * Created by napster on 07.02.18. */ -public interface GuildDataIO { +public interface GuildDataService { GuildData fetchGuildData(Guild guild); diff --git a/Database/src/main/java/fredboat/db/api/GuildModulesIO.java b/Database/src/main/java/fredboat/db/api/GuildModulesService.java similarity index 97% rename from Database/src/main/java/fredboat/db/api/GuildModulesIO.java rename to Database/src/main/java/fredboat/db/api/GuildModulesService.java index 530c96115..2273e2168 100644 --- a/Database/src/main/java/fredboat/db/api/GuildModulesIO.java +++ b/Database/src/main/java/fredboat/db/api/GuildModulesService.java @@ -33,7 +33,7 @@ /** * Created by napster on 07.02.18. */ -public interface GuildModulesIO { +public interface GuildModulesService { GuildModules fetchGuildModules(Guild guild); diff --git a/Database/src/main/java/fredboat/db/api/GuildPermsIO.java b/Database/src/main/java/fredboat/db/api/GuildPermsService.java similarity index 97% rename from Database/src/main/java/fredboat/db/api/GuildPermsIO.java rename to Database/src/main/java/fredboat/db/api/GuildPermsService.java index e1befd97f..6604b8ea4 100644 --- a/Database/src/main/java/fredboat/db/api/GuildPermsIO.java +++ b/Database/src/main/java/fredboat/db/api/GuildPermsService.java @@ -33,7 +33,7 @@ /** * Created by napster on 07.02.18. */ -public interface GuildPermsIO { +public interface GuildPermsService { GuildPermissions fetchGuildPermissions(Guild guild); diff --git a/Database/src/main/java/fredboat/db/api/PrefixIO.java b/Database/src/main/java/fredboat/db/api/PrefixService.java similarity index 97% rename from Database/src/main/java/fredboat/db/api/PrefixIO.java rename to Database/src/main/java/fredboat/db/api/PrefixService.java index 15b993243..25d3476f9 100644 --- a/Database/src/main/java/fredboat/db/api/PrefixIO.java +++ b/Database/src/main/java/fredboat/db/api/PrefixService.java @@ -35,7 +35,7 @@ /** * Created by napster on 07.02.18. */ -public interface PrefixIO { +public interface PrefixService { Prefix transformPrefix(Guild guild, Function transformation); diff --git a/Database/src/main/java/fredboat/db/api/SearchResultIO.java b/Database/src/main/java/fredboat/db/api/SearchResultService.java similarity index 97% rename from Database/src/main/java/fredboat/db/api/SearchResultIO.java rename to Database/src/main/java/fredboat/db/api/SearchResultService.java index b40f45c3e..386bc71ff 100644 --- a/Database/src/main/java/fredboat/db/api/SearchResultIO.java +++ b/Database/src/main/java/fredboat/db/api/SearchResultService.java @@ -32,7 +32,7 @@ /** * Created by napster on 07.02.18. */ -public interface SearchResultIO { +public interface SearchResultService { /** * Merge a search result into the database. diff --git a/FredBoat/src/main/java/fredboat/audio/player/GuildPlayer.java b/FredBoat/src/main/java/fredboat/audio/player/GuildPlayer.java index ce401414f..2d027c2ff 100644 --- a/FredBoat/src/main/java/fredboat/audio/player/GuildPlayer.java +++ b/FredBoat/src/main/java/fredboat/audio/player/GuildPlayer.java @@ -32,7 +32,7 @@ import fredboat.command.music.control.VoteSkipCommand; import fredboat.commandmeta.MessagingException; import fredboat.commandmeta.abs.CommandContext; -import fredboat.db.EntityIO; +import fredboat.db.api.GuildConfigService; import fredboat.definitions.PermissionLevel; import fredboat.feature.I18n; import fredboat.jda.JdaEntityProvider; @@ -69,19 +69,19 @@ public class GuildPlayer extends AbstractPlayer { private final MusicTextChannelProvider musicTextChannelProvider; private final JdaEntityProvider jdaEntityProvider; private final AudioConnectionFacade audioConnectionFacade; - private final EntityIO entityIO; + private final GuildConfigService guildConfigService; @SuppressWarnings("LeakingThisInConstructor") public GuildPlayer(Guild guild, MusicTextChannelProvider musicTextChannelProvider, JdaEntityProvider jdaEntityProvider, - AudioConnectionFacade audioConnectionFacade, AudioPlayerManager audioPlayerManager, EntityIO entityIO, - Ratelimiter ratelimiter) { + AudioConnectionFacade audioConnectionFacade, AudioPlayerManager audioPlayerManager, + GuildConfigService guildConfigService, Ratelimiter ratelimiter) { super(guild.getId(), audioConnectionFacade); log.debug("Constructing GuildPlayer({})", guild.getIdLong()); this.jdaEntityProvider = jdaEntityProvider; this.musicTextChannelProvider = musicTextChannelProvider; this.audioConnectionFacade = audioConnectionFacade; - this.entityIO = entityIO; + this.guildConfigService = guildConfigService; onPlayHook = this::announceTrack; onErrorHook = this::handleError; @@ -423,7 +423,7 @@ private boolean isTrackAnnounceEnabled() { try { Guild guild = getGuild(); if (guild != null) { - enabled = entityIO.fetchGuildConfig(guild).isTrackAnnounce(); + enabled = guildConfigService.fetchGuildConfig(guild).isTrackAnnounce(); } } catch (Exception ignored) { } diff --git a/FredBoat/src/main/java/fredboat/audio/player/PlayerRegistry.java b/FredBoat/src/main/java/fredboat/audio/player/PlayerRegistry.java index de07eb3b9..117ec9058 100644 --- a/FredBoat/src/main/java/fredboat/audio/player/PlayerRegistry.java +++ b/FredBoat/src/main/java/fredboat/audio/player/PlayerRegistry.java @@ -26,7 +26,7 @@ package fredboat.audio.player; import com.sedmelluq.discord.lavaplayer.player.AudioPlayerManager; -import fredboat.db.EntityIO; +import fredboat.db.api.GuildConfigService; import fredboat.jda.JdaEntityProvider; import fredboat.util.ratelimit.Ratelimiter; import net.dv8tion.jda.core.entities.Guild; @@ -48,19 +48,19 @@ public class PlayerRegistry { private final Map registry = new ConcurrentHashMap<>(); private final JdaEntityProvider jdaEntityProvider; private final AudioConnectionFacade audioConnectionFacade; - private final EntityIO entityIO; + private final GuildConfigService guildConfigService; private final AudioPlayerManager audioPlayerManager; private final Ratelimiter ratelimiter; private final MusicTextChannelProvider musicTextChannelProvider; public PlayerRegistry(MusicTextChannelProvider musicTextChannelProvider, JdaEntityProvider jdaEntityProvider, - AudioConnectionFacade audioConnectionFacade, EntityIO entityIO, + AudioConnectionFacade audioConnectionFacade, GuildConfigService guildConfigService, @Qualifier("loadAudioPlayerManager") AudioPlayerManager audioPlayerManager, Ratelimiter ratelimiter) { this.musicTextChannelProvider = musicTextChannelProvider; this.jdaEntityProvider = jdaEntityProvider; this.audioConnectionFacade = audioConnectionFacade; - this.entityIO = entityIO; + this.guildConfigService = guildConfigService; this.audioPlayerManager = audioPlayerManager; this.ratelimiter = ratelimiter; } @@ -70,7 +70,7 @@ public GuildPlayer getOrCreate(@Nonnull Guild guild) { return registry.computeIfAbsent( guild.getIdLong(), guildId -> { GuildPlayer p = new GuildPlayer(guild, musicTextChannelProvider, jdaEntityProvider, - audioConnectionFacade, audioPlayerManager, entityIO, ratelimiter); + audioConnectionFacade, audioPlayerManager, guildConfigService, ratelimiter); p.setVolume(DEFAULT_VOLUME); return p; }); diff --git a/FredBoat/src/main/java/fredboat/command/config/ConfigCommand.java b/FredBoat/src/main/java/fredboat/command/config/ConfigCommand.java index 0aa467483..7507ba9fa 100644 --- a/FredBoat/src/main/java/fredboat/command/config/ConfigCommand.java +++ b/FredBoat/src/main/java/fredboat/command/config/ConfigCommand.java @@ -58,7 +58,7 @@ public void onInvoke(@Nonnull CommandContext context) { } private void printConfig(CommandContext context) { - GuildConfig gc = Launcher.getBotController().getEntityIO().fetchGuildConfig(context.guild); + GuildConfig gc = Launcher.getBotController().getGuildConfigService().fetchGuildConfig(context.guild); MessageBuilder mb = CentralMessaging.getClearThreadLocalMessageBuilder() .append(context.i18nFormat("configNoArgs", context.guild.getName())).append("\n") @@ -86,7 +86,7 @@ private void setConfig(CommandContext context) { switch (key) { case "track_announce": if (val.equalsIgnoreCase("true") | val.equalsIgnoreCase("false")) { - Launcher.getBotController().getEntityIO().transformGuildConfig( + Launcher.getBotController().getGuildConfigService().transformGuildConfig( context.guild, gc -> gc.setTrackAnnounce(Boolean.valueOf(val))); context.replyWithName("`track_announce` " + context.i18nFormat("configSetTo", val)); } else { @@ -95,7 +95,7 @@ private void setConfig(CommandContext context) { break; case "auto_resume": if (val.equalsIgnoreCase("true") | val.equalsIgnoreCase("false")) { - Launcher.getBotController().getEntityIO().transformGuildConfig( + Launcher.getBotController().getGuildConfigService().transformGuildConfig( context.guild, gc -> gc.setAutoResume(Boolean.valueOf(val))); context.replyWithName("`auto_resume` " + context.i18nFormat("configSetTo", val)); } else { diff --git a/FredBoat/src/main/java/fredboat/command/config/ModulesCommand.java b/FredBoat/src/main/java/fredboat/command/config/ModulesCommand.java index 9ffca37a8..8d76a681d 100644 --- a/FredBoat/src/main/java/fredboat/command/config/ModulesCommand.java +++ b/FredBoat/src/main/java/fredboat/command/config/ModulesCommand.java @@ -108,12 +108,12 @@ public void onInvoke(@Nonnull CommandContext context) { output = context.i18nFormat("moduleDisable", "**" + context.i18n(module.translationKey) + "**"); } - Launcher.getBotController().getEntityIO().transformGuildModules(context.guild, transform); + Launcher.getBotController().getGuildModulesService().transformGuildModules(context.guild, transform); context.reply(output);//if the transaction right above this line fails, it won't be reached, which is intended } private static void displayModuleStatus(@Nonnull CommandContext context) { - GuildModules gm = Launcher.getBotController().getEntityIO().fetchGuildModules(context.guild); + GuildModules gm = Launcher.getBotController().getGuildModulesService().fetchGuildModules(context.guild); Function moduleStatusFormatter = moduleStatusLine(gm, context); String moduleStatus = ""; diff --git a/FredBoat/src/main/java/fredboat/command/config/PermissionsCommand.java b/FredBoat/src/main/java/fredboat/command/config/PermissionsCommand.java index dbf1a86c1..44d3d29fc 100644 --- a/FredBoat/src/main/java/fredboat/command/config/PermissionsCommand.java +++ b/FredBoat/src/main/java/fredboat/command/config/PermissionsCommand.java @@ -136,7 +136,7 @@ public void remove(CommandContext context) { context.replyWithName(context.i18nFormat("permsRemoved", mentionableToName(selected), permissionLevel)); return gp.setFromEnum(permissionLevel, newList); }; - Launcher.getBotController().getEntityIO().transformGuildPerms(context.guild, transformation); + Launcher.getBotController().getGuildPermsService().transformGuildPerms(context.guild, transformation); } public void add(CommandContext context) { @@ -166,13 +166,13 @@ public void add(CommandContext context) { TextUtils.escapeMarkdown(mentionableToName(selected)), permissionLevel)); return gp.setFromEnum(permissionLevel, newList); }; - Launcher.getBotController().getEntityIO().transformGuildPerms(context.guild, transformation); + Launcher.getBotController().getGuildPermsService().transformGuildPerms(context.guild, transformation); } public void list(CommandContext context) { Guild guild = context.guild; Member invoker = context.invoker; - GuildPermissions gp = Launcher.getBotController().getEntityIO().fetchGuildPermissions(guild); + GuildPermissions gp = Launcher.getBotController().getGuildPermsService().fetchGuildPermissions(guild); List mentionables = idsToMentionables(guild, gp.getFromEnum(permissionLevel)); diff --git a/FredBoat/src/main/java/fredboat/command/config/PrefixCommand.java b/FredBoat/src/main/java/fredboat/command/config/PrefixCommand.java index 6722bf389..41319a5df 100644 --- a/FredBoat/src/main/java/fredboat/command/config/PrefixCommand.java +++ b/FredBoat/src/main/java/fredboat/command/config/PrefixCommand.java @@ -69,7 +69,7 @@ public PrefixCommand(@Nullable CacheMetricsCollector cacheMetrics, @Nonnull Stri .expireAfterAccess(1, TimeUnit.MINUTES) //evict inactive guilds .concurrencyLevel(Launcher.getBotController().getCredentials().getRecommendedShardCount()) //each shard has a thread (main JDA thread) accessing this cache many times .build(CacheLoader.asyncReloading(CacheLoader.from( - guildId -> Launcher.getBotController().getEntityIO().getPrefix(new GuildBotComposite(guildId, DiscordUtil.getBotId(Launcher.getBotController().getCredentials())))), + guildId -> Launcher.getBotController().getPrefixService().getPrefix(new GuildBotComposite(guildId, DiscordUtil.getBotId(Launcher.getBotController().getCredentials())))), Launcher.getBotController().getExecutor())); @Nonnull @@ -110,7 +110,7 @@ public void onInvoke(@Nonnull CommandContext context) { newPrefix = context.rawArgs; } - Launcher.getBotController().getEntityIO().transformPrefix(context.guild, prefixEntity -> prefixEntity.setPrefix(newPrefix)); + Launcher.getBotController().getPrefixService().transformPrefix(context.guild, prefixEntity -> prefixEntity.setPrefix(newPrefix)); //we could do a put instead of invalidate here and probably safe one lookup, but that undermines the database // as being the single source of truth for prefixes diff --git a/FredBoat/src/main/java/fredboat/commandmeta/abs/CommandContext.java b/FredBoat/src/main/java/fredboat/commandmeta/abs/CommandContext.java index e0232c9f5..978062d41 100644 --- a/FredBoat/src/main/java/fredboat/commandmeta/abs/CommandContext.java +++ b/FredBoat/src/main/java/fredboat/commandmeta/abs/CommandContext.java @@ -113,7 +113,7 @@ public boolean hasArguments() { } public Collection getEnabledModules() { - return Launcher.getBotController().getEntityIO().fetchGuildModules(this.guild).getEnabledModules(); + return Launcher.getBotController().getGuildModulesService().fetchGuildModules(this.guild).getEnabledModules(); } @Override diff --git a/FredBoat/src/main/java/fredboat/db/EntityIO.java b/FredBoat/src/main/java/fredboat/db/EntityService.java similarity index 89% rename from FredBoat/src/main/java/fredboat/db/EntityIO.java rename to FredBoat/src/main/java/fredboat/db/EntityService.java index 3885c1435..a6c19d676 100644 --- a/FredBoat/src/main/java/fredboat/db/EntityIO.java +++ b/FredBoat/src/main/java/fredboat/db/EntityService.java @@ -52,10 +52,10 @@ */ @SuppressWarnings("UnusedReturnValue") @Component -public class EntityIO implements BlacklistIO, GuildConfigIO, GuildDataIO, GuildModulesIO, GuildPermsIO, PrefixIO, - SearchResultIO { +public class EntityService implements BlacklistService, GuildConfigService, GuildDataService, GuildModulesService, GuildPermsService, PrefixService, + SearchResultService { - private static final Logger log = LoggerFactory.getLogger(EntityIO.class); + private static final Logger log = LoggerFactory.getLogger(EntityService.class); private final ConfigPropertiesProvider configProvider; @@ -69,9 +69,9 @@ public class EntityIO implements BlacklistIO, GuildConfigIO, GuildDataIO, GuildM @Nullable private final SearchResultRepo searchResultRepo; - public EntityIO(ConfigPropertiesProvider configProvider, BlacklistRepo blacklistRepo, GuildConfigRepo guildConfigRepo, - GuildDataRepo guildDataRepo, GuildModulesRepo guildModulesRepo, GuildPermsRepo guildPermsRepo, - PrefixRepo prefixRepo, @Nullable SearchResultRepo searchResultRepo) { + public EntityService(ConfigPropertiesProvider configProvider, BlacklistRepo blacklistRepo, GuildConfigRepo guildConfigRepo, + GuildDataRepo guildDataRepo, GuildModulesRepo guildModulesRepo, GuildPermsRepo guildPermsRepo, + PrefixRepo prefixRepo, @Nullable SearchResultRepo searchResultRepo) { this.configProvider = configProvider; this.blacklistRepo = blacklistRepo; this.guildConfigRepo = guildConfigRepo; @@ -91,32 +91,32 @@ private static T fetchUserFriendly(NonnullSupplier operation) { try { return operation.get(); } catch (DatabaseException | BackendException e) { - log.error("EntityIO database operation failed", e); + log.error("EntityService database operation failed", e); throw new DatabaseNotReadyException(e); } } /** - * Same as {@link EntityIO#fetchUserFriendly(NonnullSupplier)}, just with a nullable return. + * Same as {@link EntityService#fetchUserFriendly(NonnullSupplier)}, just with a nullable return. */ @Nullable private static T getUserFriendly(Supplier operation) { try { return operation.get(); } catch (DatabaseException | BackendException e) { - log.error("EntityIO database operation failed", e); + log.error("EntityService database operation failed", e); throw new DatabaseNotReadyException(e); } } /** - * Same as {@link EntityIO#fetchUserFriendly(NonnullSupplier)}, just without returning anything + * Same as {@link EntityService#fetchUserFriendly(NonnullSupplier)}, just without returning anything */ private static void doUserFriendly(Runnable operation) { try { operation.run(); } catch (DatabaseException | BackendException e) { - log.error("EntityIO database operation failed", e); + log.error("EntityService database operation failed", e); throw new DatabaseNotReadyException(e); } } diff --git a/FredBoat/src/main/java/fredboat/event/EventListenerBoat.java b/FredBoat/src/main/java/fredboat/event/EventListenerBoat.java index 802748172..44fca66a4 100644 --- a/FredBoat/src/main/java/fredboat/event/EventListenerBoat.java +++ b/FredBoat/src/main/java/fredboat/event/EventListenerBoat.java @@ -38,8 +38,8 @@ import fredboat.commandmeta.CommandManager; import fredboat.commandmeta.abs.CommandContext; import fredboat.config.property.AppConfig; -import fredboat.db.api.GuildConfigIO; -import fredboat.db.api.GuildDataIO; +import fredboat.db.api.GuildConfigService; +import fredboat.db.api.GuildDataService; import fredboat.db.entity.main.GuildData; import fredboat.definitions.Module; import fredboat.definitions.PermissionLevel; @@ -94,14 +94,14 @@ public class EventListenerBoat extends AbstractEventListener { private final JdaEntityProvider jdaEntityProvider; private final Ratelimiter ratelimiter; private final AppConfig appConfig; - private final GuildDataIO guildDataIO; - private final GuildConfigIO guildConfigIO; + private final GuildDataService guildDataService; + private final GuildConfigService guildConfigService; public EventListenerBoat(CommandManager commandManager, CommandContextParser commandContextParser, PlayerRegistry playerRegistry, CacheMetricsCollector cacheMetrics, ShardStatsCounterProvider shardStatsCounterProvider, JdaEntityProvider jdaEntityProvider, - Ratelimiter ratelimiter, AppConfig appConfig, GuildDataIO guildDataIO, - GuildConfigIO guildConfigIO) { + Ratelimiter ratelimiter, AppConfig appConfig, GuildDataService guildDataService, + GuildConfigService guildConfigService) { this.commandManager = commandManager; this.commandContextParser = commandContextParser; this.playerRegistry = playerRegistry; @@ -109,8 +109,8 @@ public EventListenerBoat(CommandManager commandManager, CommandContextParser com this.jdaEntityProvider = jdaEntityProvider; this.ratelimiter = ratelimiter; this.appConfig = appConfig; - this.guildDataIO = guildDataIO; - this.guildConfigIO = guildConfigIO; + this.guildDataService = guildDataService; + this.guildConfigService = guildConfigService; cacheMetrics.addCache("messagesToDeleteIfIdDeleted", messagesToDeleteIfIdDeleted); } @@ -301,7 +301,7 @@ private void checkForAutoResume(VoiceChannel joinedChannel, Member joined) { && player.getPlayingTrack() != null && joinedChannel.getMembers().contains(guild.getSelfMember()) && player.getHumanUsersInCurrentVC().size() > 0 - && guildConfigIO.fetchGuildConfig(guild).isAutoResume() + && guildConfigService.fetchGuildConfig(guild).isAutoResume() ) { player.setPause(false); TextChannel activeTextChannel = player.getActiveTextChannel(); @@ -382,7 +382,7 @@ private void sendHelloOnJoin(@Nonnull Guild guild) { //filter guilds that already received a hello message // useful for when discord trolls us with fake guild joins // or to prevent it send repeatedly due to kick and reinvite - GuildData gd = guildDataIO.fetchGuildData(guild); + GuildData gd = guildDataService.fetchGuildData(guild); if (gd.getTimestampHelloSent() > 0) { return; } @@ -404,6 +404,6 @@ private void sendHelloOnJoin(@Nonnull Guild guild) { //send actual hello message and persist on success CentralMessaging.sendMessage(channel, HelloCommand.getHello(guild), - __ -> guildDataIO.transformGuildData(guild, GuildData::helloSent)); + __ -> guildDataService.transformGuildData(guild, GuildData::helloSent)); } } diff --git a/FredBoat/src/main/java/fredboat/feature/I18n.java b/FredBoat/src/main/java/fredboat/feature/I18n.java index 15b59d6c8..78b705bc2 100644 --- a/FredBoat/src/main/java/fredboat/feature/I18n.java +++ b/FredBoat/src/main/java/fredboat/feature/I18n.java @@ -96,7 +96,7 @@ public static ResourceBundle get(@Nullable Guild guild) { @Nonnull public static FredBoatLocale getLocale(@Nonnull Guild guild) { try { - return LANGS.getOrDefault(Launcher.getBotController().getEntityIO().fetchGuildConfig(guild).getLang(), DEFAULT); + return LANGS.getOrDefault(Launcher.getBotController().getGuildConfigService().fetchGuildConfig(guild).getLang(), DEFAULT); } catch (DatabaseNotReadyException e) { //don't log spam the full exceptions or logs return DEFAULT; @@ -110,7 +110,7 @@ public static void set(@Nonnull Guild guild, @Nonnull String lang) throws Langua if (!LANGS.containsKey(lang)) throw new LanguageNotSupportedException("Language not found"); - Launcher.getBotController().getEntityIO().transformGuildConfig(guild, config -> config.setLang(lang)); + Launcher.getBotController().getGuildConfigService().transformGuildConfig(guild, config -> config.setLang(lang)); } public static class FredBoatLocale { diff --git a/FredBoat/src/main/java/fredboat/main/BotController.java b/FredBoat/src/main/java/fredboat/main/BotController.java index 35ead96b6..3f6ce691a 100644 --- a/FredBoat/src/main/java/fredboat/main/BotController.java +++ b/FredBoat/src/main/java/fredboat/main/BotController.java @@ -5,7 +5,8 @@ import fredboat.audio.player.AudioConnectionFacade; import fredboat.audio.player.PlayerRegistry; import fredboat.config.property.*; -import fredboat.db.EntityIO; +import fredboat.db.EntityService; +import fredboat.db.api.*; import fredboat.event.EventListenerBoat; import fredboat.feature.metrics.BotMetrics; import fredboat.feature.metrics.Metrics; @@ -37,7 +38,7 @@ public class BotController { //central event listener that all events by all shards pass through private final EventListenerBoat mainEventListener; private final ShutdownHandler shutdownHandler; - private final EntityIO entityIO; + private final EntityService entityService; private final PlayerRegistry playerRegistry; private final JdaEntityProvider jdaEntityProvider; private final BotMetrics botMetrics; @@ -48,7 +49,7 @@ public class BotController { public BotController(ConfigPropertiesProvider configProvider, AudioConnectionFacade audioConnectionFacade, ShardManager shardManager, EventListenerBoat eventListenerBoat, ShutdownHandler shutdownHandler, - EntityIO entityIO, ExecutorService executor, HibernateStatisticsCollector hibernateStats, + EntityService entityService, ExecutorService executor, HibernateStatisticsCollector hibernateStats, PlayerRegistry playerRegistry, JdaEntityProvider jdaEntityProvider, BotMetrics botMetrics, @Qualifier("loadAudioPlayerManager") AudioPlayerManager audioPlayerManager, Ratelimiter ratelimiter) { @@ -57,7 +58,7 @@ public BotController(ConfigPropertiesProvider configProvider, AudioConnectionFac this.shardManager = shardManager; this.mainEventListener = eventListenerBoat; this.shutdownHandler = shutdownHandler; - this.entityIO = entityIO; + this.entityService = entityService; try { hibernateStats.register(); //call this exactly once after all db connections have been created } catch (IllegalStateException ignored) {}//can happen when using the REST repos @@ -108,9 +109,24 @@ public ShardManager getShardManager() { return shardManager; } - @Nonnull - public EntityIO getEntityIO() { - return entityIO; + public GuildConfigService getGuildConfigService() { + return entityService; + } + + public GuildModulesService getGuildModulesService() { + return entityService; + } + + public GuildPermsService getGuildPermsService() { + return entityService; + } + + public PrefixService getPrefixService() { + return entityService; + } + + public SearchResultService getSearchResultService() { + return entityService; } public PlayerRegistry getPlayerRegistry() { diff --git a/FredBoat/src/main/java/fredboat/perms/PermsUtil.java b/FredBoat/src/main/java/fredboat/perms/PermsUtil.java index 5844cae81..8477fd8ae 100644 --- a/FredBoat/src/main/java/fredboat/perms/PermsUtil.java +++ b/FredBoat/src/main/java/fredboat/perms/PermsUtil.java @@ -55,7 +55,7 @@ public static PermissionLevel getPerms(Member member) { return member.hasPermission(Permission.MESSAGE_MANAGE) ? PermissionLevel.DJ : PermissionLevel.USER; } - GuildPermissions gp = Launcher.getBotController().getEntityIO().fetchGuildPermissions(member.getGuild()); + GuildPermissions gp = Launcher.getBotController().getGuildPermsService().fetchGuildPermissions(member.getGuild()); if (checkList(gp.getAdminList(), member)) return PermissionLevel.ADMIN; if (checkList(gp.getDjList(), member)) return PermissionLevel.DJ; diff --git a/FredBoat/src/main/java/fredboat/util/ratelimit/Blacklist.java b/FredBoat/src/main/java/fredboat/util/ratelimit/Blacklist.java index bc56393a5..2ec6b54e1 100644 --- a/FredBoat/src/main/java/fredboat/util/ratelimit/Blacklist.java +++ b/FredBoat/src/main/java/fredboat/util/ratelimit/Blacklist.java @@ -24,7 +24,7 @@ package fredboat.util.ratelimit; -import fredboat.db.api.BlacklistIO; +import fredboat.db.api.BlacklistService; import fredboat.db.entity.main.BlacklistEntry; import fredboat.feature.metrics.Metrics; import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; @@ -66,14 +66,14 @@ public class Blacklist { //users that can never be blacklisted private final Set userWhiteList; - private final BlacklistIO blacklistIO; + private final BlacklistService blacklistService; - public Blacklist(BlacklistIO blacklistIO, Set userWhiteList, long rateLimitHitsBeforeBlacklist) { - this.blacklistIO = blacklistIO; + public Blacklist(BlacklistService blacklistService, Set userWhiteList, long rateLimitHitsBeforeBlacklist) { + this.blacklistService = blacklistService; this.blacklist = new Long2ObjectOpenHashMap<>(); //load blacklist from database - for (BlacklistEntry ble : blacklistIO.loadBlacklist()) { + for (BlacklistEntry ble : blacklistService.loadBlacklist()) { blacklist.put(ble.id, ble); } @@ -140,7 +140,7 @@ public long hitRateLimit(long id) { } //persist it //if this turns up to be a performance bottleneck, have an agent run that persists the blacklist occasionally - blEntry = blacklistIO.mergeBlacklistEntry(blEntry); + blEntry = blacklistService.mergeBlacklistEntry(blEntry); blacklist.put(blEntry.id, blEntry); return blacklistingLength; } @@ -166,7 +166,7 @@ private synchronized BlacklistEntry getOrCreateBlacklistEntry(long id) { */ public synchronized void liftBlacklist(long id) { blacklist.remove(id); - blacklistIO.deleteBlacklistEntry(id); + blacklistService.deleteBlacklistEntry(id); } /** diff --git a/FredBoat/src/main/java/fredboat/util/ratelimit/Ratelimiter.java b/FredBoat/src/main/java/fredboat/util/ratelimit/Ratelimiter.java index 8a86f2368..e7c3b11f0 100644 --- a/FredBoat/src/main/java/fredboat/util/ratelimit/Ratelimiter.java +++ b/FredBoat/src/main/java/fredboat/util/ratelimit/Ratelimiter.java @@ -30,7 +30,7 @@ import fredboat.command.util.WeatherCommand; import fredboat.commandmeta.abs.Command; import fredboat.config.property.AppConfig; -import fredboat.db.api.BlacklistIO; +import fredboat.db.api.BlacklistService; import fredboat.feature.metrics.Metrics; import fredboat.messaging.internal.Context; import fredboat.util.Tuple2; @@ -59,7 +59,7 @@ public class Ratelimiter { @Nullable private Blacklist autoBlacklist = null; - public Ratelimiter(AppConfig appConfig, ExecutorService executor, BlacklistIO blacklistIO) { + public Ratelimiter(AppConfig appConfig, ExecutorService executor, BlacklistService blacklistService) { Set whitelist = ConcurrentHashMap.newKeySet(); //only works for those admins who are added with their userId and not through a roleId @@ -69,7 +69,7 @@ public Ratelimiter(AppConfig appConfig, ExecutorService executor, BlacklistIO bl ratelimits = new ArrayList<>(); if (appConfig.useAutoBlacklist()) { - autoBlacklist = new Blacklist(blacklistIO, whitelist, RATE_LIMIT_HITS_BEFORE_BLACKLIST); + autoBlacklist = new Blacklist(blacklistService, whitelist, RATE_LIMIT_HITS_BEFORE_BLACKLIST); } //sort these by harsher limits coming first diff --git a/FredBoat/src/main/java/fredboat/util/rest/TrackSearcher.java b/FredBoat/src/main/java/fredboat/util/rest/TrackSearcher.java index 29a382f3b..30208d9b2 100644 --- a/FredBoat/src/main/java/fredboat/util/rest/TrackSearcher.java +++ b/FredBoat/src/main/java/fredboat/util/rest/TrackSearcher.java @@ -117,7 +117,7 @@ public AudioPlaylist searchForTracks(String query, long cacheMaxAge, int timeout if (!lavaplayerResult.getTracks().isEmpty()) { log.debug("Loaded search result {} {} from lavaplayer", provider, query); // got a search result? cache and return it - Launcher.getBotController().getExecutor().execute(() -> Launcher.getBotController().getEntityIO() + Launcher.getBotController().getExecutor().execute(() -> Launcher.getBotController().getSearchResultService() .merge(new SearchResult(audioPlayerManager, provider, query, lavaplayerResult))); Metrics.searchHits.labels("lavaplayer-" + provider.name().toLowerCase()).inc(); return lavaplayerResult; @@ -142,7 +142,7 @@ public AudioPlaylist searchForTracks(String query, long cacheMaxAge, int timeout if (!youtubeApiResult.getTracks().isEmpty()) { log.debug("Loaded search result {} {} from Youtube API", provider, query); // got a search result? cache and return it - Launcher.getBotController().getExecutor().execute(() -> Launcher.getBotController().getEntityIO() + Launcher.getBotController().getExecutor().execute(() -> Launcher.getBotController().getSearchResultService() .merge(new SearchResult(audioPlayerManager, provider, query, youtubeApiResult))); Metrics.searchHits.labels("youtube-api").inc(); return youtubeApiResult; @@ -171,7 +171,7 @@ public AudioPlaylist searchForTracks(String query, long cacheMaxAge, int timeout private AudioPlaylist fromCache(SearchProvider provider, String searchTerm, long cacheMaxAge) { try { SearchResult.SearchResultId id = new SearchResult.SearchResultId(provider, searchTerm); - SearchResult searchResult = Launcher.getBotController().getEntityIO().getSearchResult(id, cacheMaxAge); + SearchResult searchResult = Launcher.getBotController().getSearchResultService().getSearchResult(id, cacheMaxAge); return searchResult != null ? searchResult.getSearchResult(audioPlayerManager) : null; } catch (DatabaseNotReadyException ignored) { log.warn("Could not retrieve cached search result from database."); From c260bfcce9d9f7fdc9384ed1b07d721c1e604556 Mon Sep 17 00:00:00 2001 From: Napster Date: Thu, 8 Mar 2018 16:23:47 +0100 Subject: [PATCH 33/41] Move logback config back to application project --- {Shared => FredBoat}/src/main/resources/logback.xml | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {Shared => FredBoat}/src/main/resources/logback.xml (100%) diff --git a/Shared/src/main/resources/logback.xml b/FredBoat/src/main/resources/logback.xml similarity index 100% rename from Shared/src/main/resources/logback.xml rename to FredBoat/src/main/resources/logback.xml From 8f0a4f9d70f4d874df3b67b2f20e0bf7892a6c13 Mon Sep 17 00:00:00 2001 From: Napster Date: Thu, 8 Mar 2018 17:52:14 +0100 Subject: [PATCH 34/41] Adjust backend api version handling --- .../fredboat/config/RepoConfiguration.java | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/FredBoat/src/main/java/fredboat/config/RepoConfiguration.java b/FredBoat/src/main/java/fredboat/config/RepoConfiguration.java index 7023a833a..ef0bde20d 100644 --- a/FredBoat/src/main/java/fredboat/config/RepoConfiguration.java +++ b/FredBoat/src/main/java/fredboat/config/RepoConfiguration.java @@ -38,6 +38,9 @@ import org.springframework.context.annotation.Configuration; import javax.annotation.Nullable; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; /** * Created by napster on 24.02.18. @@ -57,13 +60,13 @@ public RepoConfiguration(BackendConfig backendConfig, ShutdownHandler shutdownHa this.backendConfig = backendConfig; log.info("Contacting the backend"); - Version apiVersion = null; + String[] apiVersions = null; int attempts = 0; Exception lastException = null; - while (apiVersion == null && attempts < 100) { //total time is 100 sec + while ((apiVersions == null || apiVersions.length < 1) && attempts < 100) { //total time is 100 sec try { - String s = http.get(backendConfig.getHost() + "info/version").auth(backendConfig.getBasicAuth()).asString(); - apiVersion = gson.fromJson(s, Version.class); + String s = http.get(backendConfig.getHost() + "info/api/versions").auth(backendConfig.getBasicAuth()).asString(); + apiVersions = gson.fromJson(s, String[].class); } catch (Exception ignored) { lastException = ignored; attempts++; @@ -71,16 +74,25 @@ public RepoConfiguration(BackendConfig backendConfig, ShutdownHandler shutdownHa } } - if (apiVersion == null) { + if (apiVersions == null || apiVersions.length < 1) { log.error("Could not contact the backend. Please make sure it is started and configuration values are correct", lastException); shutdownHandler.shutdown(ExitCodes.EXIT_CODE_ERROR); return; } - if (apiVersion.getNumber() >= RestRepo.API_VERSION) { - log.info("Backend API version is v{}", apiVersion.getNumber()); + List supportedApiVersions = Arrays.stream(apiVersions).map(v -> { + if (!v.startsWith("v")) return "v" + v; + else return v; + }).collect(Collectors.toList()); + log.info("Supported Backend API versions: {}", String.join(", ", supportedApiVersions)); + + + String ourVersion = Integer.toString(RestRepo.API_VERSION); + if (supportedApiVersions.contains(ourVersion) + || supportedApiVersions.contains("v" + ourVersion)) { + log.info("Using Backend API v{}", ourVersion); } else { - log.error("Backend API is version v{}, but this FredBoat expects at least v{}", apiVersion.getNumber(), RestRepo.API_VERSION); + log.error("Backend API does not support our expected version v{}. Update the backend, or roll back this FredBoat version!", ourVersion); shutdownHandler.shutdown(ExitCodes.EXIT_CODE_ERROR); } } @@ -120,16 +132,4 @@ public PrefixRepo prefixRepo() { public SearchResultRepo searchResultRepo() { return new RestSearchResultRepo(backendConfig.getHost(), http, gson, backendConfig.getBasicAuth()); } - - private static class Version { - private int number = -1; - - public void setNumber(int number) { - this.number = number; - } - - public int getNumber() { - return number; - } - } } From e9b2cf434ba89daf7d1e73982b1164ef629c8f80 Mon Sep 17 00:00:00 2001 From: Napster Date: Fri, 9 Mar 2018 00:01:54 +0100 Subject: [PATCH 35/41] Add logs volume for backend service --- docker-compose.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index f238acd6c..54f45c6de 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -52,6 +52,7 @@ services: - db volumes: - ./backend.yaml:/opt/Backend/backend.yaml + - ./backend_logs:/opt/Backend/logs # Need a bigger memory size or any other custom JVM args? uncomment and edit the line below accordingly #entrypoint: java -Xmx128m -jar Backend.jar @@ -74,7 +75,7 @@ services: - 1356:1356 volumes: - ./fredboat.yaml:/opt/FredBoat/fredboat.yaml - - ./logs:/opt/FredBoat/logs + - ./fredboat_logs:/opt/FredBoat/logs - ./music_persistence:/opt/FredBoat/music_persistence # Local audio files (dev branch only currently) # If your music directory looks like this: /home/user/music/directory/rickroll.mp3 or C:\Users\user\Music\rickroll.mp3 From 75d3c5b870f4d872d8e45ac11947023635eddc45 Mon Sep 17 00:00:00 2001 From: Napster Date: Fri, 9 Mar 2018 01:19:52 +0100 Subject: [PATCH 36/41] Backend has its own repository --- Backend/.gitignore | 2 - Backend/backend.yaml.example | 16 -- Backend/build.gradle | 49 ----- .../java/fredboat/backend/Application.java | 106 ----------- .../fredboat/backend/config/AppConfig.java | 175 ------------------ .../backend/config/RequestLoggerConfig.java | 66 ------- .../backend/config/SecurityConfig.java | 62 ------- .../fredboat/backend/config/package-info.java | 29 --- .../java/fredboat/backend/package-info.java | 29 --- .../backend/rest/BlacklistController.java | 57 ------ .../backend/rest/EntityController.java | 70 ------- .../backend/rest/GuildConfigController.java | 45 ----- .../backend/rest/GuildDataController.java | 45 ----- .../backend/rest/GuildModulesController.java | 45 ----- .../backend/rest/GuildPermsController.java | 45 ----- .../backend/rest/PrefixController.java | 60 ------ .../backend/rest/SearchResultController.java | 57 ------ .../fredboat/backend/rest/package-info.java | 29 --- ...itional-spring-configuration-metadata.json | 14 -- settings.gradle | 2 - 20 files changed, 1003 deletions(-) delete mode 100644 Backend/.gitignore delete mode 100644 Backend/backend.yaml.example delete mode 100644 Backend/build.gradle delete mode 100644 Backend/src/main/java/fredboat/backend/Application.java delete mode 100644 Backend/src/main/java/fredboat/backend/config/AppConfig.java delete mode 100644 Backend/src/main/java/fredboat/backend/config/RequestLoggerConfig.java delete mode 100644 Backend/src/main/java/fredboat/backend/config/SecurityConfig.java delete mode 100644 Backend/src/main/java/fredboat/backend/config/package-info.java delete mode 100644 Backend/src/main/java/fredboat/backend/package-info.java delete mode 100644 Backend/src/main/java/fredboat/backend/rest/BlacklistController.java delete mode 100644 Backend/src/main/java/fredboat/backend/rest/EntityController.java delete mode 100644 Backend/src/main/java/fredboat/backend/rest/GuildConfigController.java delete mode 100644 Backend/src/main/java/fredboat/backend/rest/GuildDataController.java delete mode 100644 Backend/src/main/java/fredboat/backend/rest/GuildModulesController.java delete mode 100644 Backend/src/main/java/fredboat/backend/rest/GuildPermsController.java delete mode 100644 Backend/src/main/java/fredboat/backend/rest/PrefixController.java delete mode 100644 Backend/src/main/java/fredboat/backend/rest/SearchResultController.java delete mode 100644 Backend/src/main/java/fredboat/backend/rest/package-info.java delete mode 100644 Backend/src/main/resources/META-INF/additional-spring-configuration-metadata.json diff --git a/Backend/.gitignore b/Backend/.gitignore deleted file mode 100644 index d26dd62cf..000000000 --- a/Backend/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/logs/ -application.yml diff --git a/Backend/backend.yaml.example b/Backend/backend.yaml.example deleted file mode 100644 index edde0159a..000000000 --- a/Backend/backend.yaml.example +++ /dev/null @@ -1,16 +0,0 @@ -spring: - http: - converters: - preferred-json-mapper: gson -fredboat: - db: - main: - jdbcUrl: "" - cache: - jdbcUrl: "" - security: - admins: - - name: fredbotto - pass: - - name: patronbotto - pass: diff --git a/Backend/build.gradle b/Backend/build.gradle deleted file mode 100644 index fc93f3384..000000000 --- a/Backend/build.gradle +++ /dev/null @@ -1,49 +0,0 @@ -apply plugin: 'propdeps' -apply plugin: 'propdeps-idea' -apply plugin: 'org.springframework.boot' - - -description = 'FredBoat backend, providing REST database services' -version '1.0' -ext { - moduleName = 'Backend' -} - -bootRun { - //compiling tests during bootRun increases the likelyhood of catching broken tests locally instead of on the CI - dependsOn compileTestJava - - //pass in custom jvm args - // source: https://stackoverflow.com/a/25079415 - // example: ./gradlew bootRun -PjvmArgs="--illegal-access=debug -Dwhatever=value" - if (project.hasProperty('jvmArgs')) { - jvmArgs project.jvmArgs.split('\\s+') - } -} - -bootJar { - archiveName = "Backend.jar" - doLast { - //copies the jar into a place where the Dockerfile can find it easily (and users maybe too) - copy { - from 'build/libs/Backend.jar' - into '.' - } - } -} - -dependencies { - compile project(':Database') - - - //versioning is handled by spring - compile "org.springframework.boot:spring-boot-starter-data-jpa:$springBootVersion" - compile "org.springframework.boot:spring-boot-starter-web:$springBootVersion" - compile "org.springframework.boot:spring-boot-starter-security:$springBootVersion" - testCompile "org.springframework.boot:spring-boot-starter-test:$springBootVersion" - optional "org.springframework.boot:spring-boot-configuration-processor:$springBootVersion" -} - -//required by spring boot configuration processor -compileJava.dependsOn(processResources) - diff --git a/Backend/src/main/java/fredboat/backend/Application.java b/Backend/src/main/java/fredboat/backend/Application.java deleted file mode 100644 index 45bdcfecf..000000000 --- a/Backend/src/main/java/fredboat/backend/Application.java +++ /dev/null @@ -1,106 +0,0 @@ -/* - * - * MIT License - * - * Copyright (c) 2017-2018 Frederik Ar. Mikkelsen - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package fredboat.backend; - -import fredboat.db.repositories.api.*; -import fredboat.db.repositories.impl.*; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration; -import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; -import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration; -import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Primary; -import space.npstr.sqlsauce.DatabaseWrapper; - -/** - * Created by napster on 16.02.18. - */ -@SpringBootApplication -@EnableAutoConfiguration(exclude = { //we handle these ourselves via the DatabaseManager - DataSourceAutoConfiguration.class, - DataSourceTransactionManagerAutoConfiguration.class, - HibernateJpaAutoConfiguration.class, - FlywayAutoConfiguration.class -}) -public class Application { - - public static final String API_VERSION = "v1"; - - public static void main(String[] args) { - System.setProperty("spring.config.name", "backend"); - SpringApplication.run(Application.class, args); - } - - - //main db repos - @Bean - @Primary - public GuildConfigRepo guildConfigRepo(DatabaseWrapper wrapper) { - return new SqlSauceGuildConfigRepo(wrapper); - } - - @Bean - @Primary - public BlacklistRepo blacklistRepo(DatabaseWrapper wrapper) { - return new SqlSauceBlacklistRepo(wrapper); - } - - @Bean - @Primary - public GuildDataRepo guildDataRepo(DatabaseWrapper wrapper) { - return new SqlSauceGuildDataRepo(wrapper); - } - - @Bean - @Primary - public GuildModulesRepo guildModulesRepo(DatabaseWrapper wrapper) { - return new SqlSauceGuildModulesRepo(wrapper); - } - - @Bean - @Primary - public GuildPermsRepo guildPermsRepo(DatabaseWrapper wrapper) { - return new SqlSauceGuildPermsRepo(wrapper); - } - - @Bean - @Primary - public PrefixRepo prefixRepo(DatabaseWrapper wrapper) { - return new SqlSaucePrefixRepo(wrapper); - } - - - //cache db repos - @Bean - @Primary - public SearchResultRepo searchResultRepo(@Qualifier("cacheDbWrapper") DatabaseWrapper wrapper) { - return new SqlSauceSearchResultRepo(wrapper); - } -} diff --git a/Backend/src/main/java/fredboat/backend/config/AppConfig.java b/Backend/src/main/java/fredboat/backend/config/AppConfig.java deleted file mode 100644 index f2434a008..000000000 --- a/Backend/src/main/java/fredboat/backend/config/AppConfig.java +++ /dev/null @@ -1,175 +0,0 @@ -/* - * - * MIT License - * - * Copyright (c) 2017-2018 Frederik Ar. Mikkelsen - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package fredboat.backend.config; - -import fredboat.db.DatabaseManager; -import org.springframework.beans.factory.config.ConfigurableBeanFactory; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Primary; -import org.springframework.context.annotation.Scope; -import org.springframework.orm.jpa.JpaVendorAdapter; -import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; -import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; -import space.npstr.sqlsauce.DatabaseWrapper; - -import javax.annotation.Nullable; -import java.util.ArrayList; -import java.util.List; - -/** - * Created by napster on 16.02.18. - * - * Mirrors the fredboat tree of the application.yaml - */ -@ConfigurationProperties(prefix = "fredboat") -@Configuration -@EnableConfigurationProperties -public class AppConfig { - - @Bean("databaseManager") - @Scope(ConfigurableBeanFactory.SCOPE_SINGLETON) - public DatabaseManager getDatabaseManager(Db dbConfig) { - //todo improve these parameters - return new DatabaseManager(null, null, - 4, "Backend", true, - dbConfig.getMain().getJdbcUrl(), null, - dbConfig.getCache().getJdbcUrl(), null, - (puName, dataSource, properties, entityPackages) -> { - LocalContainerEntityManagerFactoryBean emfb = new LocalContainerEntityManagerFactoryBean(); - emfb.setDataSource(dataSource); - emfb.setPackagesToScan(entityPackages.toArray(new String[entityPackages.size()])); - - JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter(); - emfb.setJpaVendorAdapter(vendorAdapter); - emfb.setJpaProperties(properties); - - emfb.afterPropertiesSet(); //initiate creation of the native emf - return emfb.getNativeEntityManagerFactory(); - }); - } - - @Primary - @Bean("mainDbWrapper") - public DatabaseWrapper getMainDbWrapper(DatabaseManager databaseManager) { - return databaseManager.getMainDbWrapper(); - } - - @Nullable - @Bean("cacheDbWrapper") - public DatabaseWrapper getCacheDbWrapper(DatabaseManager databaseManager) { - return databaseManager.getCacheDbWrapper(); - } - - private final Db db = new Db(); - - @Bean - public Db getDb() { - return db; - } - - public static class Db { - - private final Main main = new Main(); - - public Main getMain() { - return main; - } - - private final Cache cache = new Cache(); - - public Cache getCache() { - return cache; - } - - public static class Main { - private String jdbcUrl = ""; - - public String getJdbcUrl() { - return jdbcUrl; - } - - public void setJdbcUrl(String jdbcUrl) { - this.jdbcUrl = jdbcUrl; - } - } - - public static class Cache { - private String jdbcUrl = ""; - - public String getJdbcUrl() { - return jdbcUrl; - } - - public void setJdbcUrl(String jdbcUrl) { - this.jdbcUrl = jdbcUrl; - } - } - } - - private final Security security = new Security(); - - @Bean - public Security getSecurity() { - return security; - } - - public static class Security { - - private List admins = new ArrayList<>(); - - public List getAdmins() { - return admins; - } - - public void setAdmins(List admins) { - this.admins = admins; - } - - public static class Admin { - private String name = ""; - private String pass = ""; - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public String getPass() { - return pass; - } - - public void setPass(String pass) { - this.pass = pass; - } - } - } -} diff --git a/Backend/src/main/java/fredboat/backend/config/RequestLoggerConfig.java b/Backend/src/main/java/fredboat/backend/config/RequestLoggerConfig.java deleted file mode 100644 index 82531e608..000000000 --- a/Backend/src/main/java/fredboat/backend/config/RequestLoggerConfig.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * - * MIT License - * - * Copyright (c) 2017-2018 Frederik Ar. Mikkelsen - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package fredboat.backend.config; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.web.filter.AbstractRequestLoggingFilter; - -import javax.servlet.http.HttpServletRequest; - -/** - * Created by napster on 17.02.18. - */ -@Configuration -public class RequestLoggerConfig { - - @Bean - public AbstractRequestLoggingFilter logFilter() { - RequestLogger filter = new RequestLogger(); - filter.setIncludeQueryString(true); - filter.setIncludePayload(true); - filter.setMaxPayloadLength(10000); - filter.setIncludeHeaders(true); - filter.setAfterMessagePrefix("REQUEST DATA : "); - return filter; - } - - private static class RequestLogger extends AbstractRequestLoggingFilter { - private static final Logger log = LoggerFactory.getLogger(RequestLogger.class); - - @Override - protected void beforeRequest(HttpServletRequest request, String message) { -// log.debug(message); - } - - @Override - protected void afterRequest(HttpServletRequest request, String message) { - log.debug(message); - } - } -} diff --git a/Backend/src/main/java/fredboat/backend/config/SecurityConfig.java b/Backend/src/main/java/fredboat/backend/config/SecurityConfig.java deleted file mode 100644 index 61138c950..000000000 --- a/Backend/src/main/java/fredboat/backend/config/SecurityConfig.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * - * MIT License - * - * Copyright (c) 2017-2018 Frederik Ar. Mikkelsen - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package fredboat.backend.config; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Configuration; -import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; -import org.springframework.security.config.annotation.authentication.configurers.provisioning.InMemoryUserDetailsManagerConfigurer; -import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; -import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; -import org.springframework.security.config.http.SessionCreationPolicy; - -/** - * Created by napster on 18.02.18. - */ -@Configuration -@EnableWebSecurity -public class SecurityConfig extends WebSecurityConfigurerAdapter { - - @Override - protected void configure(HttpSecurity http) throws Exception { - http.csrf().disable().authorizeRequests().anyRequest().authenticated() - .and().httpBasic() - .and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS); - } - - @Autowired - public void configureGlobal(AuthenticationManagerBuilder auth, AppConfig.Security security) throws Exception { - InMemoryUserDetailsManagerConfigurer inMemoryAuth = auth.inMemoryAuthentication(); - for (AppConfig.Security.Admin admin : security.getAdmins()) { - if (admin.getPass().isEmpty()) { - throw new RuntimeException("Admin " + admin.getName() + " configured with empty pass."); - } - //we are treating the pass as tokens right now so using the noop encoder is fine - inMemoryAuth.withUser(admin.getName()).password("{noop}" + admin.getPass()).roles("ADMIN", "USER"); - } - } -} diff --git a/Backend/src/main/java/fredboat/backend/config/package-info.java b/Backend/src/main/java/fredboat/backend/config/package-info.java deleted file mode 100644 index 99057decc..000000000 --- a/Backend/src/main/java/fredboat/backend/config/package-info.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * - * MIT License - * - * Copyright (c) 2017-2018 Frederik Ar. Mikkelsen - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -@space.npstr.annotations.FieldsAreNonNullByDefault -@space.npstr.annotations.ParametersAreNonnullByDefault -@space.npstr.annotations.ReturnTypesAreNonNullByDefault -package fredboat.backend.config; diff --git a/Backend/src/main/java/fredboat/backend/package-info.java b/Backend/src/main/java/fredboat/backend/package-info.java deleted file mode 100644 index dc82d6dde..000000000 --- a/Backend/src/main/java/fredboat/backend/package-info.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * - * MIT License - * - * Copyright (c) 2017-2018 Frederik Ar. Mikkelsen - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -@space.npstr.annotations.FieldsAreNonNullByDefault -@space.npstr.annotations.ParametersAreNonnullByDefault -@space.npstr.annotations.ReturnTypesAreNonNullByDefault -package fredboat.backend; diff --git a/Backend/src/main/java/fredboat/backend/rest/BlacklistController.java b/Backend/src/main/java/fredboat/backend/rest/BlacklistController.java deleted file mode 100644 index 323acec32..000000000 --- a/Backend/src/main/java/fredboat/backend/rest/BlacklistController.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * - * MIT License - * - * Copyright (c) 2017-2018 Frederik Ar. Mikkelsen - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package fredboat.backend.rest; - -import fredboat.backend.Application; -import fredboat.db.entity.main.BlacklistEntry; -import fredboat.db.repositories.api.BlacklistRepo; -import fredboat.db.repositories.impl.rest.RestBlacklistRepo; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -import java.util.List; - -/** - * Created by napster on 17.02.18. - */ -@RestController -@RequestMapping("/" + Application.API_VERSION + RestBlacklistRepo.PATH) -public class BlacklistController extends EntityController implements BlacklistRepo { - - protected final BlacklistRepo blacklistRepo; - - public BlacklistController(BlacklistRepo repo) { - super(repo); - this.blacklistRepo = repo; - } - - @GetMapping("/loadall") - @Override - public List loadBlacklist() { - return blacklistRepo.loadBlacklist(); - } -} diff --git a/Backend/src/main/java/fredboat/backend/rest/EntityController.java b/Backend/src/main/java/fredboat/backend/rest/EntityController.java deleted file mode 100644 index 21091ee5d..000000000 --- a/Backend/src/main/java/fredboat/backend/rest/EntityController.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * - * MIT License - * - * Copyright (c) 2017-2018 Frederik Ar. Mikkelsen - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package fredboat.backend.rest; - -import fredboat.db.repositories.api.Repo; -import fredboat.db.repositories.impl.rest.RestRepo; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import space.npstr.sqlsauce.entities.SaucedEntity; - -import java.io.Serializable; - -/** - * Created by napster on 17.02.18. - *

- * Counterpart to the {@link RestRepo} - *

- * Oh no, all those PostMappings are totally against Https/Rest principles...too bad that GET / DELETE do not support - * RequestBodies, and our Ids can be a bit more than a simple string / long. So they are passed as json as part of the - * body. - */ -public abstract class EntityController> implements Repo { - - protected final Repo repo; - - public EntityController(Repo repo) { - this.repo = repo; - } - - @Override - @PostMapping("/delete") - public void delete(@RequestBody I id) { - repo.delete(id); - } - - @Override - @PostMapping("/fetch") - public E fetch(@RequestBody I id) { - return repo.fetch(id); - } - - @Override - @PostMapping("/merge") - public E merge(@RequestBody E entity) { - return repo.merge(entity); - } -} diff --git a/Backend/src/main/java/fredboat/backend/rest/GuildConfigController.java b/Backend/src/main/java/fredboat/backend/rest/GuildConfigController.java deleted file mode 100644 index 7ddad89a5..000000000 --- a/Backend/src/main/java/fredboat/backend/rest/GuildConfigController.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * - * MIT License - * - * Copyright (c) 2017-2018 Frederik Ar. Mikkelsen - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package fredboat.backend.rest; - -import fredboat.backend.Application; -import fredboat.db.entity.main.GuildConfig; -import fredboat.db.repositories.api.GuildConfigRepo; -import fredboat.db.repositories.impl.rest.RestGuildConfigRepo; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -/** - * Created by napster on 17.02.18. - */ -@RestController -@RequestMapping("/" + Application.API_VERSION + RestGuildConfigRepo.PATH) -public class GuildConfigController extends EntityController implements GuildConfigRepo { - - public GuildConfigController(GuildConfigRepo repo) { - super(repo); - } -} diff --git a/Backend/src/main/java/fredboat/backend/rest/GuildDataController.java b/Backend/src/main/java/fredboat/backend/rest/GuildDataController.java deleted file mode 100644 index ec4049d47..000000000 --- a/Backend/src/main/java/fredboat/backend/rest/GuildDataController.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * - * MIT License - * - * Copyright (c) 2017-2018 Frederik Ar. Mikkelsen - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package fredboat.backend.rest; - -import fredboat.backend.Application; -import fredboat.db.entity.main.GuildData; -import fredboat.db.repositories.api.GuildDataRepo; -import fredboat.db.repositories.impl.rest.RestGuildDataRepo; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -/** - * Created by napster on 17.02.18. - */ -@RestController -@RequestMapping("/" + Application.API_VERSION + RestGuildDataRepo.PATH) -public class GuildDataController extends EntityController implements GuildDataRepo { - - public GuildDataController(GuildDataRepo repo) { - super(repo); - } -} diff --git a/Backend/src/main/java/fredboat/backend/rest/GuildModulesController.java b/Backend/src/main/java/fredboat/backend/rest/GuildModulesController.java deleted file mode 100644 index 49c5b82b1..000000000 --- a/Backend/src/main/java/fredboat/backend/rest/GuildModulesController.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * - * MIT License - * - * Copyright (c) 2017-2018 Frederik Ar. Mikkelsen - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package fredboat.backend.rest; - -import fredboat.backend.Application; -import fredboat.db.entity.main.GuildModules; -import fredboat.db.repositories.api.GuildModulesRepo; -import fredboat.db.repositories.impl.rest.RestGuildModulesRepo; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -/** - * Created by napster on 17.02.18. - */ -@RestController -@RequestMapping("/" + Application.API_VERSION + RestGuildModulesRepo.PATH) -public class GuildModulesController extends EntityController implements GuildModulesRepo { - - public GuildModulesController(GuildModulesRepo repo) { - super(repo); - } -} diff --git a/Backend/src/main/java/fredboat/backend/rest/GuildPermsController.java b/Backend/src/main/java/fredboat/backend/rest/GuildPermsController.java deleted file mode 100644 index f23b00347..000000000 --- a/Backend/src/main/java/fredboat/backend/rest/GuildPermsController.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * - * MIT License - * - * Copyright (c) 2017-2018 Frederik Ar. Mikkelsen - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package fredboat.backend.rest; - -import fredboat.backend.Application; -import fredboat.db.entity.main.GuildPermissions; -import fredboat.db.repositories.api.GuildPermsRepo; -import fredboat.db.repositories.impl.rest.RestGuildPermsRepo; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -/** - * Created by napster on 17.02.18. - */ -@RestController -@RequestMapping("/" + Application.API_VERSION + RestGuildPermsRepo.PATH) -public class GuildPermsController extends EntityController implements GuildPermsRepo { - - public GuildPermsController(GuildPermsRepo repo) { - super(repo); - } -} diff --git a/Backend/src/main/java/fredboat/backend/rest/PrefixController.java b/Backend/src/main/java/fredboat/backend/rest/PrefixController.java deleted file mode 100644 index b53fb27df..000000000 --- a/Backend/src/main/java/fredboat/backend/rest/PrefixController.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * - * MIT License - * - * Copyright (c) 2017-2018 Frederik Ar. Mikkelsen - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package fredboat.backend.rest; - -import fredboat.backend.Application; -import fredboat.db.entity.main.Prefix; -import fredboat.db.repositories.api.PrefixRepo; -import fredboat.db.repositories.impl.rest.RestPrefixRepo; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; -import space.npstr.sqlsauce.entities.GuildBotComposite; - -import javax.annotation.Nullable; - -/** - * Created by napster on 17.02.18. - */ -@RestController -@RequestMapping("/" + Application.API_VERSION + RestPrefixRepo.PATH) -public class PrefixController extends EntityController implements PrefixRepo { - - protected final PrefixRepo prefixRepo; - - public PrefixController(PrefixRepo repo) { - super(repo); - this.prefixRepo = repo; - } - - @Nullable - @PostMapping("/getraw") - @Override - public String getPrefix(@RequestBody GuildBotComposite id) { - return prefixRepo.getPrefix(id); - } -} diff --git a/Backend/src/main/java/fredboat/backend/rest/SearchResultController.java b/Backend/src/main/java/fredboat/backend/rest/SearchResultController.java deleted file mode 100644 index 4e49a4c02..000000000 --- a/Backend/src/main/java/fredboat/backend/rest/SearchResultController.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * - * MIT License - * - * Copyright (c) 2017-2018 Frederik Ar. Mikkelsen - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package fredboat.backend.rest; - -import fredboat.backend.Application; -import fredboat.db.entity.cache.SearchResult; -import fredboat.db.repositories.api.SearchResultRepo; -import fredboat.db.repositories.impl.rest.RestSearchResultRepo; -import org.springframework.web.bind.annotation.*; - -import javax.annotation.Nullable; - -/** - * Created by napster on 17.02.18. - */ -@RestController -@RequestMapping("/" + Application.API_VERSION + RestSearchResultRepo.PATH) -public class SearchResultController extends EntityController - implements SearchResultRepo { - - protected final SearchResultRepo searchResultRepo; - - public SearchResultController(SearchResultRepo repo) { - super(repo); - this.searchResultRepo = repo; - } - - @Nullable - @PostMapping("/getmaxaged") - @Override - public SearchResult getMaxAged(@RequestBody SearchResult.SearchResultId id, @RequestParam("millis") long maxAgeMillis) { - return searchResultRepo.getMaxAged(id, maxAgeMillis); - } -} diff --git a/Backend/src/main/java/fredboat/backend/rest/package-info.java b/Backend/src/main/java/fredboat/backend/rest/package-info.java deleted file mode 100644 index 290fbcc76..000000000 --- a/Backend/src/main/java/fredboat/backend/rest/package-info.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * - * MIT License - * - * Copyright (c) 2017-2018 Frederik Ar. Mikkelsen - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -@space.npstr.annotations.FieldsAreNonNullByDefault -@space.npstr.annotations.ParametersAreNonnullByDefault -@space.npstr.annotations.ReturnTypesAreNonNullByDefault -package fredboat.backend.rest; diff --git a/Backend/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/Backend/src/main/resources/META-INF/additional-spring-configuration-metadata.json deleted file mode 100644 index 6aa18ceb9..000000000 --- a/Backend/src/main/resources/META-INF/additional-spring-configuration-metadata.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "properties": [ - { - "name": "fredboat.db.main.jdbcUrl", - "type": "java.lang.String", - "description": "Jdbc url of the main database including username and password." - }, - { - "name": "fredboat.db.cache.jdbcUrl", - "type": "java.lang.String", - "description": "Jdbc url of the cache database including username and password." - } - ] -} diff --git a/settings.gradle b/settings.gradle index ec130b650..1ec28b3b0 100644 --- a/settings.gradle +++ b/settings.gradle @@ -3,10 +3,8 @@ include ':FredBoat' include ':Bootloader' include ':Shared' include ':Database' -include ':Backend' project(':FredBoat').projectDir = "$rootDir/FredBoat" as File project(':Bootloader').projectDir = "$rootDir/Bootloader" as File project(':Shared').projectDir = "$rootDir/Shared" as File project(':Database').projectDir = "$rootDir/Database" as File -project(':Backend').projectDir = "$rootDir/Backend" as File From 8c18534d3b001cad0fbd3e0b292e910ce80a2cba Mon Sep 17 00:00:00 2001 From: Napster Date: Sun, 11 Mar 2018 08:20:23 +0100 Subject: [PATCH 37/41] Adjust quarterdeck backend naming --- .../db/repositories/impl/rest/RestRepo.java | 4 +- FredBoat/fredboat.example.yaml | 16 +-- .../fredboat/config/RepoConfiguration.java | 30 ++--- .../config/property/BackendConfig.java | 12 +- .../property/BackendConfigProperties.java | 112 ++++++++++-------- docker-compose.yml | 20 ++-- 6 files changed, 107 insertions(+), 87 deletions(-) diff --git a/Database/src/main/java/fredboat/db/repositories/impl/rest/RestRepo.java b/Database/src/main/java/fredboat/db/repositories/impl/rest/RestRepo.java index e0cf315ea..977f26d87 100644 --- a/Database/src/main/java/fredboat/db/repositories/impl/rest/RestRepo.java +++ b/Database/src/main/java/fredboat/db/repositories/impl/rest/RestRepo.java @@ -39,7 +39,7 @@ /** * Created by napster on 17.02.18. * - * Counterpart to the EntityController of the Backend module. + * Counterpart to the EntityController of the Quarterdeck module. */ public abstract class RestRepo> implements Repo { @@ -56,7 +56,7 @@ public abstract class RestRepo entityClass, Http http, Gson gson, String auth) { this.path = path; diff --git a/FredBoat/fredboat.example.yaml b/FredBoat/fredboat.example.yaml index 8f3d77e36..9f727cc9a 100644 --- a/FredBoat/fredboat.example.yaml +++ b/FredBoat/fredboat.example.yaml @@ -83,13 +83,15 @@ audio-sources: ################################################################ backend: - # Host address of your backend, including port. Example: https://such.example.com:4269/ - # No need set the host when running the whole FredBoat in docker. - host: "" - # Admin username and pass that you configured in the backend.yaml. - # Do not leave any of them empty. - user: "" - pass: "" + quarterdeck: + # Host address of your quarterdeck backend, including port unless you are using a reverse proxy. + # Example: https://such.example.com:4269/ + # No need set the host when running the whole FredBoat in docker. + host: "" + # Admin username and pass that you configured in the quarterdeck.yaml. + # Do not leave any of them empty. + user: "" + pass: "" credentials: diff --git a/FredBoat/src/main/java/fredboat/config/RepoConfiguration.java b/FredBoat/src/main/java/fredboat/config/RepoConfiguration.java index ef0bde20d..13ed68a17 100644 --- a/FredBoat/src/main/java/fredboat/config/RepoConfiguration.java +++ b/FredBoat/src/main/java/fredboat/config/RepoConfiguration.java @@ -52,20 +52,20 @@ public class RepoConfiguration { private static final Logger log = LoggerFactory.getLogger(RepoConfiguration.class); - private final BackendConfig backendConfig; + private final BackendConfig.Quarterdeck quarterdeckConfig; private final Gson gson = new Gson(); private final Http http = BotController.HTTP; //todo replace public RepoConfiguration(BackendConfig backendConfig, ShutdownHandler shutdownHandler) throws InterruptedException { - this.backendConfig = backendConfig; + this.quarterdeckConfig = backendConfig.getQuarterdeck(); - log.info("Contacting the backend"); + log.info("Contacting the quarterdeck backend"); String[] apiVersions = null; int attempts = 0; Exception lastException = null; while ((apiVersions == null || apiVersions.length < 1) && attempts < 100) { //total time is 100 sec try { - String s = http.get(backendConfig.getHost() + "info/api/versions").auth(backendConfig.getBasicAuth()).asString(); + String s = http.get(quarterdeckConfig.getHost() + "info/api/versions").auth(quarterdeckConfig.getBasicAuth()).asString(); apiVersions = gson.fromJson(s, String[].class); } catch (Exception ignored) { lastException = ignored; @@ -75,7 +75,7 @@ public RepoConfiguration(BackendConfig backendConfig, ShutdownHandler shutdownHa } if (apiVersions == null || apiVersions.length < 1) { - log.error("Could not contact the backend. Please make sure it is started and configuration values are correct", lastException); + log.error("Could not contact the quarterdeck backend. Please make sure it is started and configuration values are correct", lastException); shutdownHandler.shutdown(ExitCodes.EXIT_CODE_ERROR); return; } @@ -84,52 +84,52 @@ public RepoConfiguration(BackendConfig backendConfig, ShutdownHandler shutdownHa if (!v.startsWith("v")) return "v" + v; else return v; }).collect(Collectors.toList()); - log.info("Supported Backend API versions: {}", String.join(", ", supportedApiVersions)); + log.info("Supported Quarterdeck API versions: {}", String.join(", ", supportedApiVersions)); String ourVersion = Integer.toString(RestRepo.API_VERSION); if (supportedApiVersions.contains(ourVersion) || supportedApiVersions.contains("v" + ourVersion)) { - log.info("Using Backend API v{}", ourVersion); + log.info("Using Quaterdeck API v{}", ourVersion); } else { - log.error("Backend API does not support our expected version v{}. Update the backend, or roll back this FredBoat version!", ourVersion); + log.error("Quarterdeck API does not support our expected version v{}. Update quarterdeck, or roll back this FredBoat version!", ourVersion); shutdownHandler.shutdown(ExitCodes.EXIT_CODE_ERROR); } } @Bean public BlacklistRepo blacklistRepo() { - return new RestBlacklistRepo(backendConfig.getHost(), http, gson, backendConfig.getBasicAuth()); + return new RestBlacklistRepo(quarterdeckConfig.getHost(), http, gson, quarterdeckConfig.getBasicAuth()); } @Bean public GuildConfigRepo guildConfigRepo() { - return new RestGuildConfigRepo(backendConfig.getHost(), http, gson, backendConfig.getBasicAuth()); + return new RestGuildConfigRepo(quarterdeckConfig.getHost(), http, gson, quarterdeckConfig.getBasicAuth()); } @Bean public GuildDataRepo guildDataRepo() { - return new RestGuildDataRepo(backendConfig.getHost(), http, gson, backendConfig.getBasicAuth()); + return new RestGuildDataRepo(quarterdeckConfig.getHost(), http, gson, quarterdeckConfig.getBasicAuth()); } @Bean public GuildModulesRepo guildModulesRepo() { - return new RestGuildModulesRepo(backendConfig.getHost(), http, gson, backendConfig.getBasicAuth()); + return new RestGuildModulesRepo(quarterdeckConfig.getHost(), http, gson, quarterdeckConfig.getBasicAuth()); } @Bean public GuildPermsRepo guildPermsRepo() { - return new RestGuildPermsRepo(backendConfig.getHost(), http, gson, backendConfig.getBasicAuth()); + return new RestGuildPermsRepo(quarterdeckConfig.getHost(), http, gson, quarterdeckConfig.getBasicAuth()); } @Bean public PrefixRepo prefixRepo() { - return new RestPrefixRepo(backendConfig.getHost(), http, gson, backendConfig.getBasicAuth()); + return new RestPrefixRepo(quarterdeckConfig.getHost(), http, gson, quarterdeckConfig.getBasicAuth()); } @Nullable @Bean public SearchResultRepo searchResultRepo() { - return new RestSearchResultRepo(backendConfig.getHost(), http, gson, backendConfig.getBasicAuth()); + return new RestSearchResultRepo(quarterdeckConfig.getHost(), http, gson, quarterdeckConfig.getBasicAuth()); } } diff --git a/FredBoat/src/main/java/fredboat/config/property/BackendConfig.java b/FredBoat/src/main/java/fredboat/config/property/BackendConfig.java index c5ec25e62..9475f63ec 100644 --- a/FredBoat/src/main/java/fredboat/config/property/BackendConfig.java +++ b/FredBoat/src/main/java/fredboat/config/property/BackendConfig.java @@ -29,11 +29,15 @@ */ public interface BackendConfig { - String getHost(); + Quarterdeck getQuarterdeck(); - String getUser(); + interface Quarterdeck { + String getHost(); - String getPass(); + String getUser(); - String getBasicAuth(); + String getPass(); + + String getBasicAuth(); + } } diff --git a/FredBoat/src/main/java/fredboat/config/property/BackendConfigProperties.java b/FredBoat/src/main/java/fredboat/config/property/BackendConfigProperties.java index 75218979a..bc9a4bfe7 100644 --- a/FredBoat/src/main/java/fredboat/config/property/BackendConfigProperties.java +++ b/FredBoat/src/main/java/fredboat/config/property/BackendConfigProperties.java @@ -38,71 +38,85 @@ public class BackendConfigProperties implements BackendConfig { private static final Logger log = LoggerFactory.getLogger(BackendConfigProperties.class); - private String host = ""; - private String user = ""; - private String pass = ""; - private String auth = ""; + private Quarterdeck quarterdeck = new Quarterdeck(); @Override - public String getHost() { - return host; + public Quarterdeck getQuarterdeck() { + return quarterdeck; } - @Override - public String getUser() { - return user; + public void setQuarterdeck(Quarterdeck quarterdeck) { + this.quarterdeck = quarterdeck; } - @Override - public String getPass() { - return pass; - } + public static class Quarterdeck implements BackendConfig.Quarterdeck { - @Override - public String getBasicAuth() { - if (auth.isEmpty()) { - auth = okhttp3.Credentials.basic(getUser(), getPass()); + private String host = ""; + private String user = ""; + private String pass = ""; + private String auth = ""; + + @Override + public String getHost() { + return host; } - return auth; - } - public void setHost(String host) { - this.host = host; - //noinspection ConstantConditions - if (host == null || host.isEmpty()) { - if ("docker".equals(System.getenv("ENV"))) { - log.info("No backend host found, docker environment detected. Using default backend url"); - this.host = "http://backend:4269/"; - } else { - String message = "No backend host provided in a non-docker environment. FredBoat cannot work without a backend."; - log.error(message); - throw new RuntimeException(message); + @Override + public String getUser() { + return user; + } + + @Override + public String getPass() { + return pass; + } + + @Override + public String getBasicAuth() { + if (auth.isEmpty()) { + auth = okhttp3.Credentials.basic(getUser(), getPass()); } + return auth; } - //fix up a missing trailing slash - if (!this.host.endsWith("/")) { - this.host += "/"; + public void setHost(String host) { + this.host = host; + //noinspection ConstantConditions + if (host == null || host.isEmpty()) { + if ("docker".equals(System.getenv("ENV"))) { + log.info("No quarterdeck host found, docker environment detected. Using default quarterdeck url"); + this.host = "http://quarterdeck:4269/"; + } else { + String message = "No quarterdeck host provided in a non-docker environment. FredBoat cannot work without quarterdeck."; + log.error(message); + throw new RuntimeException(message); + } + } + + //fix up a missing trailing slash + if (!this.host.endsWith("/")) { + this.host += "/"; + } } - } - public void setUser(String user) { - this.user = user; - //noinspection ConstantConditions - if (user == null || user.isEmpty()) { - String message = "No backend user provided."; - log.error(message); - throw new RuntimeException(message); + public void setUser(String user) { + this.user = user; + //noinspection ConstantConditions + if (user == null || user.isEmpty()) { + String message = "No quarterdeck user provided."; + log.error(message); + throw new RuntimeException(message); + } } - } - public void setPass(String pass) { - this.pass = pass; - //noinspection ConstantConditions - if (pass == null || pass.isEmpty()) { - String message = "No backend pass provided."; - log.error(message); - throw new RuntimeException(message); + public void setPass(String pass) { + this.pass = pass; + //noinspection ConstantConditions + if (pass == null || pass.isEmpty()) { + String message = "No quarterdeck pass provided."; + log.error(message); + throw new RuntimeException(message); + } } } } diff --git a/docker-compose.yml b/docker-compose.yml index 54f45c6de..ce5a9c4e9 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -34,34 +34,34 @@ services: #- postgres-data-volume:/var/lib/postgresql/data ################################################################################ - ## Backend + ## Quarterdeck (Database Backend) ################################################################################ - backend: + quarterdeck: # pick one of these: stable or dev # dev receives more frequent updates than stable but may have more bugs / things breaking # versions (example: v2) receive continous non-breaking (best effort) updates via watchtower. switching between versions # (example: going from v2 to v3) usually requires manual migration. what exactly is needed is published on the # FredBoat selfhosting website and/or the selfhosters channel (see top of this file for how to get to these places) # Once you use the dev branch, you may not be able to go back to stable without deleting your database. - image: fredboat/backend:stable-v1 - #image: fredboat/backend:dev-v1 + image: fredboat/quarterdeck:stable-v1 + #image: fredboat/quarterdeck:dev-v1 restart: always labels: - "com.centurylinklabs.watchtower.enable=true" depends_on: - db volumes: - - ./backend.yaml:/opt/Backend/backend.yaml - - ./backend_logs:/opt/Backend/logs + - ./quarterdeck.yaml:/opt/Quarterdeck/quarterdeck.yaml + - ./quarterdeck_logs:/opt/Quarterdeck/logs # Need a bigger memory size or any other custom JVM args? uncomment and edit the line below accordingly - #entrypoint: java -Xmx128m -jar Backend.jar + #entrypoint: java -Xmx128m -jar Quarterdeck.jar ################################################################################ ## FredBoat ################################################################################ bot: - # for choosing between stable or dev, read the paragraph above in the backend - # IMPORTANT: both backend and fredboat need to either be on the stable, or on the dev branch + # for choosing between stable or dev, read the paragraph above in the Quarterdeck section + # IMPORTANT: both quarterdeck and fredboat need to either be on the stable, or on the dev branch image: fredboat/fredboat:stable-v3 #image: fredboat/fredboat:dev-v3 #build: ./FredBoat #useful alternative for developers @@ -70,7 +70,7 @@ services: labels: - "com.centurylinklabs.watchtower.enable=true" depends_on: - - backend + - quarterdeck ports: - 1356:1356 volumes: From b84bdb3baa377d665474ffcf6456f0c1c9dd6909 Mon Sep 17 00:00:00 2001 From: Napster Date: Sun, 11 Mar 2018 08:30:03 +0100 Subject: [PATCH 38/41] Turn off ehcache overflow to disk --- .../java/fredboat/db/DatabaseManager.java | 20 ------------------- Database/src/main/resources/ehcache_cache.xml | 8 ++++---- Database/src/main/resources/ehcache_main.xml | 14 ++++++------- 3 files changed, 11 insertions(+), 31 deletions(-) diff --git a/Database/src/main/java/fredboat/db/DatabaseManager.java b/Database/src/main/java/fredboat/db/DatabaseManager.java index 00bfc7c4b..4de057864 100644 --- a/Database/src/main/java/fredboat/db/DatabaseManager.java +++ b/Database/src/main/java/fredboat/db/DatabaseManager.java @@ -29,8 +29,6 @@ import com.zaxxer.hikari.metrics.prometheus.PrometheusMetricsTrackerFactory; import io.prometheus.client.hibernate.HibernateStatisticsCollector; import net.sf.ehcache.CacheManager; -import net.sf.ehcache.config.CacheConfiguration; -import net.sf.ehcache.config.PersistenceConfiguration; import net.ttddyy.dsproxy.listener.logging.SLF4JLogLevel; import net.ttddyy.dsproxy.support.ProxyDataSourceBuilder; import org.flywaydb.core.Flyway; @@ -203,11 +201,6 @@ private DatabaseConnection initMainDbConn() throws DatabaseException { .setFlyway(flyway) .build(); - //adjusting the ehcache config - if (mainTunnel == null && cacheTunnel == null) { - //local database: turn off overflow to disk of the cache - turnOffLocalStorageForEhcacheManager("MAIN_CACHEMANAGER"); - } log.debug(CacheManager.getCacheManager("MAIN_CACHEMANAGER").getActiveConfigurationText()); return databaseConnection; @@ -228,11 +221,6 @@ public DatabaseConnection initCacheConn(String jdbc) throws DatabaseException { .setFlyway(flyway) .build(); - //adjusting the ehcache config - if (mainTunnel == null && cacheTunnel == null) { - //local database: turn off overflow to disk of the cache - turnOffLocalStorageForEhcacheManager("CACHE_CACHEMANAGER"); - } log.debug(CacheManager.getCacheManager("CACHE_CACHEMANAGER").getActiveConfigurationText()); return databaseConnection; @@ -290,12 +278,4 @@ private Properties buildHibernateProps(String ehcacheXmlFile) { return hibernateProps; } - - private void turnOffLocalStorageForEhcacheManager(String cacheManagerName) { - CacheManager cacheManager = CacheManager.getCacheManager(cacheManagerName); - for (String cacheName : cacheManager.getCacheNames()) { - CacheConfiguration cacheConfig = cacheManager.getCache(cacheName).getCacheConfiguration(); - cacheConfig.getPersistenceConfiguration().strategy(PersistenceConfiguration.Strategy.NONE); - } - } } diff --git a/Database/src/main/resources/ehcache_cache.xml b/Database/src/main/resources/ehcache_cache.xml index 8620366f0..635983ef0 100644 --- a/Database/src/main/resources/ehcache_cache.xml +++ b/Database/src/main/resources/ehcache_cache.xml @@ -38,26 +38,26 @@ diskExpiryThreadIntervalSeconds="120" memoryStoreEvictionPolicy="LRU" statistics="true"> - + - + - + - + diff --git a/Database/src/main/resources/ehcache_main.xml b/Database/src/main/resources/ehcache_main.xml index 7bb142074..ad0a69d5b 100644 --- a/Database/src/main/resources/ehcache_main.xml +++ b/Database/src/main/resources/ehcache_main.xml @@ -38,7 +38,7 @@ diskExpiryThreadIntervalSeconds="120" memoryStoreEvictionPolicy="LRU" statistics="true"> - + - + - + - + - + - + - + From e8b983b344ab301227abfb5015ffdc8e553b211d Mon Sep 17 00:00:00 2001 From: Napster Date: Sun, 11 Mar 2018 08:30:32 +0100 Subject: [PATCH 39/41] Remove obsolete tunnel configuration --- .../src/main/java/fredboat/db/DatabaseManager.java | 11 ----------- build.gradle | 2 +- 2 files changed, 1 insertion(+), 12 deletions(-) diff --git a/Database/src/main/java/fredboat/db/DatabaseManager.java b/Database/src/main/java/fredboat/db/DatabaseManager.java index 4de057864..f96f26dee 100644 --- a/Database/src/main/java/fredboat/db/DatabaseManager.java +++ b/Database/src/main/java/fredboat/db/DatabaseManager.java @@ -38,7 +38,6 @@ import space.npstr.sqlsauce.DatabaseConnection; import space.npstr.sqlsauce.DatabaseException; import space.npstr.sqlsauce.DatabaseWrapper; -import space.npstr.sqlsauce.ssh.SshTunnel; import javax.annotation.Nullable; import java.util.Properties; @@ -60,12 +59,8 @@ public class DatabaseManager { private final boolean migrateAndValidate; private final String mainJdbc; @Nullable - private final SshTunnel.SshDetails mainTunnel; - @Nullable private final String cacheJdbc; @Nullable - private final SshTunnel.SshDetails cacheTunnel; - @Nullable private final DatabaseConnection.EntityManagerFactoryBuilder entityManagerFactoryBuilder; @Nullable @@ -90,9 +85,7 @@ public DatabaseManager(@Nullable HibernateStatisticsCollector hibernateStats, String appName, boolean migrateAndValidate, String mainJdbc, - @Nullable SshTunnel.SshDetails mainTunnel, @Nullable String cacheJdbc, - @Nullable SshTunnel.SshDetails cacheTunnel, @Nullable DatabaseConnection.EntityManagerFactoryBuilder entityManagerFactoryBuilder) { this.hibernateStats = hibernateStats; this.hikariStats = hikariStats; @@ -100,9 +93,7 @@ public DatabaseManager(@Nullable HibernateStatisticsCollector hibernateStats, this.appName = appName; this.migrateAndValidate = migrateAndValidate; this.mainJdbc = mainJdbc; - this.mainTunnel = mainTunnel; this.cacheJdbc = cacheJdbc; - this.cacheTunnel = cacheTunnel; this.entityManagerFactoryBuilder = entityManagerFactoryBuilder; if (mainJdbc.isEmpty()) { @@ -197,7 +188,6 @@ private DatabaseConnection initMainDbConn() throws DatabaseException { DatabaseConnection databaseConnection = getBasicConnectionBuilder(MAIN_PERSISTENCE_UNIT_NAME, mainJdbc) .setHibernateProps(buildHibernateProps("ehcache_main.xml")) .addEntityPackage("fredboat.db.entity.main") - .setSshDetails(mainTunnel) .setFlyway(flyway) .build(); @@ -217,7 +207,6 @@ public DatabaseConnection initCacheConn(String jdbc) throws DatabaseException { DatabaseConnection databaseConnection = getBasicConnectionBuilder(CACHE_PERSISTENCE_UNIT_NAME, jdbc) .setHibernateProps(buildHibernateProps("ehcache_cache.xml")) .addEntityPackage("fredboat.db.entity.cache") - .setSshDetails(cacheTunnel) .setFlyway(flyway) .build(); diff --git a/build.gradle b/build.gradle index c58cedf53..db1558b45 100644 --- a/build.gradle +++ b/build.gradle @@ -94,7 +94,7 @@ subprojects { napsterAnnotations = '0.0.1' //database deps - sqlsauceVersion = '0.0.11' + sqlsauceVersion = '0.0.13' hibernateVersion = '5.2.13.Final' flywayVersion = '5.0.7' dsProxyVersion = '1.4.6' From 601bfbe17986b99e3a535795c9c431f6ffbeb028 Mon Sep 17 00:00:00 2001 From: Napster Date: Sun, 11 Mar 2018 10:30:49 +0100 Subject: [PATCH 40/41] Resolve a few warnings and typos --- FredBoat/src/main/java/fredboat/api/API.java | 2 +- FredBoat/src/main/java/fredboat/config/RepoConfiguration.java | 2 +- .../src/main/java/fredboat/event/MusicPersistenceHandler.java | 3 ++- .../src/main/java/fredboat/util/rest/SpotifyAPIWrapper.java | 3 +++ 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/FredBoat/src/main/java/fredboat/api/API.java b/FredBoat/src/main/java/fredboat/api/API.java index 2798b24b1..383b2cffa 100644 --- a/FredBoat/src/main/java/fredboat/api/API.java +++ b/FredBoat/src/main/java/fredboat/api/API.java @@ -105,7 +105,7 @@ public static void start(PlayerRegistry playerRegistry, BotMetrics botMetrics, S public static void turnOnMetrics(MetricsServletAdapter metricsServlet) { if (!Launcher.getBotController().getAppConfig().isRestServerEnabled()) { - log.warn("Rest server is not enabled. Skipping Spark ignition!"); + log.warn("Rest server is not enabled. Metrics will not be scrapable!"); return; } diff --git a/FredBoat/src/main/java/fredboat/config/RepoConfiguration.java b/FredBoat/src/main/java/fredboat/config/RepoConfiguration.java index 13ed68a17..43a3727a6 100644 --- a/FredBoat/src/main/java/fredboat/config/RepoConfiguration.java +++ b/FredBoat/src/main/java/fredboat/config/RepoConfiguration.java @@ -90,7 +90,7 @@ public RepoConfiguration(BackendConfig backendConfig, ShutdownHandler shutdownHa String ourVersion = Integer.toString(RestRepo.API_VERSION); if (supportedApiVersions.contains(ourVersion) || supportedApiVersions.contains("v" + ourVersion)) { - log.info("Using Quaterdeck API v{}", ourVersion); + log.info("Using Quarterdeck API v{}", ourVersion); } else { log.error("Quarterdeck API does not support our expected version v{}. Update quarterdeck, or roll back this FredBoat version!", ourVersion); shutdownHandler.shutdown(ExitCodes.EXIT_CODE_ERROR); diff --git a/FredBoat/src/main/java/fredboat/event/MusicPersistenceHandler.java b/FredBoat/src/main/java/fredboat/event/MusicPersistenceHandler.java index f6e62cdd4..ce005dc62 100644 --- a/FredBoat/src/main/java/fredboat/event/MusicPersistenceHandler.java +++ b/FredBoat/src/main/java/fredboat/event/MusicPersistenceHandler.java @@ -39,6 +39,7 @@ import fredboat.feature.I18n; import fredboat.jda.JdaEntityProvider; import fredboat.messaging.CentralMessaging; +import fredboat.shared.constant.DistributionEnum; import fredboat.shared.constant.ExitCodes; import net.dv8tion.jda.core.JDA; import net.dv8tion.jda.core.entities.Guild; @@ -189,7 +190,7 @@ public void handlePreShutdown(int code) { @Override public void onReady(ReadyEvent event) { //the current implementation of music persistence is not a good idea on big bots - if (credentials.getRecommendedShardCount() <= 10) { + if (credentials.getRecommendedShardCount() <= 10 && appConfig.getDistribution() != DistributionEnum.MUSIC) { try { reloadPlaylists(event.getJDA()); } catch (Exception e) { diff --git a/FredBoat/src/main/java/fredboat/util/rest/SpotifyAPIWrapper.java b/FredBoat/src/main/java/fredboat/util/rest/SpotifyAPIWrapper.java index 16eea4f81..2f5eb6282 100644 --- a/FredBoat/src/main/java/fredboat/util/rest/SpotifyAPIWrapper.java +++ b/FredBoat/src/main/java/fredboat/util/rest/SpotifyAPIWrapper.java @@ -76,6 +76,9 @@ public SpotifyAPIWrapper(Credentials credentials) { * https://developer.spotify.com/web-api/authorization-guide/#client-credentials-flow */ private void refreshAccessToken() { + if (credentials.getSpotifyId().isEmpty() || credentials.getSpotifySecret().isEmpty()) { + return; //no spotify credentials configured, dont throw unnecessary errors + } try { JSONObject jsonClientCredentials = BotController.HTTP.post(URL_SPOTIFY_AUTHENTICATION_HOST + "/api/token", Http.Params.of( From 537f62e35001a8f645e7593e8ea34dea6895c0a0 Mon Sep 17 00:00:00 2001 From: Napster Date: Wed, 14 Mar 2018 07:40:50 +0100 Subject: [PATCH 41/41] Fix bot admins not recognized in private messages --- FredBoat/src/main/java/fredboat/event/EventListenerBoat.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FredBoat/src/main/java/fredboat/event/EventListenerBoat.java b/FredBoat/src/main/java/fredboat/event/EventListenerBoat.java index 771df399a..4709a0b02 100644 --- a/FredBoat/src/main/java/fredboat/event/EventListenerBoat.java +++ b/FredBoat/src/main/java/fredboat/event/EventListenerBoat.java @@ -251,7 +251,7 @@ public void onPrivateMessageReceived(PrivateMessageReceivedEvent event) { } //quick n dirty bot admin / owner check - if (appConfig.getAdminIds().contains(event.getAuthor().getId()) + if (appConfig.getAdminIds().contains(event.getAuthor().getIdLong()) || DiscordUtil.getOwnerId(event.getJDA()) == event.getAuthor().getIdLong()) { //hack in / hardcode some commands; this is not meant to look clean