diff --git a/backend/src/main/java/ch/puzzle/okr/OkrApplication.java b/backend/src/main/java/ch/puzzle/okr/OkrApplication.java index 1fb2075df2..b41f6986a5 100644 --- a/backend/src/main/java/ch/puzzle/okr/OkrApplication.java +++ b/backend/src/main/java/ch/puzzle/okr/OkrApplication.java @@ -1,16 +1,19 @@ package ch.puzzle.okr; import ch.puzzle.okr.service.clientconfig.ClientCustomizationProperties; -import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.scheduling.annotation.EnableScheduling; +import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.scheduling.annotation.EnableScheduling; @SpringBootApplication @EnableScheduling @EnableConfigurationProperties(ClientCustomizationProperties.class) public class OkrApplication { public static void main(String[] args) { - SpringApplication.run(OkrApplication.class, args); + + new SpringApplicationBuilder(OkrApplication.class) // + .initializers(new OkrApplicationContextInitializer()) // + .run(args); } } diff --git a/backend/src/main/java/ch/puzzle/okr/OkrApplicationContextInitializer.java b/backend/src/main/java/ch/puzzle/okr/OkrApplicationContextInitializer.java new file mode 100644 index 0000000000..17f5ff1c37 --- /dev/null +++ b/backend/src/main/java/ch/puzzle/okr/OkrApplicationContextInitializer.java @@ -0,0 +1,21 @@ +package ch.puzzle.okr; + +import ch.puzzle.okr.multitenancy.listener.HibernateContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.ApplicationContextInitializer; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class OkrApplicationContextInitializer implements ApplicationContextInitializer { + + private static final Logger logger = LoggerFactory.getLogger(OkrApplicationContextInitializer.class); + + @Override + public void initialize(ConfigurableApplicationContext applicationContext) { + logger.info("Loading hibernate configuration from application properties"); + HibernateContext.cacheHibernateProperties(applicationContext.getEnvironment()); + } + +} \ No newline at end of file diff --git a/backend/src/main/java/ch/puzzle/okr/multitenancy/AbstractSchemaMultiTenantConnectionProvider.java b/backend/src/main/java/ch/puzzle/okr/multitenancy/SchemaMultiTenantConnectionProvider.java similarity index 79% rename from backend/src/main/java/ch/puzzle/okr/multitenancy/AbstractSchemaMultiTenantConnectionProvider.java rename to backend/src/main/java/ch/puzzle/okr/multitenancy/SchemaMultiTenantConnectionProvider.java index 9a6a6a71ee..cfc6da1e6e 100644 --- a/backend/src/main/java/ch/puzzle/okr/multitenancy/AbstractSchemaMultiTenantConnectionProvider.java +++ b/backend/src/main/java/ch/puzzle/okr/multitenancy/SchemaMultiTenantConnectionProvider.java @@ -1,6 +1,7 @@ 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; @@ -8,7 +9,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.io.IOException; import java.sql.Connection; import java.sql.SQLException; import java.text.MessageFormat; @@ -16,13 +16,13 @@ import static ch.puzzle.okr.multitenancy.TenantContext.DEFAULT_TENANT_ID; -public abstract class AbstractSchemaMultiTenantConnectionProvider - extends AbstractMultiTenantConnectionProvider { - private static final Logger logger = LoggerFactory.getLogger(AbstractSchemaMultiTenantConnectionProvider.class); +public class SchemaMultiTenantConnectionProvider extends AbstractMultiTenantConnectionProvider { + + private static final Logger logger = LoggerFactory.getLogger(SchemaMultiTenantConnectionProvider.class); final Map connectionProviderMap; - public AbstractSchemaMultiTenantConnectionProvider() { + public SchemaMultiTenantConnectionProvider() { this.connectionProviderMap = new HashMap<>(); } @@ -80,21 +80,13 @@ private ConnectionProvider createConnectionProvider(String tenantIdentifier) { } protected Properties getHibernatePropertiesForTenantIdentifier(String tenantIdentifier) { - try { - Properties properties = getPropertiesFromFilePaths(); - if (!Objects.equals(tenantIdentifier, DEFAULT_TENANT_ID)) { - properties.put(AvailableSettings.DEFAULT_SCHEMA, MessageFormat.format("okr_{0}", tenantIdentifier)); - } - return properties; - } catch (IOException e) { - throw new RuntimeException( - String.format("Cannot open hibernate properties: %s)", this.getHibernatePropertiesFilePaths())); + Properties properties = getHibernateProperties(); + if (properties == null || properties.isEmpty()) { + throw new RuntimeException("Cannot load hibernate properties from application.properties)"); + } + if (!Objects.equals(tenantIdentifier, DEFAULT_TENANT_ID)) { + properties.put(AvailableSettings.DEFAULT_SCHEMA, MessageFormat.format("okr_{0}", tenantIdentifier)); } - } - - protected Properties getPropertiesFromFilePaths() throws IOException { - Properties properties = new Properties(); - properties.load(getClass().getResourceAsStream(this.getHibernatePropertiesFilePaths())); return properties; } @@ -118,5 +110,7 @@ private Map convertPropertiesToMap(Properties properties) { return configProperties; } - protected abstract String getHibernatePropertiesFilePaths(); + protected Properties getHibernateProperties() { + return HibernateContext.getHibernateConfig(); + } } \ No newline at end of file diff --git a/backend/src/main/java/ch/puzzle/okr/multitenancy/SchemaMultiTenantConnectionProviderH2.java b/backend/src/main/java/ch/puzzle/okr/multitenancy/SchemaMultiTenantConnectionProviderH2.java deleted file mode 100644 index e5052d7310..0000000000 --- a/backend/src/main/java/ch/puzzle/okr/multitenancy/SchemaMultiTenantConnectionProviderH2.java +++ /dev/null @@ -1,7 +0,0 @@ -package ch.puzzle.okr.multitenancy; - -public class SchemaMultiTenantConnectionProviderH2 extends AbstractSchemaMultiTenantConnectionProvider { - protected String getHibernatePropertiesFilePaths() { - return "/hibernate-multitenancy-h2.properties"; - } -} \ No newline at end of file diff --git a/backend/src/main/java/ch/puzzle/okr/multitenancy/SchemaMultiTenantConnectionProviderPGSQL.java b/backend/src/main/java/ch/puzzle/okr/multitenancy/SchemaMultiTenantConnectionProviderPGSQL.java deleted file mode 100644 index 267195cb1d..0000000000 --- a/backend/src/main/java/ch/puzzle/okr/multitenancy/SchemaMultiTenantConnectionProviderPGSQL.java +++ /dev/null @@ -1,9 +0,0 @@ -package ch.puzzle.okr.multitenancy; - -import org.hibernate.engine.jdbc.connections.spi.AbstractMultiTenantConnectionProvider; - -public class SchemaMultiTenantConnectionProviderPGSQL extends AbstractSchemaMultiTenantConnectionProvider { - protected String getHibernatePropertiesFilePaths() { - return "/hibernate-multitenancy-pgsql.properties"; - } -} \ No newline at end of file diff --git a/backend/src/main/java/ch/puzzle/okr/multitenancy/listener/HibernateContext.java b/backend/src/main/java/ch/puzzle/okr/multitenancy/listener/HibernateContext.java new file mode 100644 index 0000000000..4778057b9b --- /dev/null +++ b/backend/src/main/java/ch/puzzle/okr/multitenancy/listener/HibernateContext.java @@ -0,0 +1,52 @@ +package ch.puzzle.okr.multitenancy.listener; + +import org.springframework.core.env.ConfigurableEnvironment; + +import java.util.Properties; + +public class HibernateContext { + public static final String HIBERNATE_CONNECTION_URL = "hibernate.connection.url"; + public static final String HIBERNATE_CONNECTION_USERNAME = "hibernate.connection.username"; + public static final String HIBERNATE_CONNECTION_PASSWORD = "hibernate.connection.password"; + public static final String HIBERNATE_MULTITENANCY = "hibernate.multiTenancy"; + + public static String SPRING_DATASOURCE_URL = "spring.datasource.url"; + public static String SPRING_DATASOURCE_USERNAME = "spring.datasource.username"; + public static String SPRING_DATASOURCE_PASSWORD = "spring.datasource.password"; + + public record DbConfig(String url, String username, String password, String multiTenancy) { + } + + private static DbConfig cachedHibernateConfig; + + public static void setHibernateConfig(DbConfig dbConfig) { + cachedHibernateConfig = dbConfig; + } + + public static Properties getHibernateConfig() { + return getConfigAsProperties(cachedHibernateConfig); + } + + public 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()); + properties.put(HibernateContext.HIBERNATE_CONNECTION_PASSWORD, dbConfig.password()); + properties.put(HibernateContext.HIBERNATE_MULTITENANCY, dbConfig.multiTenancy()); + properties.put(HibernateContext.SPRING_DATASOURCE_URL, dbConfig.url()); + properties.put(HibernateContext.SPRING_DATASOURCE_USERNAME, dbConfig.username()); + 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); + } + +} diff --git a/backend/src/main/resources/application-dev.properties b/backend/src/main/resources/application-dev.properties index ac810b7d09..7aa5da0118 100644 --- a/backend/src/main/resources/application-dev.properties +++ b/backend/src/main/resources/application-dev.properties @@ -13,6 +13,12 @@ spring.flyway.locations=classpath:db/migration,classpath:db/data-migration,class okr.tenant-ids=pitc,acme okr.datasource.driver-class-name=org.postgresql.Driver +# hibernate +hibernate.connection.url=jdbc:postgresql://localhost:5432/okr +hibernate.connection.username=user +hibernate.connection.password=pwd +hibernate.multiTenancy=SCHEMA + # pitc okr.tenants.pitc.datasource.url=jdbc:postgresql://localhost:5432/okr okr.tenants.pitc.datasource.username=pitc diff --git a/backend/src/main/resources/application-integration-test.properties b/backend/src/main/resources/application-integration-test.properties index 9a727277c7..c19428abf1 100644 --- a/backend/src/main/resources/application-integration-test.properties +++ b/backend/src/main/resources/application-integration-test.properties @@ -16,6 +16,12 @@ spring.flyway.locations=classpath:db/h2-db/database-h2-schema,classpath:db/h2-db okr.tenant-ids=pitc,acme okr.datasource.driver-class-name=org.h2.Driver +# hibernate +hibernate.connection.url=jdbc:h2:mem:db;DB_CLOSE_DELAY=-1; +hibernate.connection.username=user +hibernate.connection.password=sa +hibernate.multiTenancy=SCHEMA + # pitc okr.tenants.pitc.datasource.url=jdbc:h2:mem:db;DB_CLOSE_DELAY=-1;INIT=CREATE SCHEMA IF NOT EXISTS okr_pitc okr.tenants.pitc.datasource.username=user @@ -35,5 +41,3 @@ okr.tenants.acme.user.champion.emails=peggimann@puzzle.ch,wunderland@puzzle.ch okr.tenants.acme.security.oauth2.resourceserver.jwt.jwk-set-uri=http://localhost:8544/realms/pitc/protocol/openid-connect/certs okr.tenants.acme.security.oauth2.frontend.issuer-url=http://localhost:8544/realms/pitc okr.tenants.acme.security.oauth2.frontend.client-id=acme_okr_staging - -spring.jpa.properties.hibernate.multi_tenant_connection_provider=ch.puzzle.okr.multitenancy.SchemaMultiTenantConnectionProviderH2 diff --git a/backend/src/main/resources/application.properties b/backend/src/main/resources/application.properties index 1ed0f9df7a..997f4fde7f 100644 --- a/backend/src/main/resources/application.properties +++ b/backend/src/main/resources/application.properties @@ -46,7 +46,7 @@ okr.jwt.claim.email=email spring.jpa.properties.hibernate.multiTenancy=SCHEMA spring.jpa.properties.hibernate.tenant_identifier_resolver=ch.puzzle.okr.multitenancy.CurrentTenantIdentifierResolverImpl -spring.jpa.properties.hibernate.multi_tenant_connection_provider=ch.puzzle.okr.multitenancy.SchemaMultiTenantConnectionProviderPGSQL +spring.jpa.properties.hibernate.multi_tenant_connection_provider=ch.puzzle.okr.multitenancy.SchemaMultiTenantConnectionProvider okr.clientcustomization.favicon=assets/favicon.png okr.clientcustomization.logo=assets/images/okr-logo.svg diff --git a/backend/src/main/resources/hibernate-multitenancy-h2.properties b/backend/src/main/resources/hibernate-multitenancy-h2.properties deleted file mode 100644 index 0ed4906c2c..0000000000 --- a/backend/src/main/resources/hibernate-multitenancy-h2.properties +++ /dev/null @@ -1,7 +0,0 @@ -hibernate.connection.url=jdbc:h2:mem:db;DB_CLOSE_DELAY=-1; -hibernate.connection.username=user -hibernate.connection.password=sa -hibernate.multiTenancy=SCHEMA -spring.datasource.url=${hibernate.connection.url} -spring.datasource.username=${hibernate.connection.username} -spring.datasource.password=${hibernate.connection.password} diff --git a/backend/src/main/resources/hibernate-multitenancy-pgsql.properties b/backend/src/main/resources/hibernate-multitenancy-pgsql.properties deleted file mode 100644 index 52ed8d59aa..0000000000 --- a/backend/src/main/resources/hibernate-multitenancy-pgsql.properties +++ /dev/null @@ -1,7 +0,0 @@ -hibernate.connection.url=jdbc:postgresql://localhost:5432/okr -hibernate.connection.username=user -hibernate.connection.password=pwd -hibernate.multiTenancy=SCHEMA -spring.datasource.url=${hibernate.connection.url} -spring.datasource.username=${hibernate.connection.username} -spring.datasource.password=${hibernate.connection.password} diff --git a/backend/src/test/java/ch/puzzle/okr/multitenancy/SchemaMultiTenantConnectionProviderH2Test.java b/backend/src/test/java/ch/puzzle/okr/multitenancy/SchemaMultiTenantConnectionProviderH2Test.java deleted file mode 100644 index 8e733d5ae6..0000000000 --- a/backend/src/test/java/ch/puzzle/okr/multitenancy/SchemaMultiTenantConnectionProviderH2Test.java +++ /dev/null @@ -1,15 +0,0 @@ -package ch.puzzle.okr.multitenancy; - -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -class SchemaMultiTenantConnectionProviderH2Test { - - @Test - void returnsPathToH2Properties() { - SchemaMultiTenantConnectionProviderH2 connectionProvider = new SchemaMultiTenantConnectionProviderH2(); - String filePath = connectionProvider.getHibernatePropertiesFilePaths(); - assertEquals("/hibernate-multitenancy-h2.properties", filePath); - } -} \ No newline at end of file diff --git a/backend/src/test/java/ch/puzzle/okr/multitenancy/SchemaMultiTenantConnectionProviderInternalsTest.java b/backend/src/test/java/ch/puzzle/okr/multitenancy/SchemaMultiTenantConnectionProviderInternalsTest.java index f5fddf06bc..e8bc0dc7b0 100644 --- a/backend/src/test/java/ch/puzzle/okr/multitenancy/SchemaMultiTenantConnectionProviderInternalsTest.java +++ b/backend/src/test/java/ch/puzzle/okr/multitenancy/SchemaMultiTenantConnectionProviderInternalsTest.java @@ -1,13 +1,11 @@ package ch.puzzle.okr.multitenancy; import ch.puzzle.okr.exception.ConnectionProviderException; -import org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl; import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; -import java.io.IOException; import java.util.Properties; import static org.mockito.Mockito.mock; @@ -16,25 +14,11 @@ public class SchemaMultiTenantConnectionProviderInternalsTest { private static final String TENANT_ID = "pitc"; - private static class BasicConnectionProviderMock extends AbstractSchemaMultiTenantConnectionProvider { - @Override - protected String getHibernatePropertiesFilePaths() { - return null; - } + private static class ConfigurableConnectionProviderMock extends SchemaMultiTenantConnectionProvider { @Override - protected DriverManagerConnectionProviderImpl getDriverManagerConnectionProviderImpl() { - return mock(DriverManagerConnectionProviderImpl.class); - } - } - - private static class ConfigurableConnectionProviderMock extends BasicConnectionProviderMock { - - @Override - protected Properties getPropertiesFromFilePaths() { - Properties properties = new Properties(); - properties.put("hibernate.connection.url", "no_value"); - return properties; + protected Properties getHibernateProperties() { + return new Properties(); } public void registerProvider(String tenantIdentifier, ConnectionProvider connectionProvider) { @@ -56,19 +40,6 @@ void getConnectionProviderReturnConnectionProviderIfTenantIdIsRegistered() { Assertions.assertNotNull(foundConnectionProvider); } - @DisplayName("getConnectionProvider() creates ConnectionProvider if TenantId is not registered") - @Test - void getConnectionProviderCreatesConnectionProviderIfTenantIdIsNotRegistered() { - // arrange - ConfigurableConnectionProviderMock mockProvider = new ConfigurableConnectionProviderMock(); - - // act - ConnectionProvider notFoundConnectionProvider = mockProvider.getConnectionProvider(TENANT_ID); - - // assert - Assertions.assertNotNull(notFoundConnectionProvider); - } - @DisplayName("getConnectionProvider() throws Exception when lookup TenantId is null") @Test void getConnectionProviderThrowsExceptionWhenLookupTenantIdIsNull() { @@ -107,17 +78,11 @@ void getAnyConnectionProviderReturnConnectionProviderForTenantIdPublic() { Assertions.assertNotNull(foundConnectionProvider); } - @DisplayName("throws a RuntimeException when getPropertiesFromFilePaths() throws an IOException") + @DisplayName("getConnectionProviderShouldThrowRuntimeExceptionWhenNoPropertiesAreFound") @Test - void throwsRuntimeExceptionWhenGetPropertiesFromFilePathsThrowsIOException() { - BasicConnectionProviderMock mockProviderWhichThrowsIOException = new BasicConnectionProviderMock() { - @Override - protected Properties getPropertiesFromFilePaths() throws IOException { - throw new IOException("no properties found"); - } - }; - - Assertions.assertThrows(RuntimeException.class, - () -> mockProviderWhichThrowsIOException.getConnectionProvider(TENANT_ID)); + void getConnectionProviderShouldThrowRuntimeExceptionWhenNoPropertiesAreFound() { + ConfigurableConnectionProviderMock mockProvider = new ConfigurableConnectionProviderMock(); + + Assertions.assertThrows(RuntimeException.class, () -> mockProvider.getConnectionProvider(TENANT_ID)); } } diff --git a/backend/src/test/java/ch/puzzle/okr/multitenancy/SchemaMultiTenantConnectionProviderPGSQLTest.java b/backend/src/test/java/ch/puzzle/okr/multitenancy/SchemaMultiTenantConnectionProviderPGSQLTest.java deleted file mode 100644 index 5a6b302a72..0000000000 --- a/backend/src/test/java/ch/puzzle/okr/multitenancy/SchemaMultiTenantConnectionProviderPGSQLTest.java +++ /dev/null @@ -1,15 +0,0 @@ -package ch.puzzle.okr.multitenancy; - -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -class SchemaMultiTenantConnectionProviderPGSQLTest { - - @Test - void returnsPathToPostgresProperties() { - SchemaMultiTenantConnectionProviderPGSQL connectionProvider = new SchemaMultiTenantConnectionProviderPGSQL(); - String filePath = connectionProvider.getHibernatePropertiesFilePaths(); - assertEquals("/hibernate-multitenancy-pgsql.properties", filePath); - } -} \ No newline at end of file diff --git a/backend/src/test/java/ch/puzzle/okr/multitenancy/SchemaMultiTenantConnectionProviderTest.java b/backend/src/test/java/ch/puzzle/okr/multitenancy/SchemaMultiTenantConnectionProviderTest.java index 86c5033f5f..e9a97a6d14 100644 --- a/backend/src/test/java/ch/puzzle/okr/multitenancy/SchemaMultiTenantConnectionProviderTest.java +++ b/backend/src/test/java/ch/puzzle/okr/multitenancy/SchemaMultiTenantConnectionProviderTest.java @@ -1,6 +1,7 @@ package ch.puzzle.okr.multitenancy; import ch.puzzle.okr.test.SpringIntegrationTest; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.mockito.Mock; @@ -20,19 +21,32 @@ public class SchemaMultiTenantConnectionProviderTest { private static final String TENANT_ID = "pitc"; + @DisplayName("getConnection() should set schema with okr prefix") @Test - void testSetSchemaOfTenant() throws SQLException { + void getConnectionShouldSetSchemaWithOkrPrefix() throws SQLException { + // arrange when(connection.createStatement()).thenReturn(statement); + SchemaMultiTenantConnectionProvider provider = new SchemaMultiTenantConnectionProvider(); - AbstractSchemaMultiTenantConnectionProvider provider = new AbstractSchemaMultiTenantConnectionProvider() { - @Override - protected String getHibernatePropertiesFilePaths() { - return null; - } - }; + // act provider.getConnection(TENANT_ID, connection); + // assert verify(statement).execute("SET SCHEMA 'okr_" + TENANT_ID + "';"); } + @DisplayName("getConnection() should set schema without okr prefix if tenant id is DEFAULT_TENANT_ID") + @Test + void getConnectionShouldSetSchemaWithoutOkrPrefixIfTenantIdIsDefaultTenantId() throws SQLException { + // arrange + when(connection.createStatement()).thenReturn(statement); + SchemaMultiTenantConnectionProvider provider = new SchemaMultiTenantConnectionProvider(); + + // act + provider.getConnection(TenantContext.DEFAULT_TENANT_ID, connection); + + // assert + verify(statement).execute("SET SCHEMA '" + TenantContext.DEFAULT_TENANT_ID + "';"); + } + } diff --git a/backend/src/test/java/ch/puzzle/okr/test/SpringIntegrationTest.java b/backend/src/test/java/ch/puzzle/okr/test/SpringIntegrationTest.java index c2d40543d7..2fe500d842 100644 --- a/backend/src/test/java/ch/puzzle/okr/test/SpringIntegrationTest.java +++ b/backend/src/test/java/ch/puzzle/okr/test/SpringIntegrationTest.java @@ -2,6 +2,7 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.ContextConfiguration; import java.lang.annotation.*; @@ -10,6 +11,7 @@ @Documented @Inherited @SpringBootTest +@ContextConfiguration(initializers = TestContextInitializer.class) @ActiveProfiles(value = "integration-test") public @interface SpringIntegrationTest { } diff --git a/backend/src/test/java/ch/puzzle/okr/test/TestContextInitializer.java b/backend/src/test/java/ch/puzzle/okr/test/TestContextInitializer.java new file mode 100644 index 0000000000..4c2d140b03 --- /dev/null +++ b/backend/src/test/java/ch/puzzle/okr/test/TestContextInitializer.java @@ -0,0 +1,18 @@ +package ch.puzzle.okr.test; + +import ch.puzzle.okr.multitenancy.listener.HibernateContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.ApplicationContextInitializer; +import org.springframework.context.ConfigurableApplicationContext; + +public class TestContextInitializer implements ApplicationContextInitializer { + + private static final Logger logger = LoggerFactory.getLogger(TestContextInitializer.class); + + @Override + public void initialize(ConfigurableApplicationContext applicationContext) { + logger.info("Loading hibernate configuration from application properties"); + HibernateContext.cacheHibernateProperties(applicationContext.getEnvironment()); + } +}