From cee93482c6aa2f1d5b9d8de4f88cfab3aae8872b Mon Sep 17 00:00:00 2001 From: Gabriel Roldan Date: Wed, 23 Oct 2024 22:15:43 -0300 Subject: [PATCH] Refactor the simple JNDI configuration to auto and plain config classes Workaround an issue where the JNDIInitializer would be called several times, making it wait for an unavailable JNDI data source multiple rounds instead of just one. I can't figure out why JNDIDataSourceAutoConfiguration would be instantiated several times when JNDIInitializer fails, so added a static flag to JNDIInitializer to avoid waiting for unavailable databases again and again. --- .../GeoServerBackendAutoConfiguration.java | 4 ++-- .../PgconfigDataSourceAutoConfiguration.java | 4 ++-- .../PconfigDataSourceConfiguration.java | 6 +++--- .../support/PgConfigTestContainer.java | 7 +++---- src/library/spring-boot-simplejndi/pom.xml | 5 +++++ .../jndi/JNDIDataSourceAutoConfiguration.java | 19 +++++++++++++++++++ .../SimpleJNDIStaticContextInitializer.java | 2 +- .../JNDIDataSourceConfiguration.java} | 8 ++++---- ...NDIDataSourcesConfigurationProperties.java | 2 +- .../JNDIDatasourceConfig.java | 2 +- .../JNDIInitializer.java | 15 ++++++++++++--- .../main/resources/META-INF/spring.factories | 4 ++-- .../JNDIDataSourceAutoConfigurationTest.java | 9 ++++----- ...impleJNDIStaticContextInitializerTest.java | 1 + 14 files changed, 60 insertions(+), 28 deletions(-) create mode 100644 src/library/spring-boot-simplejndi/src/main/java/org/geoserver/cloud/autoconfigure/jndi/JNDIDataSourceAutoConfiguration.java rename src/library/spring-boot-simplejndi/src/main/java/org/geoserver/cloud/{config => autoconfigure}/jndi/SimpleJNDIStaticContextInitializer.java (98%) rename src/library/spring-boot-simplejndi/src/main/java/org/geoserver/cloud/config/{jndidatasource/JNDIDataSourceAutoConfiguration.java => jndi/JNDIDataSourceConfiguration.java} (75%) rename src/library/spring-boot-simplejndi/src/main/java/org/geoserver/cloud/config/{jndidatasource => jndi}/JNDIDataSourcesConfigurationProperties.java (91%) rename src/library/spring-boot-simplejndi/src/main/java/org/geoserver/cloud/config/{jndidatasource => jndi}/JNDIDatasourceConfig.java (93%) rename src/library/spring-boot-simplejndi/src/main/java/org/geoserver/cloud/config/{jndidatasource => jndi}/JNDIInitializer.java (91%) rename src/library/spring-boot-simplejndi/src/test/java/org/geoserver/cloud/{config/jndidatasource => autoconfigure/jndi}/JNDIDataSourceAutoConfigurationTest.java (84%) diff --git a/src/catalog/backends/common/src/main/java/org/geoserver/cloud/autoconfigure/catalog/backend/core/GeoServerBackendAutoConfiguration.java b/src/catalog/backends/common/src/main/java/org/geoserver/cloud/autoconfigure/catalog/backend/core/GeoServerBackendAutoConfiguration.java index 364a51f0a..b18c97800 100644 --- a/src/catalog/backends/common/src/main/java/org/geoserver/cloud/autoconfigure/catalog/backend/core/GeoServerBackendAutoConfiguration.java +++ b/src/catalog/backends/common/src/main/java/org/geoserver/cloud/autoconfigure/catalog/backend/core/GeoServerBackendAutoConfiguration.java @@ -6,7 +6,7 @@ import org.geoserver.cloud.autoconfigure.geotools.GeoToolsHttpClientAutoConfiguration; import org.geoserver.cloud.config.catalog.backend.core.CoreBackendConfiguration; -import org.geoserver.cloud.config.jndidatasource.JNDIDataSourceAutoConfiguration; +import org.geoserver.cloud.config.jndi.JNDIDataSourceConfiguration; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.context.annotation.Import; @@ -23,6 +23,6 @@ * @see CoreBackendConfiguration */ @AutoConfiguration( - after = {GeoToolsHttpClientAutoConfiguration.class, JNDIDataSourceAutoConfiguration.class}) + after = {GeoToolsHttpClientAutoConfiguration.class, JNDIDataSourceConfiguration.class}) @Import(CoreBackendConfiguration.class) public class GeoServerBackendAutoConfiguration {} diff --git a/src/catalog/backends/pgconfig/src/main/java/org/geoserver/cloud/autoconfigure/catalog/backend/pgconfig/PgconfigDataSourceAutoConfiguration.java b/src/catalog/backends/pgconfig/src/main/java/org/geoserver/cloud/autoconfigure/catalog/backend/pgconfig/PgconfigDataSourceAutoConfiguration.java index ed923ce93..2770156a3 100644 --- a/src/catalog/backends/pgconfig/src/main/java/org/geoserver/cloud/autoconfigure/catalog/backend/pgconfig/PgconfigDataSourceAutoConfiguration.java +++ b/src/catalog/backends/pgconfig/src/main/java/org/geoserver/cloud/autoconfigure/catalog/backend/pgconfig/PgconfigDataSourceAutoConfiguration.java @@ -5,14 +5,14 @@ package org.geoserver.cloud.autoconfigure.catalog.backend.pgconfig; import org.geoserver.cloud.config.catalog.backend.pgconfig.PconfigDataSourceConfiguration; -import org.geoserver.cloud.config.jndidatasource.JNDIDataSourceAutoConfiguration; +import org.geoserver.cloud.config.jndi.JNDIDataSourceConfiguration; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.context.annotation.Import; /** * @since 1.4 */ -@AutoConfiguration(after = JNDIDataSourceAutoConfiguration.class) +@AutoConfiguration(after = JNDIDataSourceConfiguration.class) @ConditionalOnPgconfigBackendEnabled @Import(PconfigDataSourceConfiguration.class) public class PgconfigDataSourceAutoConfiguration {} diff --git a/src/catalog/backends/pgconfig/src/main/java/org/geoserver/cloud/config/catalog/backend/pgconfig/PconfigDataSourceConfiguration.java b/src/catalog/backends/pgconfig/src/main/java/org/geoserver/cloud/config/catalog/backend/pgconfig/PconfigDataSourceConfiguration.java index bdafb3b40..3ed44c404 100644 --- a/src/catalog/backends/pgconfig/src/main/java/org/geoserver/cloud/config/catalog/backend/pgconfig/PconfigDataSourceConfiguration.java +++ b/src/catalog/backends/pgconfig/src/main/java/org/geoserver/cloud/config/catalog/backend/pgconfig/PconfigDataSourceConfiguration.java @@ -46,9 +46,9 @@ DataSource pgconfigDataSource(PgconfigBackendProperties configprops) { Object jndiInitializerFallback() { log.warn( """ - jndiInitializer is not provided, beware a JNDI datasource \ - definition for the pgconfig catalog backend won't work. - """); + jndiInitializer is not provided, beware a JNDI datasource \ + definition for the pgconfig catalog backend won't work. + """); return new Object(); } } diff --git a/src/catalog/backends/pgconfig/src/test/java/org/geoserver/cloud/backend/pgconfig/support/PgConfigTestContainer.java b/src/catalog/backends/pgconfig/src/test/java/org/geoserver/cloud/backend/pgconfig/support/PgConfigTestContainer.java index 414965887..6f4027cb7 100644 --- a/src/catalog/backends/pgconfig/src/test/java/org/geoserver/cloud/backend/pgconfig/support/PgConfigTestContainer.java +++ b/src/catalog/backends/pgconfig/src/test/java/org/geoserver/cloud/backend/pgconfig/support/PgConfigTestContainer.java @@ -10,9 +10,9 @@ import lombok.Getter; import lombok.SneakyThrows; +import org.geoserver.cloud.autoconfigure.jndi.SimpleJNDIStaticContextInitializer; import org.geoserver.cloud.config.catalog.backend.pgconfig.PgconfigDatabaseMigrations; -import org.geoserver.cloud.config.jndi.SimpleJNDIStaticContextInitializer; -import org.geoserver.cloud.config.jndidatasource.JNDIDataSourceAutoConfiguration; +import org.geoserver.cloud.config.jndi.JNDIDataSourceConfiguration; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.test.context.runner.AbstractApplicationContextRunner; import org.springframework.jdbc.core.JdbcTemplate; @@ -94,8 +94,7 @@ public void tearDown() { runner // enable simplejndi .withInitializer(new SimpleJNDIStaticContextInitializer()) - .withConfiguration( - AutoConfigurations.of(JNDIDataSourceAutoConfiguration.class)) + .withConfiguration(AutoConfigurations.of(JNDIDataSourceConfiguration.class)) .withPropertyValues( "geoserver.backend.pgconfig.enabled: true", // // java:comp/env/jdbc/testdb config properties diff --git a/src/library/spring-boot-simplejndi/pom.xml b/src/library/spring-boot-simplejndi/pom.xml index 8151ae3cb..8eda16451 100644 --- a/src/library/spring-boot-simplejndi/pom.xml +++ b/src/library/spring-boot-simplejndi/pom.xml @@ -33,5 +33,10 @@ h2 test + + org.postgresql + postgresql + test + diff --git a/src/library/spring-boot-simplejndi/src/main/java/org/geoserver/cloud/autoconfigure/jndi/JNDIDataSourceAutoConfiguration.java b/src/library/spring-boot-simplejndi/src/main/java/org/geoserver/cloud/autoconfigure/jndi/JNDIDataSourceAutoConfiguration.java new file mode 100644 index 000000000..9703d0ef5 --- /dev/null +++ b/src/library/spring-boot-simplejndi/src/main/java/org/geoserver/cloud/autoconfigure/jndi/JNDIDataSourceAutoConfiguration.java @@ -0,0 +1,19 @@ +/* + * (c) 2022 Open Source Geospatial Foundation - all rights reserved This code is licensed under the + * GPL 2.0 license, available at the root application directory. + */ +package org.geoserver.cloud.autoconfigure.jndi; + +import org.geoserver.cloud.config.jndi.JNDIDataSourceConfiguration; +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.AutoConfigureOrder; +import org.springframework.context.annotation.Import; +import org.springframework.core.Ordered; + +/** + * @since 1.0 + */ +@AutoConfiguration +@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE) +@Import(JNDIDataSourceConfiguration.class) +public class JNDIDataSourceAutoConfiguration {} diff --git a/src/library/spring-boot-simplejndi/src/main/java/org/geoserver/cloud/config/jndi/SimpleJNDIStaticContextInitializer.java b/src/library/spring-boot-simplejndi/src/main/java/org/geoserver/cloud/autoconfigure/jndi/SimpleJNDIStaticContextInitializer.java similarity index 98% rename from src/library/spring-boot-simplejndi/src/main/java/org/geoserver/cloud/config/jndi/SimpleJNDIStaticContextInitializer.java rename to src/library/spring-boot-simplejndi/src/main/java/org/geoserver/cloud/autoconfigure/jndi/SimpleJNDIStaticContextInitializer.java index 22a87041d..4416db3f4 100644 --- a/src/library/spring-boot-simplejndi/src/main/java/org/geoserver/cloud/config/jndi/SimpleJNDIStaticContextInitializer.java +++ b/src/library/spring-boot-simplejndi/src/main/java/org/geoserver/cloud/autoconfigure/jndi/SimpleJNDIStaticContextInitializer.java @@ -2,7 +2,7 @@ * (c) 2022 Open Source Geospatial Foundation - all rights reserved This code is licensed under the * GPL 2.0 license, available at the root application directory. */ -package org.geoserver.cloud.config.jndi; +package org.geoserver.cloud.autoconfigure.jndi; import lombok.extern.slf4j.Slf4j; diff --git a/src/library/spring-boot-simplejndi/src/main/java/org/geoserver/cloud/config/jndidatasource/JNDIDataSourceAutoConfiguration.java b/src/library/spring-boot-simplejndi/src/main/java/org/geoserver/cloud/config/jndi/JNDIDataSourceConfiguration.java similarity index 75% rename from src/library/spring-boot-simplejndi/src/main/java/org/geoserver/cloud/config/jndidatasource/JNDIDataSourceAutoConfiguration.java rename to src/library/spring-boot-simplejndi/src/main/java/org/geoserver/cloud/config/jndi/JNDIDataSourceConfiguration.java index 5fc0f0c39..350ab5626 100644 --- a/src/library/spring-boot-simplejndi/src/main/java/org/geoserver/cloud/config/jndidatasource/JNDIDataSourceAutoConfiguration.java +++ b/src/library/spring-boot-simplejndi/src/main/java/org/geoserver/cloud/config/jndi/JNDIDataSourceConfiguration.java @@ -2,18 +2,18 @@ * (c) 2022 Open Source Geospatial Foundation - all rights reserved This code is licensed under the * GPL 2.0 license, available at the root application directory. */ -package org.geoserver.cloud.config.jndidatasource; +package org.geoserver.cloud.config.jndi; -import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; /** * @since 1.0 */ -@AutoConfiguration +@Configuration @EnableConfigurationProperties(JNDIDataSourcesConfigurationProperties.class) -public class JNDIDataSourceAutoConfiguration { +public class JNDIDataSourceConfiguration { @Bean JNDIInitializer jndiInitializer(JNDIDataSourcesConfigurationProperties config) { return new JNDIInitializer(config); diff --git a/src/library/spring-boot-simplejndi/src/main/java/org/geoserver/cloud/config/jndidatasource/JNDIDataSourcesConfigurationProperties.java b/src/library/spring-boot-simplejndi/src/main/java/org/geoserver/cloud/config/jndi/JNDIDataSourcesConfigurationProperties.java similarity index 91% rename from src/library/spring-boot-simplejndi/src/main/java/org/geoserver/cloud/config/jndidatasource/JNDIDataSourcesConfigurationProperties.java rename to src/library/spring-boot-simplejndi/src/main/java/org/geoserver/cloud/config/jndi/JNDIDataSourcesConfigurationProperties.java index 3edd15ce7..5c2598662 100644 --- a/src/library/spring-boot-simplejndi/src/main/java/org/geoserver/cloud/config/jndidatasource/JNDIDataSourcesConfigurationProperties.java +++ b/src/library/spring-boot-simplejndi/src/main/java/org/geoserver/cloud/config/jndi/JNDIDataSourcesConfigurationProperties.java @@ -2,7 +2,7 @@ * (c) 2022 Open Source Geospatial Foundation - all rights reserved This code is licensed under the * GPL 2.0 license, available at the root application directory. */ -package org.geoserver.cloud.config.jndidatasource; +package org.geoserver.cloud.config.jndi; import lombok.Data; diff --git a/src/library/spring-boot-simplejndi/src/main/java/org/geoserver/cloud/config/jndidatasource/JNDIDatasourceConfig.java b/src/library/spring-boot-simplejndi/src/main/java/org/geoserver/cloud/config/jndi/JNDIDatasourceConfig.java similarity index 93% rename from src/library/spring-boot-simplejndi/src/main/java/org/geoserver/cloud/config/jndidatasource/JNDIDatasourceConfig.java rename to src/library/spring-boot-simplejndi/src/main/java/org/geoserver/cloud/config/jndi/JNDIDatasourceConfig.java index f7b2f4429..058ef26bd 100644 --- a/src/library/spring-boot-simplejndi/src/main/java/org/geoserver/cloud/config/jndidatasource/JNDIDatasourceConfig.java +++ b/src/library/spring-boot-simplejndi/src/main/java/org/geoserver/cloud/config/jndi/JNDIDatasourceConfig.java @@ -2,7 +2,7 @@ * (c) 2022 Open Source Geospatial Foundation - all rights reserved This code is licensed under the * GPL 2.0 license, available at the root application directory. */ -package org.geoserver.cloud.config.jndidatasource; +package org.geoserver.cloud.config.jndi; import lombok.Data; import lombok.EqualsAndHashCode; diff --git a/src/library/spring-boot-simplejndi/src/main/java/org/geoserver/cloud/config/jndidatasource/JNDIInitializer.java b/src/library/spring-boot-simplejndi/src/main/java/org/geoserver/cloud/config/jndi/JNDIInitializer.java similarity index 91% rename from src/library/spring-boot-simplejndi/src/main/java/org/geoserver/cloud/config/jndidatasource/JNDIInitializer.java rename to src/library/spring-boot-simplejndi/src/main/java/org/geoserver/cloud/config/jndi/JNDIInitializer.java index f2a84c586..f1c128931 100644 --- a/src/library/spring-boot-simplejndi/src/main/java/org/geoserver/cloud/config/jndidatasource/JNDIInitializer.java +++ b/src/library/spring-boot-simplejndi/src/main/java/org/geoserver/cloud/config/jndi/JNDIInitializer.java @@ -2,7 +2,7 @@ * (c) 2022 Open Source Geospatial Foundation - all rights reserved This code is licensed under the * GPL 2.0 license, available at the root application directory. */ -package org.geoserver.cloud.config.jndidatasource; +package org.geoserver.cloud.config.jndi; import com.zaxxer.hikari.HikariDataSource; @@ -28,12 +28,17 @@ public class JNDIInitializer implements InitializingBean { private JNDIDataSourcesConfigurationProperties config; + static boolean initialized = false; + JNDIInitializer(JNDIDataSourcesConfigurationProperties config) { this.config = config; } @Override public void afterPropertiesSet() throws Exception { + if (initialized) + throw new IllegalStateException("JNDI already initialized or failed. Giving up."); + initialized = true; Map configs = config.getDatasources(); @@ -52,8 +57,12 @@ public void afterPropertiesSet() throws Exception { props.setName(name); } }); - configs.entrySet() - .forEach(e -> setUpDataSource(toJndiDatasourceName(e.getKey()), e.getValue())); + try { + configs.entrySet() + .forEach(e -> setUpDataSource(toJndiDatasourceName(e.getKey()), e.getValue())); + } catch (Exception e) { + throw new IllegalStateException(e); + } } String toJndiDatasourceName(String dsname) { diff --git a/src/library/spring-boot-simplejndi/src/main/resources/META-INF/spring.factories b/src/library/spring-boot-simplejndi/src/main/resources/META-INF/spring.factories index af2e32717..ce316edf9 100644 --- a/src/library/spring-boot-simplejndi/src/main/resources/META-INF/spring.factories +++ b/src/library/spring-boot-simplejndi/src/main/resources/META-INF/spring.factories @@ -1,7 +1,7 @@ # Initializers org.springframework.context.ApplicationContextInitializer=\ -org.geoserver.cloud.config.jndi.SimpleJNDIStaticContextInitializer +org.geoserver.cloud.autoconfigure.jndi.SimpleJNDIStaticContextInitializer # Auto Configure org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ -org.geoserver.cloud.config.jndidatasource.JNDIDataSourceAutoConfiguration \ No newline at end of file +org.geoserver.cloud.autoconfigure.jndi.JNDIDataSourceAutoConfiguration \ No newline at end of file diff --git a/src/library/spring-boot-simplejndi/src/test/java/org/geoserver/cloud/config/jndidatasource/JNDIDataSourceAutoConfigurationTest.java b/src/library/spring-boot-simplejndi/src/test/java/org/geoserver/cloud/autoconfigure/jndi/JNDIDataSourceAutoConfigurationTest.java similarity index 84% rename from src/library/spring-boot-simplejndi/src/test/java/org/geoserver/cloud/config/jndidatasource/JNDIDataSourceAutoConfigurationTest.java rename to src/library/spring-boot-simplejndi/src/test/java/org/geoserver/cloud/autoconfigure/jndi/JNDIDataSourceAutoConfigurationTest.java index f60f47dfa..9d73daf76 100644 --- a/src/library/spring-boot-simplejndi/src/test/java/org/geoserver/cloud/config/jndidatasource/JNDIDataSourceAutoConfigurationTest.java +++ b/src/library/spring-boot-simplejndi/src/test/java/org/geoserver/cloud/autoconfigure/jndi/JNDIDataSourceAutoConfigurationTest.java @@ -2,13 +2,13 @@ * (c) 2022 Open Source Geospatial Foundation - all rights reserved This code is licensed under the * GPL 2.0 license, available at the root application directory. */ -package org.geoserver.cloud.config.jndidatasource; +package org.geoserver.cloud.autoconfigure.jndi; import static org.assertj.core.api.Assertions.assertThat; import com.zaxxer.hikari.HikariDataSource; -import org.geoserver.cloud.config.jndi.SimpleJNDIStaticContextInitializer; +import org.geoserver.cloud.config.jndi.JNDIDataSourceConfiguration; import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.test.context.runner.ApplicationContextRunner; @@ -24,11 +24,10 @@ class JNDIDataSourceAutoConfigurationTest { private ApplicationContextRunner runner = new ApplicationContextRunner() .withInitializer(new SimpleJNDIStaticContextInitializer()) - .withConfiguration( - AutoConfigurations.of(JNDIDataSourceAutoConfiguration.class)); + .withConfiguration(AutoConfigurations.of(JNDIDataSourceConfiguration.class)); @Test - void test() { + void testInitialContextLookup() { runner.withPropertyValues( // "jndi.datasources.ds1.url: jdbc:h2:mem:ds1", // diff --git a/src/library/spring-boot-simplejndi/src/test/java/org/geoserver/cloud/config/jndi/SimpleJNDIStaticContextInitializerTest.java b/src/library/spring-boot-simplejndi/src/test/java/org/geoserver/cloud/config/jndi/SimpleJNDIStaticContextInitializerTest.java index 913a0e282..be57f5eb6 100644 --- a/src/library/spring-boot-simplejndi/src/test/java/org/geoserver/cloud/config/jndi/SimpleJNDIStaticContextInitializerTest.java +++ b/src/library/spring-boot-simplejndi/src/test/java/org/geoserver/cloud/config/jndi/SimpleJNDIStaticContextInitializerTest.java @@ -6,6 +6,7 @@ import static org.assertj.core.api.Assertions.assertThat; +import org.geoserver.cloud.autoconfigure.jndi.SimpleJNDIStaticContextInitializer; import org.geoserver.cloud.jndi.SimpleNamingContext; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.runner.ApplicationContextRunner;