From 502efa052417f565b1d5a10342c33bb6448fbdc1 Mon Sep 17 00:00:00 2001 From: Gabriel Roldan Date: Mon, 12 Aug 2024 10:55:16 -0300 Subject: [PATCH] Make it possible to have the gs-acl-plugin-wps module on the classpath if the WPS extension is not installed --- .../wps/AclWpsAutoConfiguration.java | 3 +- .../wps/AclWpsAutoConfigurationTest.java | 42 +++++++++++++++++-- .../wps/AclWpsIntegrationConfiguration.java | 3 ++ .../wps/WPSResourceManagerClassCondition.java | 42 +++++++++++++++++++ 4 files changed, 85 insertions(+), 5 deletions(-) create mode 100644 src/plugin/wps/src/main/java/org/geoserver/acl/plugin/config/wps/WPSResourceManagerClassCondition.java diff --git a/src/plugin/plugin/src/main/java/org/geoserver/acl/plugin/autoconfigure/wps/AclWpsAutoConfiguration.java b/src/plugin/plugin/src/main/java/org/geoserver/acl/plugin/autoconfigure/wps/AclWpsAutoConfiguration.java index b2e4f27..40df828 100644 --- a/src/plugin/plugin/src/main/java/org/geoserver/acl/plugin/autoconfigure/wps/AclWpsAutoConfiguration.java +++ b/src/plugin/plugin/src/main/java/org/geoserver/acl/plugin/autoconfigure/wps/AclWpsAutoConfiguration.java @@ -6,13 +6,12 @@ import org.geoserver.acl.plugin.autoconfigure.accessmanager.ConditionalOnAclEnabled; import org.geoserver.acl.plugin.config.wps.AclWpsIntegrationConfiguration; -import org.geoserver.wps.resource.WPSResourceManager; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.context.annotation.Import; @AutoConfiguration @ConditionalOnAclEnabled -@ConditionalOnBean(WPSResourceManager.class) +@ConditionalOnBean(name = "wpsResourceManager") @Import({AclWpsIntegrationConfiguration.class}) public class AclWpsAutoConfiguration {} diff --git a/src/plugin/plugin/src/test/java/org/geoserver/acl/plugin/autoconfigure/wps/AclWpsAutoConfigurationTest.java b/src/plugin/plugin/src/test/java/org/geoserver/acl/plugin/autoconfigure/wps/AclWpsAutoConfigurationTest.java index c735867..97956dd 100644 --- a/src/plugin/plugin/src/test/java/org/geoserver/acl/plugin/autoconfigure/wps/AclWpsAutoConfigurationTest.java +++ b/src/plugin/plugin/src/test/java/org/geoserver/acl/plugin/autoconfigure/wps/AclWpsAutoConfigurationTest.java @@ -8,11 +8,13 @@ import static org.mockito.Mockito.mock; import org.geoserver.acl.plugin.accessmanager.wps.ChainStatusHolder; +import org.geoserver.acl.plugin.config.wps.WPSResourceManagerClassCondition; import org.geoserver.acl.plugin.wps.DefaultExecutionIdRetriever; import org.geoserver.acl.plugin.wps.WPSProcessListener; import org.geoserver.wps.resource.WPSResourceManager; import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.test.context.FilteredClassLoader; import org.springframework.boot.test.context.runner.ApplicationContextRunner; /** {@link AclWpsAutoConfiguration} tests */ @@ -24,7 +26,10 @@ class AclWpsAutoConfigurationTest { @Test void testEnabledWhenAllConditionsMatch() { - runner.withBean(WPSResourceManager.class, () -> mock(WPSResourceManager.class)) + runner.withBean( + "wpsResourceManager", + WPSResourceManager.class, + () -> mock(WPSResourceManager.class)) .run( context -> { assertThat(context) @@ -37,7 +42,10 @@ void testEnabledWhenAllConditionsMatch() { @Test void testConditionalOnAclEnabled() { - runner.withBean(WPSResourceManager.class, () -> mock(WPSResourceManager.class)) + runner.withBean( + "wpsResourceManager", + WPSResourceManager.class, + () -> mock(WPSResourceManager.class)) .withPropertyValues("geoserver.acl.enabled=false") .run( context -> { @@ -48,7 +56,10 @@ void testConditionalOnAclEnabled() { .doesNotHaveBean(WPSProcessListener.class); }); runner.withPropertyValues("geoserver.acl.enabled=true") - .withBean(WPSResourceManager.class, () -> mock(WPSResourceManager.class)) + .withBean( + "wpsResourceManager", + WPSResourceManager.class, + () -> mock(WPSResourceManager.class)) .run( context -> { assertThat(context) @@ -70,4 +81,29 @@ void testConditionalOnWPSResourceManager() { .doesNotHaveBean(WPSProcessListener.class); }); } + + @Test + void testWPSResourceManagerClassCondition() { + + FilteredClassLoader classLoader = new FilteredClassLoader(WPSResourceManager.class); + WPSResourceManagerClassCondition.classLoader(classLoader); + try { + runner + // bypass the @ConditionalOnBean(name="wpsResourceManager") in the + // Autoconfiguration to hit the plain spring condition in + // AclWpsIntegrationConfiguration + .withBean("wpsResourceManager", Object.class, () -> new Object()) + .withClassLoader(classLoader) + .run( + context -> { + assertThat(context) + .hasNotFailed() + .doesNotHaveBean(ChainStatusHolder.class) + .doesNotHaveBean(DefaultExecutionIdRetriever.class) + .doesNotHaveBean(WPSProcessListener.class); + }); + } finally { + WPSResourceManagerClassCondition.classLoader(null); + } + } } diff --git a/src/plugin/wps/src/main/java/org/geoserver/acl/plugin/config/wps/AclWpsIntegrationConfiguration.java b/src/plugin/wps/src/main/java/org/geoserver/acl/plugin/config/wps/AclWpsIntegrationConfiguration.java index 0214b36..2137bf4 100644 --- a/src/plugin/wps/src/main/java/org/geoserver/acl/plugin/config/wps/AclWpsIntegrationConfiguration.java +++ b/src/plugin/wps/src/main/java/org/geoserver/acl/plugin/config/wps/AclWpsIntegrationConfiguration.java @@ -9,9 +9,12 @@ import org.geoserver.acl.plugin.wps.WPSProcessListener; import org.geoserver.wps.resource.WPSResourceManager; import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Configuration; @Configuration(proxyBeanMethods = false) +// spring with no spring boot equivalent to @ConditionalOnClass(WPSResourceManager.class) +@Conditional(value = WPSResourceManagerClassCondition.class) public class AclWpsIntegrationConfiguration { @Bean diff --git a/src/plugin/wps/src/main/java/org/geoserver/acl/plugin/config/wps/WPSResourceManagerClassCondition.java b/src/plugin/wps/src/main/java/org/geoserver/acl/plugin/config/wps/WPSResourceManagerClassCondition.java new file mode 100644 index 0000000..3331bbe --- /dev/null +++ b/src/plugin/wps/src/main/java/org/geoserver/acl/plugin/config/wps/WPSResourceManagerClassCondition.java @@ -0,0 +1,42 @@ +/* (c) 2024 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.acl.plugin.config.wps; + +import com.google.common.annotations.VisibleForTesting; + +import org.springframework.context.annotation.ConditionContext; +import org.springframework.context.annotation.ConfigurationCondition; +import org.springframework.core.type.AnnotatedTypeMetadata; + +/** + * Spring without spring boot equivalent to {@code @ConditionalOnClass(WPSResourceManager.class)}, + * so the {@code gs-acl-plugin-wps} module can be on the vanilla GeoServer classpath when the + * geoserver WPS extension is not installed. + */ +public class WPSResourceManagerClassCondition implements ConfigurationCondition { + + private static ClassLoader classLoader; + + @VisibleForTesting + public static void classLoader(ClassLoader cl) { + classLoader = cl; + } + + @Override + public ConfigurationPhase getConfigurationPhase() { + return ConfigurationPhase.PARSE_CONFIGURATION; + } + + @Override + public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { + try { + if (null == classLoader) classLoader = getClass().getClassLoader(); + classLoader.loadClass("org.geoserver.wps.resource.WPSResourceManager"); + return true; + } catch (ClassNotFoundException e) { + return false; + } + } +}