diff --git a/spring/ConfigurationProperties.md b/spring/ConfigurationProperties.md
index d4bc8126..5c80769a 100644
--- a/spring/ConfigurationProperties.md
+++ b/spring/ConfigurationProperties.md
@@ -26,6 +26,9 @@ spring boot starter web site for more details.
can be `true` or `false`. `true` will tell FLuentForms to log in with https, `false` will result in an http connection. This
property is optional, and it defaults to `false` if it is not supplied.
+`fluentforms.aem.sslBundle` - This is the name used to locate a Spring Security SSL Bundle that will be used as a trust store
+for SSL HTTPS connections to AEM. This property is optional, and it defaults to `aem` if it is not supplied.
+
### Adaptive Forms
`fluentforms.rproxy.enabled` - This is used to enable/disable the reverse proxying of secondary resources to AEM. If it is
diff --git a/spring/fluentforms-sample-cli-app/pom.xml b/spring/fluentforms-sample-cli-app/pom.xml
index 3102e342..e6401873 100644
--- a/spring/fluentforms-sample-cli-app/pom.xml
+++ b/spring/fluentforms-sample-cli-app/pom.xml
@@ -5,7 +5,7 @@
org.springframework.boot
spring-boot-starter-parent
- 3.1.4
+ 3.3.5
com._4point.aem.fluentforms
diff --git a/spring/fluentforms-sample-web-app/pom.xml b/spring/fluentforms-sample-web-app/pom.xml
index d2f3c9a3..a7a80ec2 100644
--- a/spring/fluentforms-sample-web-app/pom.xml
+++ b/spring/fluentforms-sample-web-app/pom.xml
@@ -5,7 +5,7 @@
org.springframework.boot
spring-boot-starter-parent
- 3.1.4
+ 3.3.5
com._4point.aem.fluentforms
fluentforms-sample-web-app
diff --git a/spring/fluentforms-spring-boot-autoconfigure/pom.xml b/spring/fluentforms-spring-boot-autoconfigure/pom.xml
index 8ddcac76..075aef3a 100644
--- a/spring/fluentforms-spring-boot-autoconfigure/pom.xml
+++ b/spring/fluentforms-spring-boot-autoconfigure/pom.xml
@@ -5,7 +5,7 @@
org.springframework.boot
spring-boot-starter-parent
- 3.1.4
+ 3.3.5
com._4point.aem.fluentforms
diff --git a/spring/fluentforms-spring-boot-autoconfigure/src/main/java/com/_4point/aem/fluentforms/spring/AemConfiguration.java b/spring/fluentforms-spring-boot-autoconfigure/src/main/java/com/_4point/aem/fluentforms/spring/AemConfiguration.java
index 45d537a9..f8a6615b 100644
--- a/spring/fluentforms-spring-boot-autoconfigure/src/main/java/com/_4point/aem/fluentforms/spring/AemConfiguration.java
+++ b/spring/fluentforms-spring-boot-autoconfigure/src/main/java/com/_4point/aem/fluentforms/spring/AemConfiguration.java
@@ -22,7 +22,8 @@ public record AemConfiguration(
Integer port, // "aem.port"
String user, // "aem.user"
String password, // "aem.password"
- @DefaultValue("false") Boolean useSsl // "aem.useSsl"
+ @DefaultValue("false") Boolean useSsl, // "aem.useSsl"
+ @DefaultValue("aem") String sslBundle // "aem.sslBundle" - Spring SSL Bundle for trust store
) {
public String url() {
diff --git a/spring/fluentforms-spring-boot-autoconfigure/src/main/java/com/_4point/aem/fluentforms/spring/AemProxyAfSubmission.java b/spring/fluentforms-spring-boot-autoconfigure/src/main/java/com/_4point/aem/fluentforms/spring/AemProxyAfSubmission.java
index 25e490a7..7fce01ed 100644
--- a/spring/fluentforms-spring-boot-autoconfigure/src/main/java/com/_4point/aem/fluentforms/spring/AemProxyAfSubmission.java
+++ b/spring/fluentforms-spring-boot-autoconfigure/src/main/java/com/_4point/aem/fluentforms/spring/AemProxyAfSubmission.java
@@ -16,14 +16,13 @@
import org.glassfish.jersey.client.ChunkedInput;
import org.glassfish.jersey.client.ClientProperties;
-import org.glassfish.jersey.client.authentication.HttpAuthenticationFeature;
import org.glassfish.jersey.media.multipart.BodyPartEntity;
import org.glassfish.jersey.media.multipart.FormDataBodyPart;
import org.glassfish.jersey.media.multipart.FormDataMultiPart;
-import org.glassfish.jersey.media.multipart.MultiPartFeature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.ssl.SslBundles;
import org.springframework.util.MultiValueMap;
import org.springframework.util.MultiValueMapAdapter;
@@ -34,7 +33,6 @@
import jakarta.ws.rs.PathParam;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.client.Client;
-import jakarta.ws.rs.client.ClientBuilder;
import jakarta.ws.rs.client.Entity;
import jakarta.ws.rs.client.WebTarget;
import jakarta.ws.rs.core.Context;
@@ -176,9 +174,9 @@ static class AfSubmitAemProxyProcessor implements AfSubmitProcessor {
private final AemConfiguration aemConfig;
private final Client httpClient;
- public AfSubmitAemProxyProcessor(AemConfiguration aemConfig) {
+ public AfSubmitAemProxyProcessor(AemConfiguration aemConfig, SslBundles sslBundles) {
this.aemConfig = aemConfig;
- this.httpClient = ClientBuilder.newClient().register(HttpAuthenticationFeature.basic(aemConfig.user(), aemConfig.password())).register(MultiPartFeature.class);
+ this.httpClient = JerseyClientFactory.createClient(sslBundles, aemConfig.sslBundle(), aemConfig.user(), aemConfig.password());
}
@Override
diff --git a/spring/fluentforms-spring-boot-autoconfigure/src/main/java/com/_4point/aem/fluentforms/spring/AemProxyAutoConfiguration.java b/spring/fluentforms-spring-boot-autoconfigure/src/main/java/com/_4point/aem/fluentforms/spring/AemProxyAutoConfiguration.java
index 74503e41..80d956f1 100644
--- a/spring/fluentforms-spring-boot-autoconfigure/src/main/java/com/_4point/aem/fluentforms/spring/AemProxyAutoConfiguration.java
+++ b/spring/fluentforms-spring-boot-autoconfigure/src/main/java/com/_4point/aem/fluentforms/spring/AemProxyAutoConfiguration.java
@@ -2,6 +2,7 @@
import java.util.List;
+import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
@@ -10,6 +11,7 @@
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type;
import org.springframework.boot.autoconfigure.jersey.ResourceConfigCustomizer;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.boot.ssl.SslBundles;
import org.springframework.context.annotation.Bean;
import com._4point.aem.fluentforms.spring.AemProxyAfSubmission.AfSubmissionHandler;
@@ -43,8 +45,8 @@ public class AemProxyAutoConfiguration {
* JAX-RS Resources (i.e. endpoints)
*/
@Bean
- public ResourceConfigCustomizer afProxyConfigurer(AemConfiguration aemConfig, AemProxyConfiguration aemProxyConfig) {
- return config->config.register(new AemProxyEndpoint(aemConfig, aemProxyConfig))
+ public ResourceConfigCustomizer afProxyConfigurer(AemConfiguration aemConfig, AemProxyConfiguration aemProxyConfig, @Autowired(required = false) SslBundles sslBundles) {
+ return config->config.register(new AemProxyEndpoint(aemConfig, aemProxyConfig, sslBundles))
.register(new AemProxyAfSubmission())
;
}
@@ -85,8 +87,8 @@ public AfSubmitProcessor localSubmitProcessor(List submissi
*/
@ConditionalOnMissingBean({AfSubmitProcessor.class, AfSubmissionHandler.class})
@Bean()
- public AfSubmitProcessor aemSubmitProcessor(AemConfiguration aemConfig) {
- return new AfSubmitAemProxyProcessor(aemConfig);
+ public AfSubmitProcessor aemSubmitProcessor(AemConfiguration aemConfig, @Autowired(required = false) SslBundles sslBundles) {
+ return new AfSubmitAemProxyProcessor(aemConfig, sslBundles);
}
/**
@@ -105,7 +107,7 @@ public AfSubmitProcessor aemSubmitProcessor(AemConfiguration aemConfig) {
@ConditionalOnMissingBean(InternalAfSubmitAemProxyProcessor.class)
@ConditionalOnBean(AfSubmissionHandler.class)
@Bean
- public InternalAfSubmitAemProxyProcessor aemProxyProcessor(AemConfiguration aemConfig) {
- return ()->new AfSubmitAemProxyProcessor(aemConfig);
+ public InternalAfSubmitAemProxyProcessor aemProxyProcessor(AemConfiguration aemConfig, @Autowired(required = false) SslBundles sslBundles) {
+ return ()->new AfSubmitAemProxyProcessor(aemConfig, sslBundles);
}
}
diff --git a/spring/fluentforms-spring-boot-autoconfigure/src/main/java/com/_4point/aem/fluentforms/spring/AemProxyEndpoint.java b/spring/fluentforms-spring-boot-autoconfigure/src/main/java/com/_4point/aem/fluentforms/spring/AemProxyEndpoint.java
index 977d14ff..bea1c4fc 100644
--- a/spring/fluentforms-spring-boot-autoconfigure/src/main/java/com/_4point/aem/fluentforms/spring/AemProxyEndpoint.java
+++ b/spring/fluentforms-spring-boot-autoconfigure/src/main/java/com/_4point/aem/fluentforms/spring/AemProxyEndpoint.java
@@ -7,28 +7,27 @@
import java.util.stream.Collectors;
import javax.naming.ConfigurationException;
+
+import org.glassfish.jersey.client.ChunkedInput;
+import org.glassfish.jersey.server.ChunkedOutput;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.boot.ssl.SslBundles;
+
+import com._4point.aem.docservices.rest_services.client.helpers.ReplacingInputStream;
+
import jakarta.ws.rs.GET;
import jakarta.ws.rs.HeaderParam;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.PathParam;
import jakarta.ws.rs.client.Client;
-import jakarta.ws.rs.client.ClientBuilder;
import jakarta.ws.rs.client.Entity;
import jakarta.ws.rs.client.WebTarget;
import jakarta.ws.rs.core.GenericType;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
-import org.glassfish.jersey.client.ChunkedInput;
-import org.glassfish.jersey.client.authentication.HttpAuthenticationFeature;
-import org.glassfish.jersey.media.multipart.MultiPartFeature;
-import org.glassfish.jersey.server.ChunkedOutput;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com._4point.aem.docservices.rest_services.client.helpers.ReplacingInputStream;
-
/**
* Reverse Proxy Code which reverse proxies secondary resources (.css, .js, etc.) that the browser will request.
* These requests are forwarded to AEM.
@@ -55,10 +54,10 @@ public class AemProxyEndpoint {
/**
*
*/
- public AemProxyEndpoint(AemConfiguration aemConfig, AemProxyConfiguration aemProxyConfig) {
+ public AemProxyEndpoint(AemConfiguration aemConfig, AemProxyConfiguration aemProxyConfig, SslBundles sslBundles) {
this.aemProxyConfig = aemProxyConfig;
this.aemConfig = aemConfig;
- this.httpClient = ClientBuilder.newClient().register(HttpAuthenticationFeature.basic(aemConfig.user(), aemConfig.password())).register(MultiPartFeature.class);
+ this.httpClient = JerseyClientFactory.createClient(sslBundles, aemConfig.sslBundle(), aemConfig.user(), aemConfig.password());
}
@Path("libs/granite/csrf/token.json")
diff --git a/spring/fluentforms-spring-boot-autoconfigure/src/main/java/com/_4point/aem/fluentforms/spring/FluentFormsAutoConfiguration.java b/spring/fluentforms-spring-boot-autoconfigure/src/main/java/com/_4point/aem/fluentforms/spring/FluentFormsAutoConfiguration.java
index 256943e6..3bcfe699 100644
--- a/spring/fluentforms-spring-boot-autoconfigure/src/main/java/com/_4point/aem/fluentforms/spring/FluentFormsAutoConfiguration.java
+++ b/spring/fluentforms-spring-boot-autoconfigure/src/main/java/com/_4point/aem/fluentforms/spring/FluentFormsAutoConfiguration.java
@@ -3,9 +3,11 @@
import java.io.InputStream;
import java.util.function.Function;
+import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.boot.ssl.SslBundles;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Lazy;
@@ -52,18 +54,19 @@
public class FluentFormsAutoConfiguration {
@SuppressWarnings("unchecked")
- private T setAemFields(T builder, AemConfiguration aemConfig) {
+ private T setAemFields(T builder, AemConfiguration aemConfig, SslBundles sslBundles) {
return (T)(builder.machineName(aemConfig.servername())
.port(aemConfig.port())
.basicAuthentication(aemConfig.user(), aemConfig.password())
.useSsl(aemConfig.useSsl())
+ .clientFactory(()->JerseyClientFactory.createClient(sslBundles, aemConfig.sslBundle()))
);
}
@ConditionalOnMissingBean
@Bean
- public AdaptiveFormsService adaptiveFormsService(AemConfiguration aemConfig, Function afInputStreamFilter) {
- return setAemFields(AdaptiveFormsService.builder(), aemConfig)
+ public AdaptiveFormsService adaptiveFormsService(AemConfiguration aemConfig, Function afInputStreamFilter, @Autowired(required = false) SslBundles sslBundles) {
+ return setAemFields(AdaptiveFormsService.builder(), aemConfig, sslBundles)
.addRenderResultFilter(afInputStreamFilter)
.build();
}
@@ -83,58 +86,58 @@ private Function buildInputFilter(String aemPrefix, St
@ConditionalOnMissingBean
@Bean
- public AssemblerService assemblerService(AemConfiguration aemConfig) {
- RestServicesDocAssemblerServiceAdapter adapter = setAemFields(RestServicesDocAssemblerServiceAdapter.builder(), aemConfig).build();
+ public AssemblerService assemblerService(AemConfiguration aemConfig, @Autowired(required = false) SslBundles sslBundles) {
+ RestServicesDocAssemblerServiceAdapter adapter = setAemFields(RestServicesDocAssemblerServiceAdapter.builder(), aemConfig, sslBundles).build();
return new AssemblerServiceImpl(adapter, UsageContext.CLIENT_SIDE);
}
@ConditionalOnMissingBean
@Bean
- public DocAssuranceService docAssuranceService(AemConfiguration aemConfig) {
- RestServicesDocAssuranceServiceAdapter adapter = setAemFields(RestServicesDocAssuranceServiceAdapter.builder(), aemConfig).build();
+ public DocAssuranceService docAssuranceService(AemConfiguration aemConfig, @Autowired(required = false) SslBundles sslBundles) {
+ RestServicesDocAssuranceServiceAdapter adapter = setAemFields(RestServicesDocAssuranceServiceAdapter.builder(), aemConfig, sslBundles).build();
return new DocAssuranceServiceImpl(adapter);
}
@ConditionalOnMissingBean
@Bean
- public FormsService formsService(AemConfiguration aemConfig) {
- RestServicesFormsServiceAdapter adapter = setAemFields(RestServicesFormsServiceAdapter.builder(), aemConfig).build();
+ public FormsService formsService(AemConfiguration aemConfig, @Autowired(required = false) SslBundles sslBundles) {
+ RestServicesFormsServiceAdapter adapter = setAemFields(RestServicesFormsServiceAdapter.builder(), aemConfig, sslBundles).build();
return new FormsServiceImpl(adapter, UsageContext.CLIENT_SIDE);
}
@ConditionalOnMissingBean
@Bean
- public GeneratePDFService generatePDFService(AemConfiguration aemConfig) {
- RestServicesGeneratePDFServiceAdapter adapter = setAemFields(RestServicesGeneratePDFServiceAdapter.builder(), aemConfig).build();
+ public GeneratePDFService generatePDFService(AemConfiguration aemConfig, @Autowired(required = false) SslBundles sslBundles) {
+ RestServicesGeneratePDFServiceAdapter adapter = setAemFields(RestServicesGeneratePDFServiceAdapter.builder(), aemConfig, sslBundles).build();
return new GeneratePDFServiceImpl(adapter);
}
@ConditionalOnMissingBean
@Bean
- public Html5FormsService html5FormsService(AemConfiguration aemConfig, AemProxyConfiguration aemProxyConfig) {
- return setAemFields(Html5FormsService.builder(), aemConfig)
+ public Html5FormsService html5FormsService(AemConfiguration aemConfig, AemProxyConfiguration aemProxyConfig, @Autowired(required = false) SslBundles sslBundles) {
+ return setAemFields(Html5FormsService.builder(), aemConfig, sslBundles)
.addRenderResultFilter(afInputStreamFilter(aemProxyConfig))
.build();
}
@ConditionalOnMissingBean
@Bean
- public OutputService outputService(AemConfiguration aemConfig) {
- RestServicesOutputServiceAdapter adapter = setAemFields(RestServicesOutputServiceAdapter.builder(), aemConfig).build();
+ public OutputService outputService(AemConfiguration aemConfig, @Autowired(required = false) SslBundles sslBundles) {
+ RestServicesOutputServiceAdapter adapter = setAemFields(RestServicesOutputServiceAdapter.builder(), aemConfig, sslBundles).build();
return new OutputServiceImpl(adapter, UsageContext.CLIENT_SIDE);
}
@ConditionalOnMissingBean
@Bean
- public PdfUtilityService pdfUtilityService(AemConfiguration aemConfig) {
- RestServicesPdfUtilityServiceAdapter adapter = setAemFields(RestServicesPdfUtilityServiceAdapter.builder(), aemConfig).build();
+ public PdfUtilityService pdfUtilityService(AemConfiguration aemConfig, @Autowired(required = false) SslBundles sslBundles) {
+ RestServicesPdfUtilityServiceAdapter adapter = setAemFields(RestServicesPdfUtilityServiceAdapter.builder(), aemConfig, sslBundles).build();
return new PdfUtilityServiceImpl(adapter);
}
@ConditionalOnMissingBean
@Bean
- public ConvertPdfService convertPdfService(AemConfiguration aemConfig) {
- RestServicesConvertPdfServiceAdapter adapter = setAemFields(RestServicesConvertPdfServiceAdapter.builder(), aemConfig).build();
+ public ConvertPdfService convertPdfService(AemConfiguration aemConfig, @Autowired(required = false) SslBundles sslBundles) {
+ RestServicesConvertPdfServiceAdapter adapter = setAemFields(RestServicesConvertPdfServiceAdapter.builder(), aemConfig, sslBundles).build();
return new ConvertPdfServiceImpl(adapter);
}
diff --git a/spring/fluentforms-spring-boot-autoconfigure/src/main/java/com/_4point/aem/fluentforms/spring/JerseyClientFactory.java b/spring/fluentforms-spring-boot-autoconfigure/src/main/java/com/_4point/aem/fluentforms/spring/JerseyClientFactory.java
new file mode 100644
index 00000000..6d4f6f86
--- /dev/null
+++ b/spring/fluentforms-spring-boot-autoconfigure/src/main/java/com/_4point/aem/fluentforms/spring/JerseyClientFactory.java
@@ -0,0 +1,43 @@
+package com._4point.aem.fluentforms.spring;
+
+import javax.net.ssl.SSLContext;
+
+import org.glassfish.jersey.client.authentication.HttpAuthenticationFeature;
+import org.glassfish.jersey.media.multipart.MultiPartFeature;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.boot.ssl.NoSuchSslBundleException;
+import org.springframework.boot.ssl.SslBundle;
+import org.springframework.boot.ssl.SslBundles;
+
+import jakarta.ws.rs.client.Client;
+import jakarta.ws.rs.client.ClientBuilder;
+
+/**
+ *
+ */
+public class JerseyClientFactory {
+ private final static Logger logger = LoggerFactory.getLogger(JerseyClientFactory.class);
+
+ public static Client createClient(SslBundles sslBundles, String bundleName, String username, String password) {
+ return createClient(sslBundles, bundleName)
+ .register(HttpAuthenticationFeature.basic(username, password))
+ .register(MultiPartFeature.class);
+ }
+
+ public static Client createClient(SslBundles sslBundles, String bundleName) {
+ if (sslBundles != null) {
+ logger.info("SslBundles is not null");
+ try {
+ SslBundle bundle = sslBundles.getBundle(bundleName);
+ logger.info("Client sslBundle is not null");
+ SSLContext sslContext = bundle.createSslContext();
+ return ClientBuilder.newBuilder().sslContext(sslContext).build();
+ } catch (NoSuchSslBundleException e) {
+ // Eat the exception and fall through to the default client
+ }
+ }
+ logger.info("Creating default client");
+ return ClientBuilder.newClient();
+ }
+}
diff --git a/spring/fluentforms-spring-boot-autoconfigure/src/test/java/com/_4point/aem/fluentforms/spring/AemConfigurationTest.java b/spring/fluentforms-spring-boot-autoconfigure/src/test/java/com/_4point/aem/fluentforms/spring/AemConfigurationTest.java
index b29170da..80e66136 100644
--- a/spring/fluentforms-spring-boot-autoconfigure/src/test/java/com/_4point/aem/fluentforms/spring/AemConfigurationTest.java
+++ b/spring/fluentforms-spring-boot-autoconfigure/src/test/java/com/_4point/aem/fluentforms/spring/AemConfigurationTest.java
@@ -68,6 +68,11 @@ void testGetUrl() {
assertEquals("http://" + EXPECTED_SERVERNAME + ":" + EXPECTED_PORT + "/", underTest.url());
}
+ @Test
+ void testGetSslBundle() {
+ assertEquals("aem", underTest.sslBundle());
+ }
+
@SpringBootTest(classes = {com._4point.aem.fluentforms.spring.AemConfigurationTest.TestApplication.class},
properties = {
"fluentforms.aem.servername=" + EXPECTED_SERVERNAME,
@@ -75,6 +80,7 @@ void testGetUrl() {
"fluentforms.aem.user=" + EXPECTED_USER,
"fluentforms.aem.password=" + EXPECTED_PASSWORD,
"fluentforms.aem.useSsl=true",
+ "fluentforms.aem.sslBundle=notAem"
})
static class AemConfigurationTests2 {
protected static final int EXPECTED_PORT = 80;
@@ -98,7 +104,10 @@ void testGetUrl() {
assertEquals("https://" + EXPECTED_SERVERNAME + "/", underTest.url());
}
-
+ @Test
+ void testGetSslBundle() {
+ assertEquals("notAem", underTest.sslBundle());
+ }
}
@SpringBootApplication
diff --git a/spring/fluentforms-spring-boot-autoconfigure/src/test/java/com/_4point/aem/fluentforms/spring/AemProxyAfSubmissionTest.java b/spring/fluentforms-spring-boot-autoconfigure/src/test/java/com/_4point/aem/fluentforms/spring/AemProxyAfSubmissionTest.java
index c4af4bff..39a739b3 100644
--- a/spring/fluentforms-spring-boot-autoconfigure/src/test/java/com/_4point/aem/fluentforms/spring/AemProxyAfSubmissionTest.java
+++ b/spring/fluentforms-spring-boot-autoconfigure/src/test/java/com/_4point/aem/fluentforms/spring/AemProxyAfSubmissionTest.java
@@ -20,6 +20,7 @@
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.RegisterExtension;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
import org.junit.jupiter.params.provider.EnumSource;
@@ -44,7 +45,8 @@
import com._4point.aem.fluentforms.spring.AemProxyAfSubmission.AfSubmitLocalProcessor.InternalAfSubmitAemProxyProcessor;
import com._4point.aem.fluentforms.spring.AemProxyAfSubmissionTest.AemProxyAfSubmissionTestWithLocalAfSubmitProcessorTest.MockAemProxy;
import com.github.tomakehurst.wiremock.client.WireMock;
-import com.github.tomakehurst.wiremock.junit5.WireMockTest;
+import com.github.tomakehurst.wiremock.core.WireMockConfiguration;
+import com.github.tomakehurst.wiremock.junit5.WireMockExtension;
import jakarta.ws.rs.client.ClientBuilder;
import jakarta.ws.rs.client.Entity;
@@ -99,10 +101,6 @@ public static JakartaRestClient setUpRestClient(int port) {
return getPdfForm;
}
- private static String getBaseUriString(int port) {
- return getBaseUri(port).toString();
- }
-
private static URI getBaseUri(int port) {
return URI.create("http://localhost:" + port);
}
@@ -121,10 +119,9 @@ public static class JerseyConfig extends ResourceConfig {
}
/**
- * Tests the AemAfSubmitProcessor
+ * Tests the AemAfSubmitProcessor. It utilizes an SSL connection to test the SslBundle code.
*
*/
- @WireMockTest(httpPort = 8502)
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT,
classes = {TestApplication.class, JerseyConfig.class, AfSubmitAemProxyProcessor.class},
properties = {
@@ -133,10 +130,26 @@ public static class JerseyConfig extends ResourceConfig {
"fluentforms.aem.port=" + "8502",
"fluentforms.aem.user=admin",
"fluentforms.aem.password=admin",
+ "fluentforms.aem.useSsl=true",
+ "spring.ssl.bundle.jks.aem.truststore.location=file:src/test/resources/aemforms.p12",
+ "spring.ssl.bundle.jks.aem.truststore.password=Pa$$123",
+ "spring.ssl.bundle.jks.aem.truststore.type=PKCS12"
}
)
public static class AemProxyAfSubmissionTestWithAemAfSubmitProcessorTest {
+ @RegisterExtension
+ static WireMockExtension wm1 = WireMockExtension.newInstance()
+ .options(WireMockConfiguration.wireMockConfig().httpsPort(8502)
+ .httpDisabled(true)
+ .keystorePath("src/test/resources/aemforms.p12")
+ .keyManagerPassword("Pa$$123")
+ .keystorePassword("Pa$$123")
+ .keystoreType("PKCS12")
+ )
+ .configureStaticDsl(true) // Use with Static DSL
+ .build();
+
@LocalServerPort
private int port;
diff --git a/spring/fluentforms-spring-boot-autoconfigure/src/test/java/com/_4point/aem/fluentforms/spring/JerseyClientFactoryTest.java b/spring/fluentforms-spring-boot-autoconfigure/src/test/java/com/_4point/aem/fluentforms/spring/JerseyClientFactoryTest.java
new file mode 100644
index 00000000..80cf0470
--- /dev/null
+++ b/spring/fluentforms-spring-boot-autoconfigure/src/test/java/com/_4point/aem/fluentforms/spring/JerseyClientFactoryTest.java
@@ -0,0 +1,73 @@
+package com._4point.aem.fluentforms.spring;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import javax.net.ssl.SSLContext;
+
+import org.glassfish.jersey.client.authentication.HttpAuthenticationFeature;
+import org.glassfish.jersey.media.multipart.MultiPartFeature;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.springframework.boot.ssl.SslBundle;
+import org.springframework.boot.ssl.SslBundles;
+
+import jakarta.ws.rs.client.Client;
+import jakarta.ws.rs.core.Configuration;
+
+@ExtendWith(MockitoExtension.class)
+class JerseyClientFactoryTest {
+
+ @Test
+ void testCreateClientSslBundlesStringStringString(@Mock SslBundles mockSslBundles,
+ @Captor ArgumentCaptor bundleName,
+ @Mock SslBundle mockSslBundle,
+ @Mock SSLContext mockSslContext
+ ) {
+ Mockito.when(mockSslBundles.getBundle(bundleName.capture())).thenReturn(mockSslBundle);
+ Mockito.when(mockSslBundle.createSslContext()).thenReturn(mockSslContext);
+
+ String expectedBundleName = "expectedBundle";
+
+ Client client = JerseyClientFactory.createClient(mockSslBundles, expectedBundleName, "user", "password");
+
+ Configuration configuration = client.getConfiguration();
+ assertAll(
+ ()->assertEquals(expectedBundleName, bundleName.getValue()),
+ ()->assertSame(mockSslContext, client.getSslContext()),
+ ()->assertTrue(configuration.isRegistered(MultiPartFeature.class), "MultiPartFeature should be registered."),
+ ()->assertTrue(configuration.isRegistered(HttpAuthenticationFeature.class), "HttpAuthenticationFeature should be registered.")
+ );
+ }
+
+ @Test
+ void testCreateClientSslBundlesString(@Mock SslBundles mockSslBundles,
+ @Captor ArgumentCaptor bundleName,
+ @Mock SslBundle mockSslBundle,
+ @Mock SSLContext mockSslContext
+ ) {
+ Mockito.when(mockSslBundles.getBundle(bundleName.capture())).thenReturn(mockSslBundle);
+ Mockito.when(mockSslBundle.createSslContext()).thenReturn(mockSslContext);
+
+ String expectedBundleName = "expectedBundle";
+
+ Client client = JerseyClientFactory.createClient(mockSslBundles, expectedBundleName);
+
+ assertAll(
+ ()->assertEquals(expectedBundleName, bundleName.getValue()),
+ ()->assertSame(mockSslContext, client.getSslContext())
+ );
+ }
+
+ @Test
+ void testCreateClient_NullSslBundles_NullString() throws Exception {
+ Client client = JerseyClientFactory.createClient(null, null);
+
+ assertNotNull(client.getSslContext());
+ }
+
+}
diff --git a/spring/fluentforms-spring-boot-autoconfigure/src/test/resources/aemforms.p12 b/spring/fluentforms-spring-boot-autoconfigure/src/test/resources/aemforms.p12
new file mode 100644
index 00000000..2e835490
Binary files /dev/null and b/spring/fluentforms-spring-boot-autoconfigure/src/test/resources/aemforms.p12 differ
diff --git a/spring/fluentforms-spring-boot-starter/pom.xml b/spring/fluentforms-spring-boot-starter/pom.xml
index 6656702f..f2348b1f 100644
--- a/spring/fluentforms-spring-boot-starter/pom.xml
+++ b/spring/fluentforms-spring-boot-starter/pom.xml
@@ -6,7 +6,7 @@
org.springframework.boot
spring-boot-starter-parent
- 3.1.4
+ 3.3.5
fluentforms-spring-boot-starter