package me.moodcat.database; import java.io.IOException; import java.io.InputStream; import java.util.Properties; import lombok.SneakyThrows; import com.google.common.base.Preconditions; import com.google.inject.AbstractModule; import com.google.inject.persist.jpa.JpaPersistModule; import lombok.extern.slf4j.Slf4j; /** * Guice AbstractModule that installs the JpaPersistModule for the current Persistence unit. * The properties are loaded from the resource which allows a different configuration under test. */ @Slf4j public class DbModule extends AbstractModule { /** * The name of the environment variable to set when running in production. */ private static final String ENVIRONMENT_DATABASE_VARIABLE_NAME = "Database_Password"; /** * The name of the property to set when running tests/locally. */ private static final String PASSWORD_PROPERTY_NAME = "javax.persistence.jdbc.password"; /** * Unit defined in src/main/resources/META-INF/persistence.xml. */ private static final String MOODCAT_PERSISTENCE_UNIT = "moodcat"; @Override @SneakyThrows protected void configure() { final JpaPersistModule jpaModule = new JpaPersistModule(MOODCAT_PERSISTENCE_UNIT); final Properties properties = getProperties(); setDatabasePassword(properties); jpaModule.properties(properties); install(jpaModule); } protected Properties getProperties() throws IOException { try (InputStream stream = DbModule.class.getResourceAsStream("/persistence.properties")) { final Properties properties = new Properties(); Preconditions.checkNotNull(stream, "Persistence properties not found"); properties.load(stream); log.info("Using database {}", properties.getProperty("javax.persistence.jdbc.url")); return properties; } } protected String getSystemEnvironmentVariable() { return System.getenv(ENVIRONMENT_DATABASE_VARIABLE_NAME); } private void setDatabasePassword(final Properties properties) throws DatabaseConfigurationException { final String databasePassword = getSystemEnvironmentVariable(); // This will be null if it is run in the test environment. if (databasePassword != null) { properties.setProperty(PASSWORD_PROPERTY_NAME, databasePassword); } // Make sure the property is set, else notify developer/admin the configuration is invalid if (properties.getProperty(PASSWORD_PROPERTY_NAME) == null) { throw new DatabaseConfigurationException("The database password is not set." + "Make sure the environment contains the variable '" + ENVIRONMENT_DATABASE_VARIABLE_NAME + "'."); } } /** * Exception thrown when the database configuration is invalid. */ protected static class DatabaseConfigurationException extends Exception { /** * Generated UID. */ private static final long serialVersionUID = 1071139882151857332L; protected DatabaseConfigurationException(final String string) { super(string); } } }