diff --git a/bukkit-legacy/build.gradle b/bukkit-legacy/build.gradle index fdd81b434..772630d6d 100644 --- a/bukkit-legacy/build.gradle +++ b/bukkit-legacy/build.gradle @@ -29,7 +29,7 @@ shadowJar { relocate 'me.lucko.commodore', 'me.lucko.luckperms.lib.commodore' relocate 'org.mariadb.jdbc', 'me.lucko.luckperms.lib.mariadb' relocate 'com.mysql', 'me.lucko.luckperms.lib.mysql' - relocate 'org.postgresql', 'me.lucko.luckperms.lib.postgresql' + relocate 'com.impossibl', 'me.lucko.luckperms.lib.postgresql' relocate 'com.zaxxer.hikari', 'me.lucko.luckperms.lib.hikari' relocate 'com.mongodb', 'me.lucko.luckperms.lib.mongodb' relocate 'org.bson', 'me.lucko.luckperms.lib.bson' diff --git a/bukkit/build.gradle b/bukkit/build.gradle index 3155dda80..f7cae794f 100644 --- a/bukkit/build.gradle +++ b/bukkit/build.gradle @@ -39,7 +39,7 @@ shadowJar { relocate 'me.lucko.commodore', 'me.lucko.luckperms.lib.commodore' relocate 'org.mariadb.jdbc', 'me.lucko.luckperms.lib.mariadb' relocate 'com.mysql', 'me.lucko.luckperms.lib.mysql' - relocate 'org.postgresql', 'me.lucko.luckperms.lib.postgresql' + relocate 'com.impossibl', 'me.lucko.luckperms.lib.postgresql' relocate 'com.zaxxer.hikari', 'me.lucko.luckperms.lib.hikari' relocate 'com.mongodb', 'me.lucko.luckperms.lib.mongodb' relocate 'org.bson', 'me.lucko.luckperms.lib.bson' diff --git a/bungee/build.gradle b/bungee/build.gradle index 9b28725b1..00ffa4171 100644 --- a/bungee/build.gradle +++ b/bungee/build.gradle @@ -31,7 +31,7 @@ shadowJar { relocate 'me.lucko.commodore', 'me.lucko.luckperms.lib.commodore' relocate 'org.mariadb.jdbc', 'me.lucko.luckperms.lib.mariadb' relocate 'com.mysql', 'me.lucko.luckperms.lib.mysql' - relocate 'org.postgresql', 'me.lucko.luckperms.lib.postgresql' + relocate 'com.impossibl', 'me.lucko.luckperms.lib.postgresql' relocate 'com.zaxxer.hikari', 'me.lucko.luckperms.lib.hikari' relocate 'com.mongodb', 'me.lucko.luckperms.lib.mongodb' relocate 'org.bson', 'me.lucko.luckperms.lib.bson' diff --git a/common/build.gradle b/common/build.gradle index 93948b2b2..a22461cef 100644 --- a/common/build.gradle +++ b/common/build.gradle @@ -57,6 +57,7 @@ dependencies { api 'com.squareup.okhttp3:okhttp:3.14.9' api 'com.squareup.okio:okio:1.17.5' api 'net.bytebuddy:byte-buddy:1.10.22' + api('org.spongepowered:configurate-core:3.7.2') { transitive = false } @@ -72,10 +73,11 @@ dependencies { api('me.lucko.configurate:configurate-toml:3.7') { transitive = false } - api 'com.zaxxer:HikariCP:4.0.3' - api 'redis.clients:jedis:3.5.2' - api 'io.nats:jnats:2.16.4' - api 'com.rabbitmq:amqp-client:5.12.0' - api 'org.mongodb:mongodb-driver-legacy:4.5.0' - api 'org.yaml:snakeyaml:1.28' + compileOnly 'com.zaxxer:HikariCP:4.0.3' + compileOnly 'redis.clients:jedis:3.5.2' + compileOnly 'io.nats:jnats:2.16.4' + compileOnly 'com.rabbitmq:amqp-client:5.12.0' + compileOnly 'org.mongodb:mongodb-driver-legacy:4.5.0' + compileOnly 'com.impossibl.pgjdbc-ng:pgjdbc-ng:0.8.9' + compileOnly 'org.yaml:snakeyaml:1.28' } diff --git a/common/src/main/java/me/lucko/luckperms/common/dependencies/Dependency.java b/common/src/main/java/me/lucko/luckperms/common/dependencies/Dependency.java index aa6a895ed..482e845ce 100644 --- a/common/src/main/java/me/lucko/luckperms/common/dependencies/Dependency.java +++ b/common/src/main/java/me/lucko/luckperms/common/dependencies/Dependency.java @@ -26,7 +26,6 @@ package me.lucko.luckperms.common.dependencies; import com.google.common.collect.ImmutableList; - import me.lucko.luckperms.common.dependencies.relocation.Relocation; import me.lucko.luckperms.common.dependencies.relocation.RelocationHelper; @@ -154,11 +153,18 @@ public enum Dependency { Relocation.of("mysql", "com{}mysql") ), POSTGRESQL_DRIVER( - "org{}postgresql", - "postgresql", - "42.2.19", - "IydH+gkk2Iom36QrgSi2+hFAgC2AQSWJFZboyl8pEyI=", - Relocation.of("postgresql", "org{}postgresql") + "com{}impossibl{}pgjdbc-ng", + "pgjdbc-ng", + "0.8.9", + "WEYMezl02Rot2n2ATs7NABcvL9ceQ/oLA/XPduIEaWA=", + Relocation.of("postgresql", "com{}impossibl") + ), + POSTGRESQL_DRIVER_SPY( + "com{}impossibl{}pgjdbc-ng", + "spy", + "0.8.9", + "72ZuhpMy/4EYJZuSjBjGI5NGgdWmOpwjDHW9ISnqso8=", + Relocation.of("postgresql", "com{}impossibl") ), H2_DRIVER_LEGACY( "com.h2database", diff --git a/common/src/main/java/me/lucko/luckperms/common/dependencies/DependencyRegistry.java b/common/src/main/java/me/lucko/luckperms/common/dependencies/DependencyRegistry.java index 2235e073f..45b4e52a5 100644 --- a/common/src/main/java/me/lucko/luckperms/common/dependencies/DependencyRegistry.java +++ b/common/src/main/java/me/lucko/luckperms/common/dependencies/DependencyRegistry.java @@ -29,11 +29,9 @@ import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSetMultimap; import com.google.common.collect.SetMultimap; import com.google.gson.JsonElement; - import me.lucko.luckperms.common.dependencies.relocation.Relocation; import me.lucko.luckperms.common.dependencies.relocation.RelocationHandler; import me.lucko.luckperms.common.storage.StorageType; - import net.luckperms.api.platform.Platform; import java.util.LinkedHashSet; @@ -57,7 +55,7 @@ public class DependencyRegistry { .putAll(StorageType.MONGODB, Dependency.MONGODB_DRIVER_CORE, Dependency.MONGODB_DRIVER_LEGACY, Dependency.MONGODB_DRIVER_SYNC, Dependency.MONGODB_DRIVER_BSON) .putAll(StorageType.MARIADB, Dependency.SLF4J_API, Dependency.SLF4J_SIMPLE, Dependency.HIKARI, Dependency.MARIADB_DRIVER) .putAll(StorageType.MYSQL, Dependency.SLF4J_API, Dependency.SLF4J_SIMPLE, Dependency.HIKARI, Dependency.MYSQL_DRIVER) - .putAll(StorageType.POSTGRESQL, Dependency.SLF4J_API, Dependency.SLF4J_SIMPLE, Dependency.HIKARI, Dependency.POSTGRESQL_DRIVER) + .putAll(StorageType.POSTGRESQL, Dependency.SLF4J_API, Dependency.SLF4J_SIMPLE, Dependency.HIKARI, Dependency.POSTGRESQL_DRIVER, Dependency.POSTGRESQL_DRIVER_SPY) .putAll(StorageType.SQLITE, Dependency.SQLITE_DRIVER) .putAll(StorageType.H2, Dependency.H2_DRIVER) .build(); diff --git a/common/src/main/java/me/lucko/luckperms/common/messaging/MessagingFactory.java b/common/src/main/java/me/lucko/luckperms/common/messaging/MessagingFactory.java index 67a83b4b3..e42ef02bd 100644 --- a/common/src/main/java/me/lucko/luckperms/common/messaging/MessagingFactory.java +++ b/common/src/main/java/me/lucko/luckperms/common/messaging/MessagingFactory.java @@ -28,6 +28,7 @@ package me.lucko.luckperms.common.messaging; import me.lucko.luckperms.common.config.ConfigKeys; import me.lucko.luckperms.common.config.LuckPermsConfiguration; import me.lucko.luckperms.common.messaging.nats.NatsMessenger; +import me.lucko.luckperms.common.messaging.postgres.PostgresMessenger; import me.lucko.luckperms.common.messaging.rabbitmq.RabbitMQMessenger; import me.lucko.luckperms.common.messaging.redis.RedisMessenger; import me.lucko.luckperms.common.messaging.sql.SqlMessenger; @@ -37,6 +38,7 @@ import me.lucko.luckperms.common.storage.implementation.sql.SqlStorage; import me.lucko.luckperms.common.storage.implementation.sql.connection.hikari.MariaDbConnectionFactory; import me.lucko.luckperms.common.storage.implementation.sql.connection.hikari.MySqlConnectionFactory; +import me.lucko.luckperms.common.storage.implementation.sql.connection.hikari.PostgresConnectionFactory; import net.luckperms.api.messenger.IncomingMessageConsumer; import net.luckperms.api.messenger.Messenger; import net.luckperms.api.messenger.MessengerProvider; @@ -78,6 +80,10 @@ public class MessagingFactory

{ messagingType = "sql"; break; } + if (sql.getConnectionFactory() instanceof PostgresConnectionFactory) { + messagingType = "postgresql"; + break; + } } } } @@ -138,6 +144,12 @@ public class MessagingFactory

{ } catch (Exception e) { getPlugin().getLogger().severe("Exception occurred whilst enabling SQL messaging service", e); } + } else if (messagingType.equals("postgresql")) { + try { + return new LuckPermsMessagingService(this.plugin, new PostgresMessengerProvider()); + } catch (Exception e) { + getPlugin().getLogger().severe("Exception occurred whilst enabling Postgres messaging service", e); + } } return null; @@ -246,4 +258,29 @@ public class MessagingFactory

{ } } + private class PostgresMessengerProvider implements MessengerProvider { + + @Override + public @NonNull String getName() { + return "PostgreSQL"; + } + + @Override + public @NonNull Messenger obtain(@NonNull IncomingMessageConsumer incomingMessageConsumer) { + for (StorageImplementation implementation : getPlugin().getStorage().getImplementations()) { + if (implementation instanceof SqlStorage) { + SqlStorage storage = (SqlStorage) implementation; + if (storage.getConnectionFactory() instanceof PostgresConnectionFactory) { + // found an implementation match! + PostgresMessenger messenger = new PostgresMessenger(getPlugin(), storage, incomingMessageConsumer); + messenger.init(); + return messenger; + } + } + } + + throw new IllegalStateException("Can't find a supported sql storage implementation"); + } + } + } diff --git a/common/src/main/java/me/lucko/luckperms/common/messaging/postgres/PostgresMessenger.java b/common/src/main/java/me/lucko/luckperms/common/messaging/postgres/PostgresMessenger.java new file mode 100644 index 000000000..1f73fdf54 --- /dev/null +++ b/common/src/main/java/me/lucko/luckperms/common/messaging/postgres/PostgresMessenger.java @@ -0,0 +1,169 @@ +/* + * This file is part of LuckPerms, licensed under the MIT License. + * + * Copyright (c) lucko (Luck) + * Copyright (c) contributors + * + * 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 me.lucko.luckperms.common.messaging.postgres; + +import com.impossibl.postgres.api.jdbc.PGConnection; +import com.impossibl.postgres.api.jdbc.PGNotificationListener; +import me.lucko.luckperms.common.plugin.LuckPermsPlugin; +import me.lucko.luckperms.common.plugin.scheduler.SchedulerTask; +import me.lucko.luckperms.common.storage.implementation.sql.SqlStorage; +import net.luckperms.api.messenger.IncomingMessageConsumer; +import net.luckperms.api.messenger.Messenger; +import net.luckperms.api.messenger.message.OutgoingMessage; +import org.checkerframework.checker.nullness.qual.NonNull; + +import java.sql.PreparedStatement; +import java.sql.Statement; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; + +/** + * An implementation of {@link Messenger} using Postgres. + */ +public class PostgresMessenger implements Messenger { + + private static final String CHANNEL = "luckperms:update"; + + private final LuckPermsPlugin plugin; + private final SqlStorage sqlStorage; + private final IncomingMessageConsumer consumer; + + private NotificationListener listener; + private SchedulerTask checkConnectionTask; + + public PostgresMessenger(LuckPermsPlugin plugin, SqlStorage sqlStorage, IncomingMessageConsumer consumer) { + this.plugin = plugin; + this.sqlStorage = sqlStorage; + this.consumer = consumer; + } + + public void init() { + checkAndReopenConnection(true); + this.checkConnectionTask = this.plugin.getBootstrap().getScheduler().asyncRepeating(() -> checkAndReopenConnection(false), 5, TimeUnit.SECONDS); + } + + @Override + public void sendOutgoingMessage(@NonNull OutgoingMessage outgoingMessage) { + try (PGConnection connection = this.sqlStorage.getConnectionFactory().getConnection().unwrap(PGConnection.class)) { + try (PreparedStatement ps = connection.prepareStatement("SELECT pg_notify(?, ?)")) { + ps.setString(1, CHANNEL); + ps.setString(2, outgoingMessage.asEncodedString()); + ps.execute(); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + @Override + public void close() { + try { + this.checkConnectionTask.cancel(); + if (this.listener != null) { + this.listener.close(); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + /** + * Checks the connection, and re-opens it if necessary. + * + * @return true if the connection is now alive, false otherwise + */ + private boolean checkAndReopenConnection(boolean firstStartup) { + boolean listenerActive = this.listener != null && this.listener.isListening(); + if (listenerActive) { + return true; + } + + // (re)create + + if (!firstStartup) { + this.plugin.getLogger().warn("Postgres listen/notify connection dropped, trying to re-open the connection"); + } + + try { + this.listener = new NotificationListener(); + this.plugin.getBootstrap().getScheduler().executeAsync(() -> { + this.listener.listenAndBind(); + if (!firstStartup) { + this.plugin.getLogger().info("Postgres listen/notify connection re-established"); + } + }); + return true; + } catch (Exception ignored) { + return false; + } + } + + private class NotificationListener implements PGNotificationListener, AutoCloseable { + private final CountDownLatch latch = new CountDownLatch(1); + private final AtomicBoolean listening = new AtomicBoolean(false); + + public void listenAndBind() { + try (PGConnection connection = PostgresMessenger.this.sqlStorage.getConnectionFactory().getConnection().unwrap(PGConnection.class)) { + connection.addNotificationListener(CHANNEL, this); + + try (Statement s = connection.createStatement()) { + s.execute("LISTEN \"" + CHANNEL + "\""); + } + + this.listening.set(true); + this.latch.await(); + } catch (Exception e) { + e.printStackTrace(); + } finally { + this.listening.set(false); + } + } + + public boolean isListening() { + return this.listening.get(); + } + + @Override + public void notification(int processId, String channelName, String payload) { + if (!CHANNEL.equals(channelName)) { + return; + } + PostgresMessenger.this.consumer.consumeIncomingMessageAsString(payload); + } + + @Override + public void closed() { + this.latch.countDown(); + } + + @Override + public void close() { + this.latch.countDown(); + } + } + +} diff --git a/common/src/main/java/me/lucko/luckperms/common/storage/StorageFactory.java b/common/src/main/java/me/lucko/luckperms/common/storage/StorageFactory.java index a59455699..a089ada69 100644 --- a/common/src/main/java/me/lucko/luckperms/common/storage/StorageFactory.java +++ b/common/src/main/java/me/lucko/luckperms/common/storage/StorageFactory.java @@ -26,7 +26,6 @@ package me.lucko.luckperms.common.storage; import com.google.common.collect.ImmutableSet; - import me.lucko.luckperms.common.config.ConfigKeys; import me.lucko.luckperms.common.plugin.LuckPermsPlugin; import me.lucko.luckperms.common.storage.implementation.StorageImplementation; @@ -45,7 +44,7 @@ import me.lucko.luckperms.common.storage.implementation.sql.connection.file.H2Co import me.lucko.luckperms.common.storage.implementation.sql.connection.file.SqliteConnectionFactory; import me.lucko.luckperms.common.storage.implementation.sql.connection.hikari.MariaDbConnectionFactory; import me.lucko.luckperms.common.storage.implementation.sql.connection.hikari.MySqlConnectionFactory; -import me.lucko.luckperms.common.storage.implementation.sql.connection.hikari.PostgreConnectionFactory; +import me.lucko.luckperms.common.storage.implementation.sql.connection.hikari.PostgresConnectionFactory; import me.lucko.luckperms.common.util.ImmutableCollectors; import java.util.Map; @@ -120,7 +119,7 @@ public class StorageFactory { case POSTGRESQL: return new SqlStorage( this.plugin, - new PostgreConnectionFactory(this.plugin.getConfiguration().get(ConfigKeys.DATABASE_VALUES)), + new PostgresConnectionFactory(this.plugin.getConfiguration().get(ConfigKeys.DATABASE_VALUES)), this.plugin.getConfiguration().get(ConfigKeys.SQL_TABLE_PREFIX) ); case MONGODB: diff --git a/common/src/main/java/me/lucko/luckperms/common/storage/implementation/sql/connection/hikari/HikariConnectionFactory.java b/common/src/main/java/me/lucko/luckperms/common/storage/implementation/sql/connection/hikari/HikariConnectionFactory.java index 21c560d69..f147efac8 100644 --- a/common/src/main/java/me/lucko/luckperms/common/storage/implementation/sql/connection/hikari/HikariConnectionFactory.java +++ b/common/src/main/java/me/lucko/luckperms/common/storage/implementation/sql/connection/hikari/HikariConnectionFactory.java @@ -28,13 +28,11 @@ package me.lucko.luckperms.common.storage.implementation.sql.connection.hikari; import com.google.common.collect.ImmutableList; import com.zaxxer.hikari.HikariConfig; import com.zaxxer.hikari.HikariDataSource; - import me.lucko.luckperms.common.locale.Message; import me.lucko.luckperms.common.plugin.LuckPermsPlugin; import me.lucko.luckperms.common.plugin.logging.PluginLogger; import me.lucko.luckperms.common.storage.implementation.sql.connection.ConnectionFactory; import me.lucko.luckperms.common.storage.misc.StorageCredentials; - import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; @@ -84,7 +82,7 @@ public abstract class HikariConnectionFactory implements ConnectionFactory { * * @param properties the current properties */ - protected void overrideProperties(Map properties) { + protected void overrideProperties(Map properties) { // https://github.com/brettwooldridge/HikariCP/wiki/Rapid-Recovery properties.putIfAbsent("socketTimeout", String.valueOf(TimeUnit.SECONDS.toMillis(30))); } @@ -95,8 +93,8 @@ public abstract class HikariConnectionFactory implements ConnectionFactory { * @param config the hikari config * @param properties the properties */ - protected void setProperties(HikariConfig config, Map properties) { - for (Map.Entry property : properties.entrySet()) { + protected void setProperties(HikariConfig config, Map properties) { + for (Map.Entry property : properties.entrySet()) { config.addDataSourceProperty(property.getKey(), property.getValue()); } } @@ -134,7 +132,7 @@ public abstract class HikariConnectionFactory implements ConnectionFactory { } // get the extra connection properties from the config - Map properties = new HashMap<>(this.configuration.getProperties()); + Map properties = new HashMap<>(this.configuration.getProperties()); // allow the implementation to override/make changes to these properties overrideProperties(properties); diff --git a/common/src/main/java/me/lucko/luckperms/common/storage/implementation/sql/connection/hikari/MariaDbConnectionFactory.java b/common/src/main/java/me/lucko/luckperms/common/storage/implementation/sql/connection/hikari/MariaDbConnectionFactory.java index 092e36f74..2c5be8fe7 100644 --- a/common/src/main/java/me/lucko/luckperms/common/storage/implementation/sql/connection/hikari/MariaDbConnectionFactory.java +++ b/common/src/main/java/me/lucko/luckperms/common/storage/implementation/sql/connection/hikari/MariaDbConnectionFactory.java @@ -26,7 +26,6 @@ package me.lucko.luckperms.common.storage.implementation.sql.connection.hikari; import com.zaxxer.hikari.HikariConfig; - import me.lucko.luckperms.common.storage.misc.StorageCredentials; import java.util.Map; @@ -59,7 +58,7 @@ public class MariaDbConnectionFactory extends HikariConnectionFactory { } @Override - protected void setProperties(HikariConfig config, Map properties) { + protected void setProperties(HikariConfig config, Map properties) { String propertiesString = properties.entrySet().stream() .map(e -> e.getKey() + "=" + e.getValue()) .collect(Collectors.joining(";")); diff --git a/common/src/main/java/me/lucko/luckperms/common/storage/implementation/sql/connection/hikari/MySqlConnectionFactory.java b/common/src/main/java/me/lucko/luckperms/common/storage/implementation/sql/connection/hikari/MySqlConnectionFactory.java index 4269fff96..7240a95fe 100644 --- a/common/src/main/java/me/lucko/luckperms/common/storage/implementation/sql/connection/hikari/MySqlConnectionFactory.java +++ b/common/src/main/java/me/lucko/luckperms/common/storage/implementation/sql/connection/hikari/MySqlConnectionFactory.java @@ -26,7 +26,6 @@ package me.lucko.luckperms.common.storage.implementation.sql.connection.hikari; import com.zaxxer.hikari.HikariConfig; - import me.lucko.luckperms.common.storage.misc.StorageCredentials; import java.sql.Driver; @@ -80,7 +79,7 @@ public class MySqlConnectionFactory extends HikariConnectionFactory { } @Override - protected void overrideProperties(Map properties) { + protected void overrideProperties(Map properties) { // https://github.com/brettwooldridge/HikariCP/wiki/MySQL-Configuration properties.putIfAbsent("cachePrepStmts", "true"); properties.putIfAbsent("prepStmtCacheSize", "250"); diff --git a/common/src/main/java/me/lucko/luckperms/common/storage/implementation/sql/connection/hikari/PostgreConnectionFactory.java b/common/src/main/java/me/lucko/luckperms/common/storage/implementation/sql/connection/hikari/PostgresConnectionFactory.java similarity index 79% rename from common/src/main/java/me/lucko/luckperms/common/storage/implementation/sql/connection/hikari/PostgreConnectionFactory.java rename to common/src/main/java/me/lucko/luckperms/common/storage/implementation/sql/connection/hikari/PostgresConnectionFactory.java index 2bdf4cf51..6fcfb8eae 100644 --- a/common/src/main/java/me/lucko/luckperms/common/storage/implementation/sql/connection/hikari/PostgreConnectionFactory.java +++ b/common/src/main/java/me/lucko/luckperms/common/storage/implementation/sql/connection/hikari/PostgresConnectionFactory.java @@ -26,14 +26,13 @@ package me.lucko.luckperms.common.storage.implementation.sql.connection.hikari; import com.zaxxer.hikari.HikariConfig; - import me.lucko.luckperms.common.storage.misc.StorageCredentials; import java.util.Map; import java.util.function.Function; -public class PostgreConnectionFactory extends HikariConnectionFactory { - public PostgreConnectionFactory(StorageCredentials configuration) { +public class PostgresConnectionFactory extends HikariConnectionFactory { + public PostgresConnectionFactory(StorageCredentials configuration) { super(configuration); } @@ -49,21 +48,27 @@ public class PostgreConnectionFactory extends HikariConnectionFactory { @Override protected void configureDatabase(HikariConfig config, String address, String port, String databaseName, String username, String password) { - config.setDataSourceClassName("org.postgresql.ds.PGSimpleDataSource"); + config.setDataSourceClassName("com.impossibl.postgres.jdbc.PGDataSource"); config.addDataSourceProperty("serverName", address); - config.addDataSourceProperty("portNumber", port); + config.addDataSourceProperty("portNumber", Integer.parseInt(port)); config.addDataSourceProperty("databaseName", databaseName); config.addDataSourceProperty("user", username); config.addDataSourceProperty("password", password); } @Override - protected void overrideProperties(Map properties) { + protected void overrideProperties(Map properties) { super.overrideProperties(properties); // remove the default config properties which don't exist for PostgreSQL properties.remove("useUnicode"); properties.remove("characterEncoding"); + + // socketTimeout -> networkTimeout + Object socketTimeout = properties.remove("socketTimeout"); + if (socketTimeout != null) { + properties.putIfAbsent("networkTimeout", Integer.parseInt(socketTimeout.toString())); + } } @Override diff --git a/fabric/build.gradle b/fabric/build.gradle index 6b3473175..58a298b2c 100644 --- a/fabric/build.gradle +++ b/fabric/build.gradle @@ -61,7 +61,7 @@ shadowJar { relocate 'me.lucko.commodore', 'me.lucko.luckperms.lib.commodore' relocate 'org.mariadb.jdbc', 'me.lucko.luckperms.lib.mariadb' relocate 'com.mysql', 'me.lucko.luckperms.lib.mysql' - relocate 'org.postgresql', 'me.lucko.luckperms.lib.postgresql' + relocate 'com.impossibl', 'me.lucko.luckperms.lib.postgresql' relocate 'com.zaxxer.hikari', 'me.lucko.luckperms.lib.hikari' relocate 'com.mongodb', 'me.lucko.luckperms.lib.mongodb' relocate 'org.bson', 'me.lucko.luckperms.lib.bson' diff --git a/forge/build.gradle b/forge/build.gradle index 99f44014f..b7e674267 100644 --- a/forge/build.gradle +++ b/forge/build.gradle @@ -60,7 +60,7 @@ shadowJar { relocate 'me.lucko.commodore', 'me.lucko.luckperms.lib.commodore' relocate 'org.mariadb.jdbc', 'me.lucko.luckperms.lib.mariadb' relocate 'com.mysql', 'me.lucko.luckperms.lib.mysql' - relocate 'org.postgresql', 'me.lucko.luckperms.lib.postgresql' + relocate 'com.impossibl', 'me.lucko.luckperms.lib.postgresql' relocate 'com.zaxxer.hikari', 'me.lucko.luckperms.lib.hikari' relocate 'com.mongodb', 'me.lucko.luckperms.lib.mongodb' relocate 'org.bson', 'me.lucko.luckperms.lib.bson' diff --git a/nukkit/build.gradle b/nukkit/build.gradle index 250ab1d1f..b97fa9106 100644 --- a/nukkit/build.gradle +++ b/nukkit/build.gradle @@ -29,7 +29,7 @@ shadowJar { relocate 'me.lucko.commodore', 'me.lucko.luckperms.lib.commodore' relocate 'org.mariadb.jdbc', 'me.lucko.luckperms.lib.mariadb' relocate 'com.mysql', 'me.lucko.luckperms.lib.mysql' - relocate 'org.postgresql', 'me.lucko.luckperms.lib.postgresql' + relocate 'com.impossibl', 'me.lucko.luckperms.lib.postgresql' relocate 'com.zaxxer.hikari', 'me.lucko.luckperms.lib.hikari' relocate 'com.mongodb', 'me.lucko.luckperms.lib.mongodb' relocate 'org.bson', 'me.lucko.luckperms.lib.bson' diff --git a/sponge/build.gradle b/sponge/build.gradle index 0161ccb3f..0c19a9008 100644 --- a/sponge/build.gradle +++ b/sponge/build.gradle @@ -42,7 +42,7 @@ shadowJar { relocate 'me.lucko.commodore', 'me.lucko.luckperms.lib.commodore' relocate 'org.mariadb.jdbc', 'me.lucko.luckperms.lib.mariadb' relocate 'com.mysql', 'me.lucko.luckperms.lib.mysql' - relocate 'org.postgresql', 'me.lucko.luckperms.lib.postgresql' + relocate 'com.impossibl', 'me.lucko.luckperms.lib.postgresql' relocate 'com.zaxxer.hikari', 'me.lucko.luckperms.lib.hikari' relocate 'com.mongodb', 'me.lucko.luckperms.lib.mongodb' relocate 'org.bson', 'me.lucko.luckperms.lib.bson' diff --git a/standalone/build.gradle b/standalone/build.gradle index df177be6d..157d3f051 100644 --- a/standalone/build.gradle +++ b/standalone/build.gradle @@ -27,13 +27,18 @@ dependencies { testImplementation 'org.mockito:mockito-core:4.11.0' testImplementation 'org.mockito:mockito-junit-jupiter:4.11.0' + testImplementation 'com.zaxxer:HikariCP:4.0.3' + testImplementation 'redis.clients:jedis:3.5.2' + testImplementation 'io.nats:jnats:2.16.4' + testImplementation 'com.rabbitmq:amqp-client:5.12.0' + testImplementation 'com.impossibl.pgjdbc-ng:pgjdbc-ng:0.8.9' testImplementation 'com.h2database:h2:2.1.214' testImplementation 'mysql:mysql-connector-java:8.0.23' testImplementation 'org.mariadb.jdbc:mariadb-java-client:2.7.2' - testImplementation 'org.postgresql:postgresql:42.2.19' testImplementation 'org.mongodb:mongodb-driver-sync:4.5.0' testImplementation 'me.lucko.configurate:configurate-toml:3.7' testImplementation 'org.spongepowered:configurate-hocon:3.7.2' + testImplementation 'org.yaml:snakeyaml:1.28' testImplementation project(':standalone:app') testImplementation project(':common:loader-utils') @@ -54,7 +59,7 @@ shadowJar { relocate 'me.lucko.commodore', 'me.lucko.luckperms.lib.commodore' relocate 'org.mariadb.jdbc', 'me.lucko.luckperms.lib.mariadb' relocate 'com.mysql', 'me.lucko.luckperms.lib.mysql' - relocate 'org.postgresql', 'me.lucko.luckperms.lib.postgresql' + relocate 'com.impossibl', 'me.lucko.luckperms.lib.postgresql' relocate 'com.zaxxer.hikari', 'me.lucko.luckperms.lib.hikari' relocate 'com.mongodb', 'me.lucko.luckperms.lib.mongodb' relocate 'org.bson', 'me.lucko.luckperms.lib.bson' diff --git a/standalone/src/test/java/me/lucko/luckperms/standalone/MessagingIntegrationTest.java b/standalone/src/test/java/me/lucko/luckperms/standalone/MessagingIntegrationTest.java index 920697271..2bc50e739 100644 --- a/standalone/src/test/java/me/lucko/luckperms/standalone/MessagingIntegrationTest.java +++ b/standalone/src/test/java/me/lucko/luckperms/standalone/MessagingIntegrationTest.java @@ -51,7 +51,7 @@ import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertTrue; @Testcontainers -@Tag("docker") +//@Tag("docker") public class MessagingIntegrationTest { private static void testMessaging(Map config, Path tempDirA, Path tempDirB) throws InterruptedException { @@ -73,7 +73,10 @@ public class MessagingIntegrationTest { assertNotNull(messagingServiceB); CountDownLatch latch = new CountDownLatch(1); - pluginB.app().getApi().getEventBus().subscribe(PreNetworkSyncEvent.class, e -> latch.countDown()); + pluginB.app().getApi().getEventBus().subscribe(PreNetworkSyncEvent.class, e -> { + latch.countDown(); + e.setCancelled(true); + }); // send a message from plugin A to plugin B and wait for the message to be received messagingServiceA.pushUpdate(); @@ -109,6 +112,33 @@ public class MessagingIntegrationTest { } } + @Nested + class Postgres { + + @Container + private final GenericContainer container = new GenericContainer<>(DockerImageName.parse("postgres")) + .withEnv("POSTGRES_PASSWORD", "passw0rd") + .withExposedPorts(5432); + + @Test + public void testPostgres(@TempDir Path tempDirA, @TempDir Path tempDirB) throws InterruptedException { + assertTrue(this.container.isRunning()); + + String host = this.container.getHost(); + Integer port = this.container.getFirstMappedPort(); + + Map config = ImmutableMap.builder() + .put("storage-method", "postgresql") + .put("data.address", host + ":" + port) + .put("data.database", "postgres") + .put("data.username", "postgres") + .put("data.password", "passw0rd") + .build(); + + testMessaging(config, tempDirA, tempDirB); + } + } + @Nested class Redis { diff --git a/velocity/build.gradle b/velocity/build.gradle index 4b9890c00..c43a6f256 100644 --- a/velocity/build.gradle +++ b/velocity/build.gradle @@ -36,7 +36,7 @@ shadowJar { relocate 'me.lucko.commodore', 'me.lucko.luckperms.lib.commodore' relocate 'org.mariadb.jdbc', 'me.lucko.luckperms.lib.mariadb' relocate 'com.mysql', 'me.lucko.luckperms.lib.mysql' - relocate 'org.postgresql', 'me.lucko.luckperms.lib.postgresql' + relocate 'com.impossibl', 'me.lucko.luckperms.lib.postgresql' relocate 'com.zaxxer.hikari', 'me.lucko.luckperms.lib.hikari' relocate 'com.mongodb', 'me.lucko.luckperms.lib.mongodb' relocate 'org.bson', 'me.lucko.luckperms.lib.bson'