Skip to content

Commit c1a7ecb

Browse files
committed
✨ SpringMVC aem proxy implementation optional based on more criteria
SpringMVC implementation can now be overridden by having other autoconfigurations override it (as in the case of fluentforms-jersey-spring-boot-starter). It can also be overridden via an explicit configuration setting (fluentforms.rproxy.type).
1 parent adb7402 commit c1a7ecb

4 files changed

Lines changed: 64 additions & 35 deletions

File tree

spring/ConfigurationProperties.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,9 @@ be set to `/clientApp` (as in `fluentforms.rproxy.clientPrefix=/clientApp`).
4343

4444
`fluentforms.rproxy.afBaseLocation` - TBD - This needs to be documented.
4545

46+
`fluentforms.rproxy.type` - This is used to set the mechanism used to reverse-proxy secondary resources to AEM. If the value is `springmvc`, then Spring MVC is used to implement the reverse proxy. If it is `jersey`, then JAX-RS Jersey is used. This property is optional and, if omitted, then the autoconfiguration will choose `springmvc` if no other type is available. It will typically use a different implementation if it is available (e.g. if `fluentforms-jersey-spring-starter` is on the class path). This means that under normal circumstances, this setting should not have to be set and is only intended to be used to override the autoconfiguration mechanisms.
47+
48+
4649
### Rest Client Properties
4750

4851
Fluent Forms can be configured to use one of two different REST client libraries. It can use either the Jersey client libraries or the Spring RestClient libraries. it was originally developed to use the Jersey client libraries however this some drawbacks - firstly, the Spring requires special configuration when you combine it with libraries that use the built in Spring Web Mechanisms (e.g. Spring MVC, Spring Boot Activator, etc. - see [https://docs.spring.io/spring-boot/how-to/jersey.html](https://docs.spring.io/spring-boot/how-to/jersey.html)). Secondly, Spring Jersey is an extra dependency that duplicates functionality that is already available in the Spring Framework, so it causes some jar bloat.

spring/fluentforms-spring-boot-autoconfigure/src/main/java/com/_4point/aem/fluentforms/spring/AemProxyAutoConfiguration.java

Lines changed: 14 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -26,43 +26,22 @@
2626
@AutoConfiguration
2727
@ConditionalOnWebApplication(type=Type.SERVLET)
2828
@ConditionalOnProperty(prefix="fluentforms.rproxy", name="enabled", havingValue="true", matchIfMissing=true )
29+
@ConditionalOnProperty(prefix="fluentforms.rproxy", name="type", havingValue="springmvc", matchIfMissing=true )
2930
@EnableConfigurationProperties({AemConfiguration.class, AemProxyConfiguration.class})
31+
@ConditionalOnMissingBean(AemProxyImplemention.class)
3032
public class AemProxyAutoConfiguration {
31-
32-
// /**
33-
// * Configures the JAX-RS resources associated with reverse proxying resources and submissions from
34-
// * Adaptive Forms.
35-
// *
36-
// * @param aemConfig
37-
// * AEM configuration typically configured using application.properties files. This is
38-
// * typically injected by the Spring Framework.
39-
// * @param aemProxyConfig
40-
// * AEM proxy-specific configuration typically configured using application.properties files.
41-
// * This is typically injected by the Spring Framework.
42-
// * @param aemProxyTaskExecutor
43-
// * @return
44-
// * JAX-RS Resource configuration customizer that is used by the spring-jersey starter to configure
45-
// * JAX-RS Resources (i.e. endpoints)
46-
// */
47-
// @Bean
48-
// public ResourceConfigCustomizer afProxyConfigurer(AemConfiguration aemConfig, AemProxyConfiguration aemProxyConfig, @Autowired(required = false) SslBundles sslBundles, TaskExecutor aemProxyTaskExecutor) {
49-
// return config->config.register(new AemProxyEndpoint(aemConfig, aemProxyConfig, sslBundles, aemProxyTaskExecutor))
50-
// .register(new AemProxyAfSubmission())
51-
// ;
52-
// }
53-
//
54-
// /**
55-
// * Supply a TaskExecutor for use by the AemProxyEndpoint. This is used to process csrf token requests because they are Chunked.
56-
// *
57-
// * @return the taskeExecutor that will be used to process csrf token requests.
58-
// */
59-
// @Bean
60-
// public TaskExecutor aemProxyTaskExecutor() {
61-
// var executor = new SimpleAsyncTaskExecutor("AemProxy-");
62-
// // Use virtual threads if available. This will be the default for Java 21 and later.
63-
// executor.setVirtualThreads(JavaVersion.getJavaVersion().isEqualOrNewerThan(JavaVersion.TWENTY_ONE));
64-
// return executor;
65-
// }
33+
34+
/**
35+
* Marker bean to indicate that the Spring MVC-based AEM Proxy implementation is being used.
36+
*
37+
* @return
38+
*/
39+
@Bean
40+
AemProxyImplemention aemProxyImplemention() {
41+
return new AemProxyImplemention() {
42+
// This is just a marker bean.
43+
};
44+
}
6645

6746
@Bean
6847
AemProxyEndpoint aemProxyEndpoint(AemConfiguration aemConfig, AemProxyConfiguration aemProxyConfig, @Autowired(required = false) RestClientSsl restClientSsl) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package com._4point.aem.fluentforms.spring;
2+
3+
/**
4+
* This is a placeholder interface used to identify the AEM Proxy Implementation, Each implementation
5+
* (spring-mvc, jersey, etc.) will provide a bean that implements this one so that only one implementation is used.
6+
*/
7+
public interface AemProxyImplemention {
8+
9+
}

spring/fluentforms-spring-boot-autoconfigure/src/test/java/com/_4point/aem/fluentforms/spring/AutoConfigurationTest.java

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ private static class SpringBootMocks {
4343

4444
private static final AutoConfigurations LOCAL_SUBMIT_CONFIG = AutoConfigurations.of(FluentFormsAutoConfiguration.class, AemProxyAutoConfiguration.class, DummyLocalSubmitHandler.class, SpringBootMocks.class);
4545

46+
private static final AutoConfigurations ALTERNATE_PROXY_CONFIG = AutoConfigurations.of(DummyProxyImplementation.class, FluentFormsAutoConfiguration.class, AemProxyAutoConfiguration.class, SpringBootMocks.class);
47+
4648
// Tests to make sure that only the FluentFormsLibraries are loaded in a non-web application.
4749
private static final ContextConsumer<? super AssertableApplicationContext> FF_LIBRARIES_ONLY = (context) -> {
4850
assertAll(
@@ -108,6 +110,9 @@ private static class SpringBootMocks {
108110
private final WebApplicationContextRunner webLocalSubmitContextRunner = new WebApplicationContextRunner()
109111
.withConfiguration(LOCAL_SUBMIT_CONFIG);
110112

113+
private final WebApplicationContextRunner webAlternateProxyContextRunner = new WebApplicationContextRunner()
114+
.withConfiguration(ALTERNATE_PROXY_CONFIG);
115+
111116
// Only the services that do not require a web server should be started.
112117
@Test
113118
void nonWebContext_StartNonWebServices() {
@@ -165,6 +170,35 @@ void webContext_StartAllServices_LocalSubmit() {
165170
.run(WEB_LOCAL_SUBMIT_SERVICES);
166171
}
167172

173+
// Only the FluentForms libraries are instantiated by this autoconfiguration when an alternate proxy implementation is supplied.
174+
@Test
175+
void webContext_StartAllServices_AlternateProxySupplied() {
176+
this.webAlternateProxyContextRunner
177+
.withPropertyValues("fluentforms.aem.servername=localhost", "fluentforms.aem.port=4502",
178+
"fluentforms.aem.user=user", "fluentforms.aem.password=password")
179+
.run(WEB_FF_LIBRARIES_ONLY);
180+
}
181+
182+
// Only the FluentForms libraries are instantiated when an alternate proxy tyoe is configured.
183+
@Test
184+
void webContext_ProxyDisabled_AlternateProxyConfigured() {
185+
this.webContextRunner
186+
.withPropertyValues("fluentforms.aem.servername=localhost", "fluentforms.aem.port=4502",
187+
"fluentforms.aem.user=user", "fluentforms.aem.password=password",
188+
"fluentforms.rproxy.type=someothertype")
189+
.run(WEB_FF_LIBRARIES_ONLY);
190+
}
191+
192+
// All services should start when the default proxy type is configured.
193+
@Test
194+
void webContext_ProxyEnabled_DefaultProxyConfigured() {
195+
this.webContextRunner
196+
.withPropertyValues("fluentforms.aem.servername=localhost", "fluentforms.aem.port=4502",
197+
"fluentforms.aem.user=user", "fluentforms.aem.password=password",
198+
"fluentforms.rproxy.type=springmvc")
199+
.run(WEB_ALL_DEFAULT_SERVICES);
200+
}
201+
168202

169203
public static class DummyLocalSubmitHandler implements AfSubmissionHandler {
170204

@@ -178,4 +212,8 @@ public SubmitResponse processSubmission(Submission submission) {
178212
return null;
179213
}
180214
}
215+
216+
public static class DummyProxyImplementation implements AemProxyImplemention {
217+
218+
}
181219
}

0 commit comments

Comments
 (0)