diff --git a/spring-modulith-events/spring-modulith-events-jdbc/src/main/java/org/springframework/modulith/events/jdbc/DatabaseSchemaInitializer.java b/spring-modulith-events/spring-modulith-events-jdbc/src/main/java/org/springframework/modulith/events/jdbc/DatabaseSchemaInitializer.java index 41e41d24..a8d2aa1a 100644 --- a/spring-modulith-events/spring-modulith-events-jdbc/src/main/java/org/springframework/modulith/events/jdbc/DatabaseSchemaInitializer.java +++ b/spring-modulith-events/spring-modulith-events-jdbc/src/main/java/org/springframework/modulith/events/jdbc/DatabaseSchemaInitializer.java @@ -15,15 +15,7 @@ */ package org.springframework.modulith.events.jdbc; -import java.io.IOException; -import java.io.UncheckedIOException; -import java.nio.charset.StandardCharsets; - import org.springframework.beans.factory.InitializingBean; -import org.springframework.core.io.Resource; -import org.springframework.core.io.ResourceLoader; -import org.springframework.jdbc.core.JdbcOperations; -import org.springframework.util.StreamUtils; /** * Initializes the DB schema used to store events @@ -32,48 +24,4 @@ import org.springframework.util.StreamUtils; * @author Björn Kieling * @author Oliver Drotbohm */ -class DatabaseSchemaInitializer implements InitializingBean { - - private final JdbcOperations jdbcOperations; - private final ResourceLoader resourceLoader; - private final DatabaseType databaseType; - - /** - * Creates a new {@link DatabaseSchemaInitializer} for the given {@link JdbcOperations}, {@link ResourceLoader} and - * {@link DatabaseType}. - * - * @param jdbcOperations must not be {@literal null}. - * @param resourceLoader must not be {@literal null}. - * @param databaseType must not be {@literal null}. - */ - public DatabaseSchemaInitializer(JdbcOperations jdbcOperations, ResourceLoader resourceLoader, - DatabaseType databaseType) { - - this.jdbcOperations = jdbcOperations; - this.resourceLoader = resourceLoader; - this.databaseType = databaseType; - } - - /* - * (non-Javadoc) - * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet() - */ - @Override - public void afterPropertiesSet() { - - var schemaResourceFilename = databaseType.getSchemaResourceFilename(); - var schemaDdlResource = resourceLoader.getResource(ResourceLoader.CLASSPATH_URL_PREFIX + schemaResourceFilename); - var schemaDdl = asString(schemaDdlResource); - - jdbcOperations.execute(schemaDdl); - } - - private static String asString(Resource resource) { - - try { - return StreamUtils.copyToString(resource.getInputStream(), StandardCharsets.UTF_8); - } catch (IOException e) { - throw new UncheckedIOException(e); - } - } -} +interface DatabaseSchemaInitializer extends InitializingBean {} diff --git a/spring-modulith-events/spring-modulith-events-jdbc/src/main/java/org/springframework/modulith/events/jdbc/DatabaseSchemaLocator.java b/spring-modulith-events/spring-modulith-events-jdbc/src/main/java/org/springframework/modulith/events/jdbc/DatabaseSchemaLocator.java new file mode 100644 index 00000000..1750c420 --- /dev/null +++ b/spring-modulith-events/spring-modulith-events-jdbc/src/main/java/org/springframework/modulith/events/jdbc/DatabaseSchemaLocator.java @@ -0,0 +1,56 @@ +/* + * Copyright 2024 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.modulith.events.jdbc; + +import org.springframework.core.io.Resource; +import org.springframework.core.io.ResourceLoader; +import org.springframework.util.Assert; + +/** + * Simple wrapper around a {@link ResourceLoader} to load database specific schema files from the classpath. + * + * @author Oliver Drotbohm + */ +public class DatabaseSchemaLocator { + + private final ResourceLoader resourceLoader; + + /** + * Creates a new {@link DatabaseSchemaLocator} for the given {@link ResourceLoader}. + * + * @param resourceLoader must not be {@literal null}. + */ + DatabaseSchemaLocator(ResourceLoader resourceLoader) { + + Assert.notNull(resourceLoader, "ResourceLoader must not be null!"); + + this.resourceLoader = resourceLoader; + } + + /** + * Loads the {@link Resource} copntaining the schema for the given {@link DatabaseType} from the classpath. + * + * @param databaseType must not be {@literal null}. + * @return will never be {@literal null}. + */ + Resource getSchemaResource(DatabaseType databaseType) { + + Assert.notNull(databaseType, "DatabaseType must not be null!"); + + var schemaResourceFilename = databaseType.getSchemaResourceFilename(); + return resourceLoader.getResource(ResourceLoader.CLASSPATH_URL_PREFIX + schemaResourceFilename); + } +} diff --git a/spring-modulith-events/spring-modulith-events-jdbc/src/main/java/org/springframework/modulith/events/jdbc/JdbcEventPublicationAutoConfiguration.java b/spring-modulith-events/spring-modulith-events-jdbc/src/main/java/org/springframework/modulith/events/jdbc/JdbcEventPublicationAutoConfiguration.java index 4faa90fb..413d13b7 100644 --- a/spring-modulith-events/spring-modulith-events-jdbc/src/main/java/org/springframework/modulith/events/jdbc/JdbcEventPublicationAutoConfiguration.java +++ b/spring-modulith-events/spring-modulith-events-jdbc/src/main/java/org/springframework/modulith/events/jdbc/JdbcEventPublicationAutoConfiguration.java @@ -25,6 +25,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.ResourceLoader; import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator; import org.springframework.jdbc.support.JdbcUtils; import org.springframework.modulith.events.config.EventPublicationAutoConfiguration; import org.springframework.modulith.events.config.EventPublicationConfigurationExtension; @@ -53,10 +54,15 @@ class JdbcEventPublicationAutoConfiguration implements EventPublicationConfigura @Bean @ConditionalOnProperty(name = "spring.modulith.events.jdbc.schema-initialization.enabled", havingValue = "true") - DatabaseSchemaInitializer databaseSchemaInitializer(JdbcTemplate jdbcTemplate, ResourceLoader resourceLoader, + DatabaseSchemaInitializer databaseSchemaInitializer(DataSource dataSource, ResourceLoader resourceLoader, DatabaseType databaseType) { - return new DatabaseSchemaInitializer(jdbcTemplate, resourceLoader, databaseType); + return () -> { + + var locator = new DatabaseSchemaLocator(resourceLoader); + + new ResourceDatabasePopulator(locator.getSchemaResource(databaseType)).execute(dataSource); + }; } private static String fromDataSource(DataSource dataSource) { diff --git a/spring-modulith-events/spring-modulith-events-jdbc/src/test/java/org/springframework/modulith/events/jdbc/DatabaseSchemaInitializerUnitTests.java b/spring-modulith-events/spring-modulith-events-jdbc/src/test/java/org/springframework/modulith/events/jdbc/DatabaseSchemaLocatorUnitTests.java similarity index 84% rename from spring-modulith-events/spring-modulith-events-jdbc/src/test/java/org/springframework/modulith/events/jdbc/DatabaseSchemaInitializerUnitTests.java rename to spring-modulith-events/spring-modulith-events-jdbc/src/test/java/org/springframework/modulith/events/jdbc/DatabaseSchemaLocatorUnitTests.java index 79c5a68c..f20931e8 100644 --- a/spring-modulith-events/spring-modulith-events-jdbc/src/test/java/org/springframework/modulith/events/jdbc/DatabaseSchemaInitializerUnitTests.java +++ b/spring-modulith-events/spring-modulith-events-jdbc/src/test/java/org/springframework/modulith/events/jdbc/DatabaseSchemaLocatorUnitTests.java @@ -26,7 +26,6 @@ import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.ResourceLoader; -import org.springframework.jdbc.core.JdbcOperations; /** * Unit tests for {@link DatabaseSchemaInitializer}. @@ -34,9 +33,8 @@ import org.springframework.jdbc.core.JdbcOperations; * @author Oliver Drotbohm */ @ExtendWith(MockitoExtension.class) -class DatabaseSchemaInitializerUnitTests { +public class DatabaseSchemaLocatorUnitTests { - @Mock JdbcOperations jdbcOperations; @Mock ResourceLoader resourceLoader; @Test // GH-159 @@ -46,10 +44,10 @@ class DatabaseSchemaInitializerUnitTests { return new ClassPathResource(it. getArgument(0).substring(ResourceLoader.CLASSPATH_URL_PREFIX.length())); }); - var initializer = new DatabaseSchemaInitializer(jdbcOperations, resourceLoader, DatabaseType.H2); + var locator = new DatabaseSchemaLocator(resourceLoader); var captor = ArgumentCaptor.forClass(String.class); - assertThatNoException().isThrownBy(initializer::afterPropertiesSet); + assertThatNoException().isThrownBy(() -> locator.getSchemaResource(DatabaseType.H2)); verify(resourceLoader).getResource(captor.capture()); assertThat(captor.getValue()).startsWith(ResourceLoader.CLASSPATH_URL_PREFIX); }