From 01290f735515a35025187b9e501841033a769fe2 Mon Sep 17 00:00:00 2001 From: mayur-solace Date: Fri, 26 Jul 2024 14:44:25 -0400 Subject: [PATCH 1/7] DATAGO-81464: OAuth2 conditional auto configuration activation issue fix --- .../SolaceOAuthClientConfiguration.java | 5 +-- .../SolaceOAuthClientConfigurationTest.java | 45 +++++++++++++++++++ .../resources/application-oauthConfigIT.yml | 24 ++++++++++ 3 files changed, 71 insertions(+), 3 deletions(-) create mode 100644 solace-spring-boot-autoconfigure/solace-java-spring-boot-autoconfigure/src/test/java/com/solace/spring/boot/autoconfigure/SolaceOAuthClientConfigurationTest.java create mode 100644 solace-spring-boot-autoconfigure/solace-java-spring-boot-autoconfigure/src/test/resources/application-oauthConfigIT.yml diff --git a/solace-spring-boot-autoconfigure/solace-java-spring-boot-autoconfigure/src/main/java/com/solace/spring/boot/autoconfigure/SolaceOAuthClientConfiguration.java b/solace-spring-boot-autoconfigure/solace-java-spring-boot-autoconfigure/src/main/java/com/solace/spring/boot/autoconfigure/SolaceOAuthClientConfiguration.java index a96a62f..d8656e3 100644 --- a/solace-spring-boot-autoconfigure/solace-java-spring-boot-autoconfigure/src/main/java/com/solace/spring/boot/autoconfigure/SolaceOAuthClientConfiguration.java +++ b/solace-spring-boot-autoconfigure/solace-java-spring-boot-autoconfigure/src/main/java/com/solace/spring/boot/autoconfigure/SolaceOAuthClientConfiguration.java @@ -2,7 +2,7 @@ import com.solacesystems.jcsmp.DefaultSolaceSessionOAuth2TokenProvider; import com.solacesystems.jcsmp.JCSMPProperties; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; import org.springframework.boot.autoconfigure.security.oauth2.client.servlet.OAuth2ClientAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -19,8 +19,7 @@ * 'AUTHENTICATION_SCHEME_OAUTH2'. */ @Configuration -@ConditionalOnProperty(prefix = "solace.java.apiProperties", name = "AUTHENTICATION_SCHEME", - havingValue = "AUTHENTICATION_SCHEME_OAUTH2") +@ConditionalOnExpression("'${solace.java.api-properties.AUTHENTICATION_SCHEME}' == 'AUTHENTICATION_SCHEME_OAUTH2' OR '${solace.java.apiProperties.AUTHENTICATION_SCHEME}' == 'AUTHENTICATION_SCHEME_OAUTH2'") @Import(OAuth2ClientAutoConfiguration.class) public class SolaceOAuthClientConfiguration { diff --git a/solace-spring-boot-autoconfigure/solace-java-spring-boot-autoconfigure/src/test/java/com/solace/spring/boot/autoconfigure/SolaceOAuthClientConfigurationTest.java b/solace-spring-boot-autoconfigure/solace-java-spring-boot-autoconfigure/src/test/java/com/solace/spring/boot/autoconfigure/SolaceOAuthClientConfigurationTest.java new file mode 100644 index 0000000..76b71b2 --- /dev/null +++ b/solace-spring-boot-autoconfigure/solace-java-spring-boot-autoconfigure/src/test/java/com/solace/spring/boot/autoconfigure/SolaceOAuthClientConfigurationTest.java @@ -0,0 +1,45 @@ +package com.solace.spring.boot.autoconfigure; + +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; +import com.solacesystems.jcsmp.SolaceSessionOAuth2TokenProvider; +import org.junit.jupiter.api.Test; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.security.oauth2.client.AuthorizedClientServiceOAuth2AuthorizedClientManager; + +class SolaceOAuthClientConfigurationTest { + + @SpringBootApplication + public static class TestApp { + + } + + @Test + void verifyApplicationContextContainsRequiredBeans() { + try (ConfigurableApplicationContext context = new SpringApplicationBuilder() + .profiles("oauthConfigIT").sources(TestApp.class) + .properties(String.format("%s=%s", "solace.java.api-properties.AUTHENTICATION_SCHEME", + "AUTHENTICATION_SCHEME_OAUTH2")) + .run()) { + assertThat(context.isRunning()).isTrue(); + assertThat(context.getBean(SolaceSessionOAuth2TokenProvider.class)).isNotNull(); + assertThat( + context.getBean(AuthorizedClientServiceOAuth2AuthorizedClientManager.class)).isNotNull(); + } + } + + @Test + void verifyApplicationContextContainsRequiredBeans2() { + try (ConfigurableApplicationContext context = new SpringApplicationBuilder() + .profiles("oauthConfigIT").sources(TestApp.class) + .properties(String.format("%s=%s", "solace.java.apiProperties.AUTHENTICATION_SCHEME", + "AUTHENTICATION_SCHEME_OAUTH2")) + .run()) { + assertThat(context.isRunning()).isTrue(); + assertThat(context.getBean(SolaceSessionOAuth2TokenProvider.class)).isNotNull(); + assertThat( + context.getBean(AuthorizedClientServiceOAuth2AuthorizedClientManager.class)).isNotNull(); + } + } +} \ No newline at end of file diff --git a/solace-spring-boot-autoconfigure/solace-java-spring-boot-autoconfigure/src/test/resources/application-oauthConfigIT.yml b/solace-spring-boot-autoconfigure/solace-java-spring-boot-autoconfigure/src/test/resources/application-oauthConfigIT.yml new file mode 100644 index 0000000..6c3d2a3 --- /dev/null +++ b/solace-spring-boot-autoconfigure/solace-java-spring-boot-autoconfigure/src/test/resources/application-oauthConfigIT.yml @@ -0,0 +1,24 @@ +spring: + security: + oauth2: + client: + registration: + my-oauth2-client: + provider: my-auth-server + client-id: testClientId + client-secret: testClientSecret + authorization-grant-type: client_credentials + scope: openid + provider: + my-auth-server: + token-uri: https://localhost:10443/auth/realms/solace-oauth-resource-server-role/protocol/openid-connect/token + +solace: + java: + host: tcps://localhost:55443 + msgVpn: default + connectRetries: 3 + reconnectRetries: 3 + connectRetriesPerHost: 1 + reconnectRetryWaitInMillis: 2000 + oauth2ClientRegistrationId: my-oauth2-client From 9a867dc3073556087c8af3d75ec7078389485336 Mon Sep 17 00:00:00 2001 From: mayur-solace Date: Fri, 26 Jul 2024 14:54:11 -0400 Subject: [PATCH 2/7] DATAGO-81464: OAuth2 conditional auto configuration activation issue fix --- .../SolaceOAuthClientConfigurationTest.java | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/solace-spring-boot-autoconfigure/solace-java-spring-boot-autoconfigure/src/test/java/com/solace/spring/boot/autoconfigure/SolaceOAuthClientConfigurationTest.java b/solace-spring-boot-autoconfigure/solace-java-spring-boot-autoconfigure/src/test/java/com/solace/spring/boot/autoconfigure/SolaceOAuthClientConfigurationTest.java index 76b71b2..30ca98b 100644 --- a/solace-spring-boot-autoconfigure/solace-java-spring-boot-autoconfigure/src/test/java/com/solace/spring/boot/autoconfigure/SolaceOAuthClientConfigurationTest.java +++ b/solace-spring-boot-autoconfigure/solace-java-spring-boot-autoconfigure/src/test/java/com/solace/spring/boot/autoconfigure/SolaceOAuthClientConfigurationTest.java @@ -1,8 +1,10 @@ package com.solace.spring.boot.autoconfigure; +import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.assertj.core.api.AssertionsForClassTypes.assertThat; import com.solacesystems.jcsmp.SolaceSessionOAuth2TokenProvider; import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.context.ConfigurableApplicationContext; @@ -42,4 +44,20 @@ void verifyApplicationContextContainsRequiredBeans2() { context.getBean(AuthorizedClientServiceOAuth2AuthorizedClientManager.class)).isNotNull(); } } + + @Test + void verifyApplicationContextDoesNotContainOAuth2BeansWhenAuthSchemeIsNotOAuth2() { + try (ConfigurableApplicationContext context = new SpringApplicationBuilder() + .profiles("oauthConfigIT").sources(TestApp.class) + .properties(String.format("%s=%s", "solace.java.apiProperties.AUTHENTICATION_SCHEME", + "AUTHENTICATION_SCHEME_BASIC")) + .run()) { + assertThat(context.isRunning()).isTrue(); + + assertThatThrownBy(() -> context.getBean(SolaceSessionOAuth2TokenProvider.class)) + .isInstanceOf(NoSuchBeanDefinitionException.class); + assertThatThrownBy(() -> context.getBean(AuthorizedClientServiceOAuth2AuthorizedClientManager.class)) + .isInstanceOf(NoSuchBeanDefinitionException.class); + } + } } \ No newline at end of file From 6564bda89a91c060a65f0ebbff8aad74f86ecec1 Mon Sep 17 00:00:00 2001 From: mayur-solace Date: Fri, 26 Jul 2024 16:16:20 -0400 Subject: [PATCH 3/7] DATAGO-81464: Add a custom condition class for OAuth2 auto configuration --- .../SolaceOAuthClientConfiguration.java | 44 +++++++++++++++- .../SolaceOAuthClientConfigurationTest.java | 50 ++++++++++++++++--- .../resources/application-oauthConfigIT.yml | 2 +- 3 files changed, 86 insertions(+), 10 deletions(-) diff --git a/solace-spring-boot-autoconfigure/solace-java-spring-boot-autoconfigure/src/main/java/com/solace/spring/boot/autoconfigure/SolaceOAuthClientConfiguration.java b/solace-spring-boot-autoconfigure/solace-java-spring-boot-autoconfigure/src/main/java/com/solace/spring/boot/autoconfigure/SolaceOAuthClientConfiguration.java index d8656e3..8aedd54 100644 --- a/solace-spring-boot-autoconfigure/solace-java-spring-boot-autoconfigure/src/main/java/com/solace/spring/boot/autoconfigure/SolaceOAuthClientConfiguration.java +++ b/solace-spring-boot-autoconfigure/solace-java-spring-boot-autoconfigure/src/main/java/com/solace/spring/boot/autoconfigure/SolaceOAuthClientConfiguration.java @@ -1,12 +1,19 @@ package com.solace.spring.boot.autoconfigure; +import com.solace.spring.boot.autoconfigure.SolaceOAuthClientConfiguration.OAuth2ClientRegistrationIdCondition; +import com.solace.spring.boot.autoconfigure.SolaceOAuthClientConfiguration.SolaceOAuth2SchemeCondition; import com.solacesystems.jcsmp.DefaultSolaceSessionOAuth2TokenProvider; import com.solacesystems.jcsmp.JCSMPProperties; -import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; +import java.util.Objects; import org.springframework.boot.autoconfigure.security.oauth2.client.servlet.OAuth2ClientAutoConfiguration; +import org.springframework.boot.context.properties.bind.Binder; import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Condition; +import org.springframework.context.annotation.ConditionContext; +import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; +import org.springframework.core.type.AnnotatedTypeMetadata; import org.springframework.security.oauth2.client.AuthorizedClientServiceOAuth2AuthorizedClientManager; import org.springframework.security.oauth2.client.OAuth2AuthorizedClientProvider; import org.springframework.security.oauth2.client.OAuth2AuthorizedClientProviderBuilder; @@ -19,7 +26,7 @@ * 'AUTHENTICATION_SCHEME_OAUTH2'. */ @Configuration -@ConditionalOnExpression("'${solace.java.api-properties.AUTHENTICATION_SCHEME}' == 'AUTHENTICATION_SCHEME_OAUTH2' OR '${solace.java.apiProperties.AUTHENTICATION_SCHEME}' == 'AUTHENTICATION_SCHEME_OAUTH2'") +@Conditional({SolaceOAuth2SchemeCondition.class, OAuth2ClientRegistrationIdCondition.class}) @Import(OAuth2ClientAutoConfiguration.class) public class SolaceOAuthClientConfiguration { @@ -66,4 +73,37 @@ public DefaultSolaceSessionOAuth2TokenProvider solaceSessionOAuth2TokenProvider( return new DefaultSolaceSessionOAuth2TokenProvider(jcsmpProperties, solaceOAuthAuthorizedClientServiceAndManager); } + + + /** + * Condition class to check if the 'solace.java.apiProperties.AUTHENTICATION_SCHEME' property is + * set to 'AUTHENTICATION_SCHEME_OAUTH2'. + */ + static class SolaceOAuth2SchemeCondition implements Condition { + + @Override + public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { + return Binder.get(context.getEnvironment()) + .bind("solace.java", SolaceJavaProperties.class) + .map(SolaceJavaProperties::getApiProperties) + .map(p -> p.get(JCSMPProperties.AUTHENTICATION_SCHEME)) + .map(v -> v.equals(JCSMPProperties.AUTHENTICATION_SCHEME_OAUTH2)) + .orElse(false); + } + } + + /** + * Condition class to check if the 'solace.java.oauth2ClientRegistrationId' property is set. + */ + static class OAuth2ClientRegistrationIdCondition implements Condition { + + @Override + public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { + return Binder.get(context.getEnvironment()) + .bind("solace.java", SolaceJavaProperties.class) + .map(SolaceJavaProperties::getOauth2ClientRegistrationId) + .map(Objects::nonNull) + .orElse(false); + } + } } \ No newline at end of file diff --git a/solace-spring-boot-autoconfigure/solace-java-spring-boot-autoconfigure/src/test/java/com/solace/spring/boot/autoconfigure/SolaceOAuthClientConfigurationTest.java b/solace-spring-boot-autoconfigure/solace-java-spring-boot-autoconfigure/src/test/java/com/solace/spring/boot/autoconfigure/SolaceOAuthClientConfigurationTest.java index 30ca98b..fb0f4f8 100644 --- a/solace-spring-boot-autoconfigure/solace-java-spring-boot-autoconfigure/src/test/java/com/solace/spring/boot/autoconfigure/SolaceOAuthClientConfigurationTest.java +++ b/solace-spring-boot-autoconfigure/solace-java-spring-boot-autoconfigure/src/test/java/com/solace/spring/boot/autoconfigure/SolaceOAuthClientConfigurationTest.java @@ -21,8 +21,9 @@ public static class TestApp { void verifyApplicationContextContainsRequiredBeans() { try (ConfigurableApplicationContext context = new SpringApplicationBuilder() .profiles("oauthConfigIT").sources(TestApp.class) - .properties(String.format("%s=%s", "solace.java.api-properties.AUTHENTICATION_SCHEME", - "AUTHENTICATION_SCHEME_OAUTH2")) + .properties( + String.format("%s=%s", "solace.java.api-properties.AUTHENTICATION_SCHEME", "AUTHENTICATION_SCHEME_OAUTH2"), + String.format("%s=%s", "solace.java.oauth2ClientRegistrationId", "my-oauth2-client")) .run()) { assertThat(context.isRunning()).isTrue(); assertThat(context.getBean(SolaceSessionOAuth2TokenProvider.class)).isNotNull(); @@ -35,8 +36,9 @@ void verifyApplicationContextContainsRequiredBeans() { void verifyApplicationContextContainsRequiredBeans2() { try (ConfigurableApplicationContext context = new SpringApplicationBuilder() .profiles("oauthConfigIT").sources(TestApp.class) - .properties(String.format("%s=%s", "solace.java.apiProperties.AUTHENTICATION_SCHEME", - "AUTHENTICATION_SCHEME_OAUTH2")) + .properties( + String.format("%s=%s", "solace.java.apiProperties.AUTHENTICATION_SCHEME", "AUTHENTICATION_SCHEME_OAUTH2"), + String.format("%s=%s", "solace.java.oauth2ClientRegistrationId", "my-oauth2-client")) .run()) { assertThat(context.isRunning()).isTrue(); assertThat(context.getBean(SolaceSessionOAuth2TokenProvider.class)).isNotNull(); @@ -49,14 +51,48 @@ void verifyApplicationContextContainsRequiredBeans2() { void verifyApplicationContextDoesNotContainOAuth2BeansWhenAuthSchemeIsNotOAuth2() { try (ConfigurableApplicationContext context = new SpringApplicationBuilder() .profiles("oauthConfigIT").sources(TestApp.class) - .properties(String.format("%s=%s", "solace.java.apiProperties.AUTHENTICATION_SCHEME", - "AUTHENTICATION_SCHEME_BASIC")) + .properties( + String.format("%s=%s", "solace.java.apiProperties.AUTHENTICATION_SCHEME", "AUTHENTICATION_SCHEME_BASIC"), + String.format("%s=%s", "solace.java.oauth2ClientRegistrationId", "my-oauth2-client")) .run()) { assertThat(context.isRunning()).isTrue(); assertThatThrownBy(() -> context.getBean(SolaceSessionOAuth2TokenProvider.class)) .isInstanceOf(NoSuchBeanDefinitionException.class); - assertThatThrownBy(() -> context.getBean(AuthorizedClientServiceOAuth2AuthorizedClientManager.class)) + assertThatThrownBy( + () -> context.getBean(AuthorizedClientServiceOAuth2AuthorizedClientManager.class)) + .isInstanceOf(NoSuchBeanDefinitionException.class); + } + } + + @Test + void verifyApplicationContextDoesNotContainOAuth2BeansWhenAuthSchemePropertyNotDefined() { + try (ConfigurableApplicationContext context = new SpringApplicationBuilder() + .profiles("oauthConfigIT").sources(TestApp.class) + .properties(String.format("%s=%s", "solace.java.apiProperties.AUTHENTICATION_SCHEME", "AUTHENTICATION_SCHEME_OAUTH2")) + .run()) { + assertThat(context.isRunning()).isTrue(); + + assertThatThrownBy(() -> context.getBean(SolaceSessionOAuth2TokenProvider.class)) + .isInstanceOf(NoSuchBeanDefinitionException.class); + assertThatThrownBy( + () -> context.getBean(AuthorizedClientServiceOAuth2AuthorizedClientManager.class)) + .isInstanceOf(NoSuchBeanDefinitionException.class); + } + } + + @Test + void verifyApplicationContextDoesNotContainOAuth2BeansWhenClientRegistrationIdNotDefined() { + try (ConfigurableApplicationContext context = new SpringApplicationBuilder() + .profiles("oauthConfigIT").sources(TestApp.class) + .properties(String.format("%s=%s", "solace.java.oauth2ClientRegistrationId", "my-oauth2-client")) + .run()) { + assertThat(context.isRunning()).isTrue(); + + assertThatThrownBy(() -> context.getBean(SolaceSessionOAuth2TokenProvider.class)) + .isInstanceOf(NoSuchBeanDefinitionException.class); + assertThatThrownBy( + () -> context.getBean(AuthorizedClientServiceOAuth2AuthorizedClientManager.class)) .isInstanceOf(NoSuchBeanDefinitionException.class); } } diff --git a/solace-spring-boot-autoconfigure/solace-java-spring-boot-autoconfigure/src/test/resources/application-oauthConfigIT.yml b/solace-spring-boot-autoconfigure/solace-java-spring-boot-autoconfigure/src/test/resources/application-oauthConfigIT.yml index 6c3d2a3..aa81692 100644 --- a/solace-spring-boot-autoconfigure/solace-java-spring-boot-autoconfigure/src/test/resources/application-oauthConfigIT.yml +++ b/solace-spring-boot-autoconfigure/solace-java-spring-boot-autoconfigure/src/test/resources/application-oauthConfigIT.yml @@ -21,4 +21,4 @@ solace: reconnectRetries: 3 connectRetriesPerHost: 1 reconnectRetryWaitInMillis: 2000 - oauth2ClientRegistrationId: my-oauth2-client + From 438a5696c65dac2abf899b617f82db9c7065d396 Mon Sep 17 00:00:00 2001 From: mayur-solace Date: Fri, 26 Jul 2024 14:44:25 -0400 Subject: [PATCH 4/7] DATAGO-81464: OAuth2 conditional auto configuration activation issue fix --- .../SolaceOAuthClientConfigurationTest.java | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/solace-spring-boot-autoconfigure/solace-java-spring-boot-autoconfigure/src/test/java/com/solace/spring/boot/autoconfigure/SolaceOAuthClientConfigurationTest.java b/solace-spring-boot-autoconfigure/solace-java-spring-boot-autoconfigure/src/test/java/com/solace/spring/boot/autoconfigure/SolaceOAuthClientConfigurationTest.java index 30ca98b..76b71b2 100644 --- a/solace-spring-boot-autoconfigure/solace-java-spring-boot-autoconfigure/src/test/java/com/solace/spring/boot/autoconfigure/SolaceOAuthClientConfigurationTest.java +++ b/solace-spring-boot-autoconfigure/solace-java-spring-boot-autoconfigure/src/test/java/com/solace/spring/boot/autoconfigure/SolaceOAuthClientConfigurationTest.java @@ -1,10 +1,8 @@ package com.solace.spring.boot.autoconfigure; -import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.assertj.core.api.AssertionsForClassTypes.assertThat; import com.solacesystems.jcsmp.SolaceSessionOAuth2TokenProvider; import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.context.ConfigurableApplicationContext; @@ -44,20 +42,4 @@ void verifyApplicationContextContainsRequiredBeans2() { context.getBean(AuthorizedClientServiceOAuth2AuthorizedClientManager.class)).isNotNull(); } } - - @Test - void verifyApplicationContextDoesNotContainOAuth2BeansWhenAuthSchemeIsNotOAuth2() { - try (ConfigurableApplicationContext context = new SpringApplicationBuilder() - .profiles("oauthConfigIT").sources(TestApp.class) - .properties(String.format("%s=%s", "solace.java.apiProperties.AUTHENTICATION_SCHEME", - "AUTHENTICATION_SCHEME_BASIC")) - .run()) { - assertThat(context.isRunning()).isTrue(); - - assertThatThrownBy(() -> context.getBean(SolaceSessionOAuth2TokenProvider.class)) - .isInstanceOf(NoSuchBeanDefinitionException.class); - assertThatThrownBy(() -> context.getBean(AuthorizedClientServiceOAuth2AuthorizedClientManager.class)) - .isInstanceOf(NoSuchBeanDefinitionException.class); - } - } } \ No newline at end of file From c656a517718d4f4d92484ed97533ec6674ad5b05 Mon Sep 17 00:00:00 2001 From: mayur-solace Date: Fri, 26 Jul 2024 14:54:11 -0400 Subject: [PATCH 5/7] DATAGO-81464: OAuth2 conditional auto configuration activation issue fix --- .../SolaceOAuthClientConfigurationTest.java | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/solace-spring-boot-autoconfigure/solace-java-spring-boot-autoconfigure/src/test/java/com/solace/spring/boot/autoconfigure/SolaceOAuthClientConfigurationTest.java b/solace-spring-boot-autoconfigure/solace-java-spring-boot-autoconfigure/src/test/java/com/solace/spring/boot/autoconfigure/SolaceOAuthClientConfigurationTest.java index 76b71b2..30ca98b 100644 --- a/solace-spring-boot-autoconfigure/solace-java-spring-boot-autoconfigure/src/test/java/com/solace/spring/boot/autoconfigure/SolaceOAuthClientConfigurationTest.java +++ b/solace-spring-boot-autoconfigure/solace-java-spring-boot-autoconfigure/src/test/java/com/solace/spring/boot/autoconfigure/SolaceOAuthClientConfigurationTest.java @@ -1,8 +1,10 @@ package com.solace.spring.boot.autoconfigure; +import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.assertj.core.api.AssertionsForClassTypes.assertThat; import com.solacesystems.jcsmp.SolaceSessionOAuth2TokenProvider; import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.context.ConfigurableApplicationContext; @@ -42,4 +44,20 @@ void verifyApplicationContextContainsRequiredBeans2() { context.getBean(AuthorizedClientServiceOAuth2AuthorizedClientManager.class)).isNotNull(); } } + + @Test + void verifyApplicationContextDoesNotContainOAuth2BeansWhenAuthSchemeIsNotOAuth2() { + try (ConfigurableApplicationContext context = new SpringApplicationBuilder() + .profiles("oauthConfigIT").sources(TestApp.class) + .properties(String.format("%s=%s", "solace.java.apiProperties.AUTHENTICATION_SCHEME", + "AUTHENTICATION_SCHEME_BASIC")) + .run()) { + assertThat(context.isRunning()).isTrue(); + + assertThatThrownBy(() -> context.getBean(SolaceSessionOAuth2TokenProvider.class)) + .isInstanceOf(NoSuchBeanDefinitionException.class); + assertThatThrownBy(() -> context.getBean(AuthorizedClientServiceOAuth2AuthorizedClientManager.class)) + .isInstanceOf(NoSuchBeanDefinitionException.class); + } + } } \ No newline at end of file From b096daee3e1d2859d7091febaf2320f92a112042 Mon Sep 17 00:00:00 2001 From: mayur-solace Date: Fri, 26 Jul 2024 16:16:20 -0400 Subject: [PATCH 6/7] DATAGO-81464: Add a custom condition class for OAuth2 auto configuration --- .../SolaceOAuthClientConfiguration.java | 44 +++++++++++++++- .../SolaceOAuthClientConfigurationTest.java | 50 ++++++++++++++++--- .../resources/application-oauthConfigIT.yml | 2 +- 3 files changed, 86 insertions(+), 10 deletions(-) diff --git a/solace-spring-boot-autoconfigure/solace-java-spring-boot-autoconfigure/src/main/java/com/solace/spring/boot/autoconfigure/SolaceOAuthClientConfiguration.java b/solace-spring-boot-autoconfigure/solace-java-spring-boot-autoconfigure/src/main/java/com/solace/spring/boot/autoconfigure/SolaceOAuthClientConfiguration.java index d8656e3..8aedd54 100644 --- a/solace-spring-boot-autoconfigure/solace-java-spring-boot-autoconfigure/src/main/java/com/solace/spring/boot/autoconfigure/SolaceOAuthClientConfiguration.java +++ b/solace-spring-boot-autoconfigure/solace-java-spring-boot-autoconfigure/src/main/java/com/solace/spring/boot/autoconfigure/SolaceOAuthClientConfiguration.java @@ -1,12 +1,19 @@ package com.solace.spring.boot.autoconfigure; +import com.solace.spring.boot.autoconfigure.SolaceOAuthClientConfiguration.OAuth2ClientRegistrationIdCondition; +import com.solace.spring.boot.autoconfigure.SolaceOAuthClientConfiguration.SolaceOAuth2SchemeCondition; import com.solacesystems.jcsmp.DefaultSolaceSessionOAuth2TokenProvider; import com.solacesystems.jcsmp.JCSMPProperties; -import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; +import java.util.Objects; import org.springframework.boot.autoconfigure.security.oauth2.client.servlet.OAuth2ClientAutoConfiguration; +import org.springframework.boot.context.properties.bind.Binder; import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Condition; +import org.springframework.context.annotation.ConditionContext; +import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; +import org.springframework.core.type.AnnotatedTypeMetadata; import org.springframework.security.oauth2.client.AuthorizedClientServiceOAuth2AuthorizedClientManager; import org.springframework.security.oauth2.client.OAuth2AuthorizedClientProvider; import org.springframework.security.oauth2.client.OAuth2AuthorizedClientProviderBuilder; @@ -19,7 +26,7 @@ * 'AUTHENTICATION_SCHEME_OAUTH2'. */ @Configuration -@ConditionalOnExpression("'${solace.java.api-properties.AUTHENTICATION_SCHEME}' == 'AUTHENTICATION_SCHEME_OAUTH2' OR '${solace.java.apiProperties.AUTHENTICATION_SCHEME}' == 'AUTHENTICATION_SCHEME_OAUTH2'") +@Conditional({SolaceOAuth2SchemeCondition.class, OAuth2ClientRegistrationIdCondition.class}) @Import(OAuth2ClientAutoConfiguration.class) public class SolaceOAuthClientConfiguration { @@ -66,4 +73,37 @@ public DefaultSolaceSessionOAuth2TokenProvider solaceSessionOAuth2TokenProvider( return new DefaultSolaceSessionOAuth2TokenProvider(jcsmpProperties, solaceOAuthAuthorizedClientServiceAndManager); } + + + /** + * Condition class to check if the 'solace.java.apiProperties.AUTHENTICATION_SCHEME' property is + * set to 'AUTHENTICATION_SCHEME_OAUTH2'. + */ + static class SolaceOAuth2SchemeCondition implements Condition { + + @Override + public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { + return Binder.get(context.getEnvironment()) + .bind("solace.java", SolaceJavaProperties.class) + .map(SolaceJavaProperties::getApiProperties) + .map(p -> p.get(JCSMPProperties.AUTHENTICATION_SCHEME)) + .map(v -> v.equals(JCSMPProperties.AUTHENTICATION_SCHEME_OAUTH2)) + .orElse(false); + } + } + + /** + * Condition class to check if the 'solace.java.oauth2ClientRegistrationId' property is set. + */ + static class OAuth2ClientRegistrationIdCondition implements Condition { + + @Override + public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { + return Binder.get(context.getEnvironment()) + .bind("solace.java", SolaceJavaProperties.class) + .map(SolaceJavaProperties::getOauth2ClientRegistrationId) + .map(Objects::nonNull) + .orElse(false); + } + } } \ No newline at end of file diff --git a/solace-spring-boot-autoconfigure/solace-java-spring-boot-autoconfigure/src/test/java/com/solace/spring/boot/autoconfigure/SolaceOAuthClientConfigurationTest.java b/solace-spring-boot-autoconfigure/solace-java-spring-boot-autoconfigure/src/test/java/com/solace/spring/boot/autoconfigure/SolaceOAuthClientConfigurationTest.java index 30ca98b..fb0f4f8 100644 --- a/solace-spring-boot-autoconfigure/solace-java-spring-boot-autoconfigure/src/test/java/com/solace/spring/boot/autoconfigure/SolaceOAuthClientConfigurationTest.java +++ b/solace-spring-boot-autoconfigure/solace-java-spring-boot-autoconfigure/src/test/java/com/solace/spring/boot/autoconfigure/SolaceOAuthClientConfigurationTest.java @@ -21,8 +21,9 @@ public static class TestApp { void verifyApplicationContextContainsRequiredBeans() { try (ConfigurableApplicationContext context = new SpringApplicationBuilder() .profiles("oauthConfigIT").sources(TestApp.class) - .properties(String.format("%s=%s", "solace.java.api-properties.AUTHENTICATION_SCHEME", - "AUTHENTICATION_SCHEME_OAUTH2")) + .properties( + String.format("%s=%s", "solace.java.api-properties.AUTHENTICATION_SCHEME", "AUTHENTICATION_SCHEME_OAUTH2"), + String.format("%s=%s", "solace.java.oauth2ClientRegistrationId", "my-oauth2-client")) .run()) { assertThat(context.isRunning()).isTrue(); assertThat(context.getBean(SolaceSessionOAuth2TokenProvider.class)).isNotNull(); @@ -35,8 +36,9 @@ void verifyApplicationContextContainsRequiredBeans() { void verifyApplicationContextContainsRequiredBeans2() { try (ConfigurableApplicationContext context = new SpringApplicationBuilder() .profiles("oauthConfigIT").sources(TestApp.class) - .properties(String.format("%s=%s", "solace.java.apiProperties.AUTHENTICATION_SCHEME", - "AUTHENTICATION_SCHEME_OAUTH2")) + .properties( + String.format("%s=%s", "solace.java.apiProperties.AUTHENTICATION_SCHEME", "AUTHENTICATION_SCHEME_OAUTH2"), + String.format("%s=%s", "solace.java.oauth2ClientRegistrationId", "my-oauth2-client")) .run()) { assertThat(context.isRunning()).isTrue(); assertThat(context.getBean(SolaceSessionOAuth2TokenProvider.class)).isNotNull(); @@ -49,14 +51,48 @@ void verifyApplicationContextContainsRequiredBeans2() { void verifyApplicationContextDoesNotContainOAuth2BeansWhenAuthSchemeIsNotOAuth2() { try (ConfigurableApplicationContext context = new SpringApplicationBuilder() .profiles("oauthConfigIT").sources(TestApp.class) - .properties(String.format("%s=%s", "solace.java.apiProperties.AUTHENTICATION_SCHEME", - "AUTHENTICATION_SCHEME_BASIC")) + .properties( + String.format("%s=%s", "solace.java.apiProperties.AUTHENTICATION_SCHEME", "AUTHENTICATION_SCHEME_BASIC"), + String.format("%s=%s", "solace.java.oauth2ClientRegistrationId", "my-oauth2-client")) .run()) { assertThat(context.isRunning()).isTrue(); assertThatThrownBy(() -> context.getBean(SolaceSessionOAuth2TokenProvider.class)) .isInstanceOf(NoSuchBeanDefinitionException.class); - assertThatThrownBy(() -> context.getBean(AuthorizedClientServiceOAuth2AuthorizedClientManager.class)) + assertThatThrownBy( + () -> context.getBean(AuthorizedClientServiceOAuth2AuthorizedClientManager.class)) + .isInstanceOf(NoSuchBeanDefinitionException.class); + } + } + + @Test + void verifyApplicationContextDoesNotContainOAuth2BeansWhenAuthSchemePropertyNotDefined() { + try (ConfigurableApplicationContext context = new SpringApplicationBuilder() + .profiles("oauthConfigIT").sources(TestApp.class) + .properties(String.format("%s=%s", "solace.java.apiProperties.AUTHENTICATION_SCHEME", "AUTHENTICATION_SCHEME_OAUTH2")) + .run()) { + assertThat(context.isRunning()).isTrue(); + + assertThatThrownBy(() -> context.getBean(SolaceSessionOAuth2TokenProvider.class)) + .isInstanceOf(NoSuchBeanDefinitionException.class); + assertThatThrownBy( + () -> context.getBean(AuthorizedClientServiceOAuth2AuthorizedClientManager.class)) + .isInstanceOf(NoSuchBeanDefinitionException.class); + } + } + + @Test + void verifyApplicationContextDoesNotContainOAuth2BeansWhenClientRegistrationIdNotDefined() { + try (ConfigurableApplicationContext context = new SpringApplicationBuilder() + .profiles("oauthConfigIT").sources(TestApp.class) + .properties(String.format("%s=%s", "solace.java.oauth2ClientRegistrationId", "my-oauth2-client")) + .run()) { + assertThat(context.isRunning()).isTrue(); + + assertThatThrownBy(() -> context.getBean(SolaceSessionOAuth2TokenProvider.class)) + .isInstanceOf(NoSuchBeanDefinitionException.class); + assertThatThrownBy( + () -> context.getBean(AuthorizedClientServiceOAuth2AuthorizedClientManager.class)) .isInstanceOf(NoSuchBeanDefinitionException.class); } } diff --git a/solace-spring-boot-autoconfigure/solace-java-spring-boot-autoconfigure/src/test/resources/application-oauthConfigIT.yml b/solace-spring-boot-autoconfigure/solace-java-spring-boot-autoconfigure/src/test/resources/application-oauthConfigIT.yml index 6c3d2a3..aa81692 100644 --- a/solace-spring-boot-autoconfigure/solace-java-spring-boot-autoconfigure/src/test/resources/application-oauthConfigIT.yml +++ b/solace-spring-boot-autoconfigure/solace-java-spring-boot-autoconfigure/src/test/resources/application-oauthConfigIT.yml @@ -21,4 +21,4 @@ solace: reconnectRetries: 3 connectRetriesPerHost: 1 reconnectRetryWaitInMillis: 2000 - oauth2ClientRegistrationId: my-oauth2-client + From b805f2704255ac7d03749785d518920feb9ca0d2 Mon Sep 17 00:00:00 2001 From: mayur-solace Date: Fri, 26 Jul 2024 16:32:05 -0400 Subject: [PATCH 7/7] DATAGO-81464: Changed as per review comments --- .../boot/autoconfigure/SolaceOAuthClientConfiguration.java | 3 +-- .../autoconfigure/SolaceOAuthClientConfigurationTest.java | 6 +++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/solace-spring-boot-autoconfigure/solace-java-spring-boot-autoconfigure/src/main/java/com/solace/spring/boot/autoconfigure/SolaceOAuthClientConfiguration.java b/solace-spring-boot-autoconfigure/solace-java-spring-boot-autoconfigure/src/main/java/com/solace/spring/boot/autoconfigure/SolaceOAuthClientConfiguration.java index 8aedd54..a2892b0 100644 --- a/solace-spring-boot-autoconfigure/solace-java-spring-boot-autoconfigure/src/main/java/com/solace/spring/boot/autoconfigure/SolaceOAuthClientConfiguration.java +++ b/solace-spring-boot-autoconfigure/solace-java-spring-boot-autoconfigure/src/main/java/com/solace/spring/boot/autoconfigure/SolaceOAuthClientConfiguration.java @@ -102,8 +102,7 @@ public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) return Binder.get(context.getEnvironment()) .bind("solace.java", SolaceJavaProperties.class) .map(SolaceJavaProperties::getOauth2ClientRegistrationId) - .map(Objects::nonNull) - .orElse(false); + .isBound(); } } } \ No newline at end of file diff --git a/solace-spring-boot-autoconfigure/solace-java-spring-boot-autoconfigure/src/test/java/com/solace/spring/boot/autoconfigure/SolaceOAuthClientConfigurationTest.java b/solace-spring-boot-autoconfigure/solace-java-spring-boot-autoconfigure/src/test/java/com/solace/spring/boot/autoconfigure/SolaceOAuthClientConfigurationTest.java index fb0f4f8..4d0d93b 100644 --- a/solace-spring-boot-autoconfigure/solace-java-spring-boot-autoconfigure/src/test/java/com/solace/spring/boot/autoconfigure/SolaceOAuthClientConfigurationTest.java +++ b/solace-spring-boot-autoconfigure/solace-java-spring-boot-autoconfigure/src/test/java/com/solace/spring/boot/autoconfigure/SolaceOAuthClientConfigurationTest.java @@ -38,7 +38,7 @@ void verifyApplicationContextContainsRequiredBeans2() { .profiles("oauthConfigIT").sources(TestApp.class) .properties( String.format("%s=%s", "solace.java.apiProperties.AUTHENTICATION_SCHEME", "AUTHENTICATION_SCHEME_OAUTH2"), - String.format("%s=%s", "solace.java.oauth2ClientRegistrationId", "my-oauth2-client")) + String.format("%s=%s", "solace.java.oauth2-client-registration-id", "my-oauth2-client")) .run()) { assertThat(context.isRunning()).isTrue(); assertThat(context.getBean(SolaceSessionOAuth2TokenProvider.class)).isNotNull(); @@ -69,7 +69,7 @@ void verifyApplicationContextDoesNotContainOAuth2BeansWhenAuthSchemeIsNotOAuth2( void verifyApplicationContextDoesNotContainOAuth2BeansWhenAuthSchemePropertyNotDefined() { try (ConfigurableApplicationContext context = new SpringApplicationBuilder() .profiles("oauthConfigIT").sources(TestApp.class) - .properties(String.format("%s=%s", "solace.java.apiProperties.AUTHENTICATION_SCHEME", "AUTHENTICATION_SCHEME_OAUTH2")) + .properties(String.format("%s=%s", "solace.java.oauth2ClientRegistrationId", "my-oauth2-client")) .run()) { assertThat(context.isRunning()).isTrue(); @@ -85,7 +85,7 @@ void verifyApplicationContextDoesNotContainOAuth2BeansWhenAuthSchemePropertyNotD void verifyApplicationContextDoesNotContainOAuth2BeansWhenClientRegistrationIdNotDefined() { try (ConfigurableApplicationContext context = new SpringApplicationBuilder() .profiles("oauthConfigIT").sources(TestApp.class) - .properties(String.format("%s=%s", "solace.java.oauth2ClientRegistrationId", "my-oauth2-client")) + .properties(String.format("%s=%s", "solace.java.apiProperties.AUTHENTICATION_SCHEME", "AUTHENTICATION_SCHEME_OAUTH2")) .run()) { assertThat(context.isRunning()).isTrue();