diff --git a/pom.xml b/pom.xml index b0ed9b5..8837eb4 100644 --- a/pom.xml +++ b/pom.xml @@ -55,7 +55,7 @@ org.apache.logging.log4j - log4j-slf4j2-impl + log4j-slf4j-impl ${log4j.version} @@ -83,6 +83,13 @@ protobuf-java 4.32.0 + + io.zonky.test + embedded-postgres + 2.0.6 + + + diff --git a/src/main/java/com/mediamanager/MediaManagerApplication.java b/src/main/java/com/mediamanager/MediaManagerApplication.java index bc04be1..7d58c03 100644 --- a/src/main/java/com/mediamanager/MediaManagerApplication.java +++ b/src/main/java/com/mediamanager/MediaManagerApplication.java @@ -9,22 +9,55 @@ import java.io.IOException; import java.io.InputStream; import java.util.Properties; -import com.mediamanager.service.database.DatabaseManager; +import com.mediamanager.service.database.LocalDatabaseManager; public class MediaManagerApplication { private static final Logger logger = LogManager.getLogger(MediaManagerApplication.class); private static Properties config; - private static DatabaseManager databaseManager; + private static LocalDatabaseManager databaseManager; private static DelegateActionManager actionManager; private static IPCManager ipcManager; + public enum ApplicationMode { + LOCAL("local"), + SERVER("server"); + + private final String value; + + ApplicationMode(String value) { + this.value = value; + } + } + public static void main(String[] args) { logger.info("Starting MediaManager Core Application..."); try { // Load configuration loadConfiguration(); - databaseManager = new DatabaseManager(config); + String runTypeString = config.getProperty("runtype","local"); + ApplicationMode mode = null; + + for (ApplicationMode am : ApplicationMode.values()) { + if (am.value.equalsIgnoreCase(runTypeString)) { + mode = am; + break; + } + } + if (mode == null) { + logger.error("Invalid run type: {}", runTypeString); + throw new Exception("Invalid run type: " + runTypeString); + } + logger.info("Run type: {}", mode); + switch (mode) { + case LOCAL: + logger.info("Starting local database..."); + databaseManager = new LocalDatabaseManager(config); + break; + case SERVER: + throw new Exception("Server mode not yet implemented"); + default: + } databaseManager.init(); actionManager = new DelegateActionManager(); actionManager.start(); diff --git a/src/main/java/com/mediamanager/service/database/DatabaseManager.java b/src/main/java/com/mediamanager/service/database/DatabaseManager.java index eeabc69..dbbaed4 100644 --- a/src/main/java/com/mediamanager/service/database/DatabaseManager.java +++ b/src/main/java/com/mediamanager/service/database/DatabaseManager.java @@ -1,55 +1,28 @@ package com.mediamanager.service.database; + import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import java.sql.Connection; -import java.sql.DriverManager; import java.sql.SQLException; import java.sql.Statement; import java.util.Properties; +public abstract class DatabaseManager { + protected final Properties configuration; + protected Connection connection; + protected static final Logger logger = LogManager.getLogger(DatabaseManager.class); -public class DatabaseManager { - private final Properties configuration; - private Connection connection; - private static final Logger logger = LogManager.getLogger(DatabaseManager.class); public DatabaseManager(Properties config) { this.configuration = config; logger.debug("DatabaseManager created with configuration:"); - } - public void init() throws Exception { - logger.info("Initializing database connection..."); - validateConfiguration(); + public abstract void init() throws Exception; - String databaseType = configuration.getProperty("database.type"); - String databaseUrl = configuration.getProperty("database.url"); - String databaseUsername = configuration.getProperty("database.username"); - String databasePassword = configuration.getProperty("database.password"); - String databasePort = configuration.getProperty("database.port"); - String databaseName = configuration.getProperty("database.name"); + protected abstract Connection createConnection() throws Exception; - - String connectionString = String.format("jdbc:postgresql://%s:%s/%s", databaseUrl, databasePort, databaseName); - logger.debug("Attempting to connect to: {}", connectionString); - try { - connection = DriverManager.getConnection(connectionString, databaseUsername, databasePassword); - logger.info("Database connection established successfully"); - - performSanityChecks(); - logger.info("Database sanity checks passed successfully"); - - - } catch (SQLException e) { - logger.error("Failed to connect to database", e); - throw new Exception("Database connection failed: " + e.getMessage(), e); - } - - - - } - private void performSanityChecks() throws SQLException { + protected void performSanityChecks() throws SQLException { logger.debug("Performing sanity checks..."); try (Statement stmt = connection.createStatement()) { stmt.execute("SELECT 1"); @@ -59,27 +32,6 @@ public class DatabaseManager { String databaseProductVersion = connection.getMetaData().getDatabaseProductVersion(); logger.info("Connected to database: {} v{}", databaseProductName, databaseProductVersion); } - private void validateConfiguration() throws Exception { - String[] requiredProperties = { - "database.url", - "database.username", - "database.password", - "database.port", - "database.name" - }; - - for (String property : requiredProperties) { - if (configuration.getProperty(property) == null || - configuration.getProperty(property).trim().isEmpty()) { - throw new Exception("Required database configuration missing: " + property); - } - } - - logger.debug("Database configuration validated successfully"); - - } - - public Connection getConnection() { return connection; @@ -98,4 +50,13 @@ public class DatabaseManager { logger.debug("No database connection to close"); } } + protected boolean testConnection() { + try (Statement stmt = connection.createStatement()) { + stmt.execute("SELECT 1"); + return true; + } catch (SQLException e) { + logger.error("Connection test failed", e); + return false; + } + } } diff --git a/src/main/java/com/mediamanager/service/database/LocalDatabaseManager.java b/src/main/java/com/mediamanager/service/database/LocalDatabaseManager.java new file mode 100644 index 0000000..718401b --- /dev/null +++ b/src/main/java/com/mediamanager/service/database/LocalDatabaseManager.java @@ -0,0 +1,87 @@ +package com.mediamanager.service.database; + +import io.zonky.test.db.postgres.embedded.EmbeddedPostgres; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.sql.Connection; +import java.util.Properties; + +public class LocalDatabaseManager extends DatabaseManager { + private static final Logger logger = LogManager.getLogger(LocalDatabaseManager.class); + private EmbeddedPostgres embeddedPostgres; + + public LocalDatabaseManager(Properties config) { + super(config); + } + + @Override + public void init() throws Exception { + logger.info("Initializing embedded PostgreSQL database..."); + + // Configurações específicas do modo local + String dataDir = configuration.getProperty("local.database.dir", + System.getProperty("user.home") + "/.mediamanager/db"); + int port = Integer.parseInt( + configuration.getProperty("local.database.port", "54321") + ); + + // Cria diretório se não existir + Path dataPath = Paths.get(dataDir); + Files.createDirectories(dataPath); + logger.debug("Using data directory: {}", dataDir); + + // Inicia o PostgreSQL embedded + logger.info("Starting embedded PostgreSQL on port {}", port); + embeddedPostgres = EmbeddedPostgres.builder() + .setDataDirectory(dataPath) + .setCleanDataDirectory(false) // Mantém dados + .setPort(port) + .start(); + + // Cria a conexão + this.connection = createConnection(); + logger.info("Embedded database connection established successfully"); + + // Usa o método da classe pai para sanity checks + performSanityChecks(); + logger.info("Database sanity checks passed successfully"); + } + + @Override + protected Connection createConnection() throws Exception { + if (embeddedPostgres == null) { + throw new IllegalStateException("Embedded PostgreSQL not started"); + } + + try { + // Pega conexão do embedded + Connection conn = embeddedPostgres.getPostgresDatabase().getConnection(); + logger.debug("Got connection from embedded PostgreSQL"); + return conn; + } catch (Exception e) { + logger.error("Failed to get embedded connection", e); + throw new Exception("Embedded connection failed: " + e.getMessage(), e); + } + } + + @Override + public void close() { + // Primeiro fecha a conexão (método da classe pai) + super.close(); + + // Depois para o embedded + if (embeddedPostgres != null) { + try { + logger.info("Stopping embedded PostgreSQL..."); + embeddedPostgres.close(); + logger.info("Embedded PostgreSQL stopped successfully"); + } catch (Exception e) { + logger.error("Error stopping embedded PostgreSQL", e); + } + } + } +} \ No newline at end of file diff --git a/src/main/resources/config.properties.example b/src/main/resources/config.properties.example index 095d75c..6e9634e 100644 --- a/src/main/resources/config.properties.example +++ b/src/main/resources/config.properties.example @@ -23,4 +23,5 @@ ipc.pipe.path=/tmp/mediamanager ipc.buffer.size=8192 ipc.socket.path=/tmp/mediamanager +runtype=local diff --git a/src/main/resources/log4j2.xml b/src/main/resources/log4j2.xml index 39be1a8..d3b2458 100644 --- a/src/main/resources/log4j2.xml +++ b/src/main/resources/log4j2.xml @@ -27,6 +27,29 @@ + + + + + + + + + + + + + + + + + + + + + + +