Add Flyway, run db migration in local PostgreSQL db
First step in my plan to switch away from MySQL.
This commit is contained in:
@@ -165,6 +165,14 @@ server:
|
|||||||
DB_PASS: "snailshell"
|
DB_PASS: "snailshell"
|
||||||
INIT_CONNECTION_POOL_TIMEOUT: 90 # Seconds
|
INIT_CONNECTION_POOL_TIMEOUT: 90 # Seconds
|
||||||
|
|
||||||
|
PG_DB_NAME: "cosmic"
|
||||||
|
PG_DB_HOST: "localhost"
|
||||||
|
PG_DB_SCHEMA: "cosmic"
|
||||||
|
PG_DB_ADMIN_USERNAME: "cosmic_admin"
|
||||||
|
PG_DB_ADMIN_PASSWORD: "redsnailshell"
|
||||||
|
PG_DB_USERNAME: "cosmic_server"
|
||||||
|
PG_DB_PASSWORD: "bluesnailshell"
|
||||||
|
|
||||||
#Login Configuration
|
#Login Configuration
|
||||||
WORLDS: 1 #Initial number of worlds on the server.
|
WORLDS: 1 #Initial number of worlds on the server.
|
||||||
WLDLIST_SIZE: 21 #Max possible worlds on the server.
|
WLDLIST_SIZE: 21 #Max possible worlds on the server.
|
||||||
|
|||||||
3
database/postgresql/create-admin-user.sql
Normal file
3
database/postgresql/create-admin-user.sql
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
CREATE USER cosmic_admin WITH ENCRYPTED PASSWORD 'redsnailshell';
|
||||||
|
GRANT ALL PRIVILEGES ON DATABASE cosmic TO cosmic_admin;
|
||||||
|
ALTER ROLE cosmic_admin WITH CREATEROLE;
|
||||||
12
pom.xml
12
pom.xml
@@ -32,6 +32,8 @@
|
|||||||
<jcip-annotations.version>1.0</jcip-annotations.version> <!-- Annotations for concurrency documentation -->
|
<jcip-annotations.version>1.0</jcip-annotations.version> <!-- Annotations for concurrency documentation -->
|
||||||
<HikariCP.version>5.0.1</HikariCP.version> <!-- Database connection pool -->
|
<HikariCP.version>5.0.1</HikariCP.version> <!-- Database connection pool -->
|
||||||
<mysql-connector-java.version>8.0.30</mysql-connector-java.version> <!-- MySQL JDBC driver -->
|
<mysql-connector-java.version>8.0.30</mysql-connector-java.version> <!-- MySQL JDBC driver -->
|
||||||
|
<postgresql.version>42.5.4</postgresql.version> <!-- PostgreSQL JDBC driver -->
|
||||||
|
<flyway.version>9.15.1</flyway.version> <!-- Database migration -->
|
||||||
<jdbi-version>3.35.0</jdbi-version> <!-- Convenience wrapper around JDBC -->
|
<jdbi-version>3.35.0</jdbi-version> <!-- Convenience wrapper around JDBC -->
|
||||||
<junit.version>5.9.0</junit.version> <!-- Unit test -->
|
<junit.version>5.9.0</junit.version> <!-- Unit test -->
|
||||||
<mockito.version>4.7.0</mockito.version> <!-- Unit test -->
|
<mockito.version>4.7.0</mockito.version> <!-- Unit test -->
|
||||||
@@ -60,11 +62,21 @@
|
|||||||
<artifactId>mysql-connector-java</artifactId>
|
<artifactId>mysql-connector-java</artifactId>
|
||||||
<version>${mysql-connector-java.version}</version>
|
<version>${mysql-connector-java.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.postgresql</groupId>
|
||||||
|
<artifactId>postgresql</artifactId>
|
||||||
|
<version>${postgresql.version}</version>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.jdbi</groupId>
|
<groupId>org.jdbi</groupId>
|
||||||
<artifactId>jdbi3-core</artifactId>
|
<artifactId>jdbi3-core</artifactId>
|
||||||
<version>${jdbi-version}</version>
|
<version>${jdbi-version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.flywaydb</groupId>
|
||||||
|
<artifactId>flyway-core</artifactId>
|
||||||
|
<version>${flyway.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
|
||||||
<!-- Networking -->
|
<!-- Networking -->
|
||||||
|
|||||||
@@ -12,6 +12,15 @@ public class ServerConfig {
|
|||||||
public String DB_PASS;
|
public String DB_PASS;
|
||||||
public int INIT_CONNECTION_POOL_TIMEOUT;
|
public int INIT_CONNECTION_POOL_TIMEOUT;
|
||||||
|
|
||||||
|
// PostgreSQL database configuration
|
||||||
|
public String PG_DB_NAME;
|
||||||
|
public String PG_DB_HOST;
|
||||||
|
public String PG_DB_SCHEMA;
|
||||||
|
public String PG_DB_ADMIN_USERNAME;
|
||||||
|
public String PG_DB_ADMIN_PASSWORD;
|
||||||
|
public String PG_DB_USERNAME;
|
||||||
|
public String PG_DB_PASSWORD;
|
||||||
|
|
||||||
//Login Configuration
|
//Login Configuration
|
||||||
public int WORLDS;
|
public int WORLDS;
|
||||||
public int WLDLIST_SIZE;
|
public int WLDLIST_SIZE;
|
||||||
|
|||||||
30
src/main/java/database/PgDatabaseConfig.java
Normal file
30
src/main/java/database/PgDatabaseConfig.java
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
package database;
|
||||||
|
|
||||||
|
import java.time.Duration;
|
||||||
|
|
||||||
|
public record PgDatabaseConfig(
|
||||||
|
String databaseName, String host, String schema,
|
||||||
|
String adminUsername, String adminPassword,
|
||||||
|
String username, String password,
|
||||||
|
Duration poolInitTimeout
|
||||||
|
) {
|
||||||
|
public PgDatabaseConfig {
|
||||||
|
verifyNotBlank(databaseName);
|
||||||
|
verifyNotBlank(host);
|
||||||
|
verifyNotBlank(schema);
|
||||||
|
verifyNotBlank(adminUsername);
|
||||||
|
verifyNotBlank(adminPassword);
|
||||||
|
verifyNotBlank(username);
|
||||||
|
verifyNotBlank(password);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void verifyNotBlank(String value) {
|
||||||
|
if (value == null || value.isBlank()) {
|
||||||
|
throw new IllegalArgumentException("Missing or blank value in PG database config");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getJdbcUrl() {
|
||||||
|
return "jdbc:postgresql://%s:5432/%s".formatted(host, databaseName);
|
||||||
|
}
|
||||||
|
}
|
||||||
22
src/main/java/database/migration/FlywayRunner.java
Normal file
22
src/main/java/database/migration/FlywayRunner.java
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
package database.migration;
|
||||||
|
|
||||||
|
import database.PgDatabaseConfig;
|
||||||
|
import org.flywaydb.core.Flyway;
|
||||||
|
import org.flywaydb.core.api.FlywayException;
|
||||||
|
|
||||||
|
public class FlywayRunner {
|
||||||
|
private final PgDatabaseConfig dbConfig;
|
||||||
|
|
||||||
|
public FlywayRunner(PgDatabaseConfig dbConfig) {
|
||||||
|
this.dbConfig = dbConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void migrate() throws FlywayException {
|
||||||
|
Flyway flyway = Flyway.configure()
|
||||||
|
.dataSource(dbConfig.getJdbcUrl(), dbConfig.adminUsername(), dbConfig.adminPassword())
|
||||||
|
.schemas(dbConfig.schema())
|
||||||
|
.createSchemas(true)
|
||||||
|
.load();
|
||||||
|
flyway.migrate();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -31,11 +31,14 @@ import client.inventory.ItemFactory;
|
|||||||
import client.inventory.manipulator.CashIdGenerator;
|
import client.inventory.manipulator.CashIdGenerator;
|
||||||
import client.newyear.NewYearCardRecord;
|
import client.newyear.NewYearCardRecord;
|
||||||
import client.processor.npc.FredrickProcessor;
|
import client.processor.npc.FredrickProcessor;
|
||||||
|
import config.ServerConfig;
|
||||||
import config.YamlConfig;
|
import config.YamlConfig;
|
||||||
import constants.game.GameConstants;
|
import constants.game.GameConstants;
|
||||||
import constants.inventory.ItemConstants;
|
import constants.inventory.ItemConstants;
|
||||||
import constants.net.OpcodeConstants;
|
import constants.net.OpcodeConstants;
|
||||||
import constants.net.ServerConstants;
|
import constants.net.ServerConstants;
|
||||||
|
import database.PgDatabaseConfig;
|
||||||
|
import database.migration.FlywayRunner;
|
||||||
import database.note.NoteDao;
|
import database.note.NoteDao;
|
||||||
import net.ChannelDependencies;
|
import net.ChannelDependencies;
|
||||||
import net.PacketProcessor;
|
import net.PacketProcessor;
|
||||||
@@ -840,6 +843,8 @@ public class Server {
|
|||||||
Runtime.getRuntime().addShutdownHook(new Thread(shutdown(false)));
|
Runtime.getRuntime().addShutdownHook(new Thread(shutdown(false)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
runDatabaseMigration();
|
||||||
|
|
||||||
if (!DatabaseConnection.initializeConnectionPool()) {
|
if (!DatabaseConnection.initializeConnectionPool()) {
|
||||||
throw new IllegalStateException("Failed to initiate a connection to the database");
|
throw new IllegalStateException("Failed to initiate a connection to the database");
|
||||||
}
|
}
|
||||||
@@ -922,6 +927,22 @@ 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;
|
||||||
|
return new PgDatabaseConfig(
|
||||||
|
serverConfig.PG_DB_NAME, serverConfig.PG_DB_HOST, serverConfig.PG_DB_SCHEMA,
|
||||||
|
serverConfig.PG_DB_ADMIN_USERNAME, serverConfig.PG_DB_ADMIN_PASSWORD,
|
||||||
|
serverConfig.PG_DB_USERNAME, serverConfig.PG_DB_PASSWORD,
|
||||||
|
Duration.ofSeconds(serverConfig.INIT_CONNECTION_POOL_TIMEOUT)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
private ChannelDependencies registerChannelDependencies() {
|
private ChannelDependencies registerChannelDependencies() {
|
||||||
NoteService noteService = new NoteService(new NoteDao());
|
NoteService noteService = new NoteService(new NoteDao());
|
||||||
FredrickProcessor fredrickProcessor = new FredrickProcessor(noteService);
|
FredrickProcessor fredrickProcessor = new FredrickProcessor(noteService);
|
||||||
|
|||||||
4
src/main/resources/db/migration/postgresql/V0__test.sql
Normal file
4
src/main/resources/db/migration/postgresql/V0__test.sql
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
CREATE TABLE flyway_test(
|
||||||
|
id SERIAL PRIMARY KEY,
|
||||||
|
dummy TEXT
|
||||||
|
);
|
||||||
@@ -100,5 +100,7 @@
|
|||||||
|
|
||||||
<Logger name="com.zaxxer.hikari" level="info"/>
|
<Logger name="com.zaxxer.hikari" level="info"/>
|
||||||
<Logger name="io.netty" level="info"/>
|
<Logger name="io.netty" level="info"/>
|
||||||
|
<Logger name="org.flywaydb" level="info"/>
|
||||||
|
<Logger name="org.flywaydb.core.internal.license.VersionPrinter" level="off"/>
|
||||||
</Loggers>
|
</Loggers>
|
||||||
</Configuration>
|
</Configuration>
|
||||||
Reference in New Issue
Block a user