Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/921 read hibernate config from application properties cleanup #970

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package ch.puzzle.okr;

import ch.puzzle.okr.multitenancy.listener.HibernateContext;
import ch.puzzle.okr.multitenancy.HibernateContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContextInitializer;
Expand All @@ -15,7 +15,7 @@ public class OkrApplicationContextInitializer implements ApplicationContextIniti
@Override
public void initialize(ConfigurableApplicationContext applicationContext) {
logger.info("Loading hibernate configuration from application properties");
HibernateContext.cacheHibernateProperties(applicationContext.getEnvironment());
HibernateContext.extractAndSetHibernateConfig(applicationContext.getEnvironment());
}

}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package ch.puzzle.okr.multitenancy.listener;
package ch.puzzle.okr.multitenancy;

import org.springframework.core.env.ConfigurableEnvironment;

Expand All @@ -15,19 +15,55 @@ public class HibernateContext {
public static String SPRING_DATASOURCE_PASSWORD = "spring.datasource.password";

public record DbConfig(String url, String username, String password, String multiTenancy) {

public boolean isValid() {
return !hasNullValues() && !hasEmptyValues();
}

private boolean hasNullValues() {
return url() == null || username() == null || password() == null || multiTenancy() == null;
}

private boolean hasEmptyValues() {
return url().isBlank() || username().isBlank() || password().isBlank() || multiTenancy().isBlank();
}
}

private static DbConfig cachedHibernateConfig;

public static void setHibernateConfig(DbConfig dbConfig) {
if (dbConfig == null || !dbConfig.isValid()) {
throw new RuntimeException("Invalid hibernate configuration " + dbConfig);
}
cachedHibernateConfig = dbConfig;
}

public static void extractAndSetHibernateConfig(ConfigurableEnvironment environment) {
DbConfig dbConfig = extractHibernateConfig(environment);
HibernateContext.setHibernateConfig(dbConfig);
}

private static DbConfig extractHibernateConfig(ConfigurableEnvironment environment) {
String url = environment.getProperty(HibernateContext.HIBERNATE_CONNECTION_URL);
String username = environment.getProperty(HibernateContext.HIBERNATE_CONNECTION_USERNAME);
String password = environment.getProperty(HibernateContext.HIBERNATE_CONNECTION_PASSWORD);
String multiTenancy = environment.getProperty(HibernateContext.HIBERNATE_MULTITENANCY);
return new DbConfig(url, username, password, multiTenancy);
}

// for testing
public static void resetHibernateConfig() {
cachedHibernateConfig = null;
}

public static Properties getHibernateConfig() {
if (cachedHibernateConfig == null) {
throw new RuntimeException("No cached hibernate configuration found");
}
return getConfigAsProperties(cachedHibernateConfig);
}

public static Properties getConfigAsProperties(DbConfig dbConfig) {
private static Properties getConfigAsProperties(DbConfig dbConfig) {
Properties properties = new Properties();
properties.put(HibernateContext.HIBERNATE_CONNECTION_URL, dbConfig.url());
properties.put(HibernateContext.HIBERNATE_CONNECTION_USERNAME, dbConfig.username());
Expand All @@ -38,15 +74,4 @@ public static Properties getConfigAsProperties(DbConfig dbConfig) {
properties.put(HibernateContext.SPRING_DATASOURCE_PASSWORD, dbConfig.password());
return properties;
}

public static void cacheHibernateProperties(ConfigurableEnvironment environment) {
String url = environment.getProperty(HibernateContext.HIBERNATE_CONNECTION_URL);
String username = environment.getProperty(HibernateContext.HIBERNATE_CONNECTION_USERNAME);
String password = environment.getProperty(HibernateContext.HIBERNATE_CONNECTION_PASSWORD);
String multiTenancy = environment.getProperty(HibernateContext.HIBERNATE_MULTITENANCY);

HibernateContext.DbConfig h2DbConfig = new HibernateContext.DbConfig(url, username, password, multiTenancy);
HibernateContext.setHibernateConfig(h2DbConfig);
}

}
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package ch.puzzle.okr.multitenancy;

import ch.puzzle.okr.exception.ConnectionProviderException;
import ch.puzzle.okr.multitenancy.listener.HibernateContext;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl;
import org.hibernate.engine.jdbc.connections.spi.AbstractMultiTenantConnectionProvider;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
package ch.puzzle.okr.multitenancy;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import org.springframework.core.env.ConfigurableEnvironment;

import java.util.Properties;
import java.util.stream.Stream;

import static ch.puzzle.okr.multitenancy.HibernateContext.*;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

public class HibernateContextTest {

@BeforeEach
void setUp() {
resetHibernateConfig();
}

@DisplayName("setHibernateConfig() should throw exception if db config is null")
@Test
void setHibernateConfigShouldThrowExceptionIfDbConfigIsNull() {
// arrange
DbConfig dbConfig = null;

// act + assert
RuntimeException exception = assertThrows(RuntimeException.class, () -> setHibernateConfig(dbConfig));
assertEquals("Invalid hibernate configuration null", exception.getMessage());
}

@DisplayName("setHibernateConfig() should throw exception if db config has null or empty values")
@ParameterizedTest
@MethodSource("invalidDbConfig")
void setHibernateConfigShouldThrowExceptionIfDbConfigHasNullOrEmptyValues(String url, String username,
String password, String tenant) {

// arrange
DbConfig dbConfig = new DbConfig(url, username, password, tenant);

// act + assert
RuntimeException exception = assertThrows(RuntimeException.class, () -> setHibernateConfig(dbConfig));
assertTrue(exception.getMessage().startsWith("Invalid hibernate configuration"));
}

private static Stream<Arguments> invalidDbConfig() {
return Stream.of( //
Arguments.of(null, "username", "password", "multiTenancy"), //
Arguments.of("", "username", "password", "multiTenancy"), //
Arguments.of("url", null, "password", "multiTenancy"), //
Arguments.of("url", "", "password", "multiTenancy"), //
Arguments.of("url", "username", null, "multiTenancy"), //
Arguments.of("url", "username", "", "multiTenancy"), //
Arguments.of("url", "username", "password", null), //
Arguments.of("url", "username", "password", ""));
}

@DisplayName("extractAndSetHibernateConfig() should extract hibernate properties from environment and set it")
@Test
void extractAndSetHibernateConfigShouldExtractHibernatePropertiesFromEnvironmentAndSetIt() {
// arrange
String url = "url", username = "username", password = "password", multiTenancy = "multiTenancy";

ConfigurableEnvironment environment = mock(ConfigurableEnvironment.class);
when(environment.getProperty(HIBERNATE_CONNECTION_URL)).thenReturn(url);
when(environment.getProperty(HIBERNATE_CONNECTION_USERNAME)).thenReturn(username);
when(environment.getProperty(HIBERNATE_CONNECTION_PASSWORD)).thenReturn(password);
when(environment.getProperty(HIBERNATE_MULTITENANCY)).thenReturn(multiTenancy);

// act
extractAndSetHibernateConfig(environment);
Properties hibernateProperties = getHibernateConfig();

// assert
assertNotNull(hibernateProperties);
assertProperties(url, username, password, multiTenancy, hibernateProperties);
}

@DisplayName("getHibernateConfig() should throw exception if setHibernateConfig() is not called before with valid configuration")
@Test
void getHibernateConfigShouldThrowExceptionIfSetHibernateConfigIsNotCalledBeforeWithValidConfiguration() {
// arrange

// act + assert
RuntimeException exception = assertThrows(RuntimeException.class, HibernateContext::getHibernateConfig);
assertEquals("No cached hibernate configuration found", exception.getMessage());
}

@DisplayName("getHibernateConfig() should return hibernate config as properties if db config is valid")
@Test
void getHibernateConfigShouldReturnHibernateConfigAsPropertiesIfDbConfigIsValid() {
// arrange
String url = "url", username = "username", password = "password", multiTenancy = "multiTenancy";
DbConfig dbConfig = new DbConfig(url, username, password, multiTenancy);
setHibernateConfig(dbConfig);

// act
Properties hibernateProperties = getHibernateConfig();

// assert
assertNotNull(hibernateProperties);
assertProperties(url, username, password, multiTenancy, hibernateProperties);
}

private void assertProperties(String url, String username, String password, String multiTenancy,
Properties properties) {

assertEquals(url, properties.get(HIBERNATE_CONNECTION_URL));
assertEquals(username, properties.get(HIBERNATE_CONNECTION_USERNAME));
assertEquals(password, properties.get(HIBERNATE_CONNECTION_PASSWORD));
assertEquals(multiTenancy, properties.get(HIBERNATE_MULTITENANCY));
assertEquals(url, properties.get(SPRING_DATASOURCE_URL));
assertEquals(username, properties.get(SPRING_DATASOURCE_USERNAME));
assertEquals(password, properties.get(SPRING_DATASOURCE_PASSWORD));
}

}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package ch.puzzle.okr.test;

import ch.puzzle.okr.multitenancy.listener.HibernateContext;
import ch.puzzle.okr.multitenancy.HibernateContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContextInitializer;
Expand All @@ -13,6 +13,6 @@ public class TestContextInitializer implements ApplicationContextInitializer<Con
@Override
public void initialize(ConfigurableApplicationContext applicationContext) {
logger.info("Loading hibernate configuration from application properties");
HibernateContext.cacheHibernateProperties(applicationContext.getEnvironment());
HibernateContext.extractAndSetHibernateConfig(applicationContext.getEnvironment());
}
}
Loading