diff --git a/src/main/java/database/PgDatabaseConnection.java b/src/main/java/database/PgDatabaseConnection.java new file mode 100644 index 0000000000..c8d3a254cd --- /dev/null +++ b/src/main/java/database/PgDatabaseConnection.java @@ -0,0 +1,28 @@ +package database; + +import database.note.NoteRowMapper; +import org.jdbi.v3.core.Handle; +import org.jdbi.v3.core.Jdbi; + +import javax.sql.DataSource; +import java.sql.Connection; +import java.sql.SQLException; + +public class PgDatabaseConnection { + private final DataSource dataSource; + private final Jdbi jdbi; + + public PgDatabaseConnection(DataSource dataSource) { + this.dataSource = dataSource; + this.jdbi = Jdbi.create(dataSource) + .registerRowMapper(new NoteRowMapper()); // TODO: configure jdbi elsewhere + } + + public Connection getConnection() throws SQLException { + return dataSource.getConnection(); + } + + public Handle getHandle() { + return jdbi.open(); + } +} diff --git a/src/main/java/database/migration/FlywayRunner.java b/src/main/java/database/migration/FlywayRunner.java index aed1633e4f..edbb2aba25 100644 --- a/src/main/java/database/migration/FlywayRunner.java +++ b/src/main/java/database/migration/FlywayRunner.java @@ -4,6 +4,8 @@ import database.PgDatabaseConfig; import org.flywaydb.core.Flyway; import org.flywaydb.core.api.FlywayException; +import java.util.Map; + public class FlywayRunner { private final PgDatabaseConfig dbConfig; @@ -18,6 +20,10 @@ public class FlywayRunner { .createSchemas(true) .connectRetries(10) .connectRetriesInterval(5) + .placeholders(Map.of( + "server-username", dbConfig.username(), + "server-password", dbConfig.password()) + ) .load(); flyway.migrate(); } diff --git a/src/main/java/database/note/NoteDao.java b/src/main/java/database/note/NoteDao.java index d429aa249f..9bdeb8dcac 100644 --- a/src/main/java/database/note/NoteDao.java +++ b/src/main/java/database/note/NoteDao.java @@ -1,6 +1,7 @@ package database.note; import database.DaoException; +import database.PgDatabaseConnection; import model.Note; import org.jdbi.v3.core.Handle; import org.jdbi.v3.core.JdbiException; @@ -10,6 +11,11 @@ import java.util.List; import java.util.Optional; public class NoteDao { + private final PgDatabaseConnection connection; + + public NoteDao(PgDatabaseConnection connection) { + this.connection = connection; + } public void save(Note note) { try (Handle handle = DatabaseConnection.getHandle()) { diff --git a/src/main/java/net/server/Server.java b/src/main/java/net/server/Server.java index 64830194fb..c2c985964c 100644 --- a/src/main/java/net/server/Server.java +++ b/src/main/java/net/server/Server.java @@ -31,6 +31,8 @@ import client.inventory.ItemFactory; import client.inventory.manipulator.CashIdGenerator; import client.newyear.NewYearCardRecord; import client.processor.npc.FredrickProcessor; +import com.zaxxer.hikari.HikariConfig; +import com.zaxxer.hikari.HikariDataSource; import config.ServerConfig; import config.YamlConfig; import constants.game.GameConstants; @@ -38,6 +40,7 @@ import constants.inventory.ItemConstants; import constants.net.OpcodeConstants; import constants.net.ServerConstants; import database.PgDatabaseConfig; +import database.PgDatabaseConnection; import database.migration.FlywayRunner; import database.note.NoteDao; import net.ChannelDependencies; @@ -843,13 +846,15 @@ public class Server { Runtime.getRuntime().addShutdownHook(new Thread(shutdown(false))); } - runDatabaseMigration(); + PgDatabaseConfig pgDbConfig = readPgDbConfig(); + runDatabaseMigration(pgDbConfig); + PgDatabaseConnection pgDbConnection = createPgDbConnection(pgDbConfig); if (!DatabaseConnection.initializeConnectionPool()) { throw new IllegalStateException("Failed to initiate a connection to the database"); } - channelDependencies = registerChannelDependencies(); + channelDependencies = registerChannelDependencies(pgDbConnection); final ExecutorService initExecutor = Executors.newFixedThreadPool(10); // Run slow operations asynchronously to make startup faster @@ -927,12 +932,6 @@ public class Server { } } - private void runDatabaseMigration() { - PgDatabaseConfig pgDbConfig = readPgDbConfig(); - FlywayRunner flywayRunner = new FlywayRunner(pgDbConfig); - flywayRunner.migrate(); - } - private PgDatabaseConfig readPgDbConfig() { final ServerConfig serverConfig = YamlConfig.config.server; String pgDbHost = System.getenv("PG_DB_HOST"); @@ -947,8 +946,29 @@ public class Server { ); } - private ChannelDependencies registerChannelDependencies() { - NoteService noteService = new NoteService(new NoteDao()); + private void runDatabaseMigration(PgDatabaseConfig config) { + FlywayRunner flywayRunner = new FlywayRunner(config); + flywayRunner.migrate(); + } + + private PgDatabaseConnection createPgDbConnection(PgDatabaseConfig config) { + var hikariConfig = createHikariConfig(config); + var dataSource = new HikariDataSource(hikariConfig); + return new PgDatabaseConnection(dataSource); + } + + private HikariConfig createHikariConfig(PgDatabaseConfig config) { + final HikariConfig hikariConfig = new HikariConfig(); + hikariConfig.setJdbcUrl(config.getJdbcUrl()); + hikariConfig.setSchema(config.schema()); + hikariConfig.setUsername(config.username()); + hikariConfig.setPassword(config.password()); + hikariConfig.setInitializationFailTimeout(config.poolInitTimeout().toMillis()); + return hikariConfig; + } + + private ChannelDependencies registerChannelDependencies(PgDatabaseConnection connection) { + NoteService noteService = new NoteService(new NoteDao(connection)); FredrickProcessor fredrickProcessor = new FredrickProcessor(noteService); ChannelDependencies channelDependencies = new ChannelDependencies(noteService, fredrickProcessor); diff --git a/src/main/resources/db/migration/postgresql/V0.1__server_user.sql b/src/main/resources/db/migration/postgresql/V0.1__server_user.sql new file mode 100644 index 0000000000..d3e6da8a36 --- /dev/null +++ b/src/main/resources/db/migration/postgresql/V0.1__server_user.sql @@ -0,0 +1,7 @@ +DO $$ +BEGIN + CREATE USER ${server-username} WITH PASSWORD '${server-password}'; + EXCEPTION WHEN duplicate_object THEN RAISE NOTICE '%, skipping', SQLERRM USING ERRCODE = SQLSTATE; +END +$$; +GRANT USAGE ON SCHEMA ${flyway:defaultSchema} TO ${server-username}; \ No newline at end of file diff --git a/src/main/resources/db/migration/postgresql/V0__test.sql b/src/main/resources/db/migration/postgresql/V0__test.sql deleted file mode 100644 index e554e389ed..0000000000 --- a/src/main/resources/db/migration/postgresql/V0__test.sql +++ /dev/null @@ -1,4 +0,0 @@ -CREATE TABLE flyway_test( - id SERIAL PRIMARY KEY, - dummy TEXT -); \ No newline at end of file