pull/10504/merge
Phillip Webb 7 years ago
parent 99101bae5c
commit 9192444c31

@ -63,7 +63,7 @@ import static org.mockito.Mockito.verify;
*/
public abstract class AbstractWebEndpointIntegrationTests<T extends ConfigurableApplicationContext> {
private static final Duration TIMEOUT = Duration.ofSeconds(30);
private static final Duration TIMEOUT = Duration.ofMinutes(2);
private final Class<?> exporterConfiguration;

@ -30,7 +30,8 @@ import org.springframework.core.type.AnnotationMetadata;
* @author Stephane Nicoll
*/
@Configuration
@Import({ DataSourceInitializerInvoker.class, DataSourceInitializationConfiguration.Registrar.class })
@Import({ DataSourceInitializerInvoker.class,
DataSourceInitializationConfiguration.Registrar.class })
class DataSourceInitializationConfiguration {
/**

@ -119,7 +119,6 @@ class DataSourceInitializer {
String username = this.properties.getDataUsername();
String password = this.properties.getDataPassword();
runScripts(scripts, username, password);
}
}

@ -37,7 +37,8 @@ import org.springframework.context.ApplicationListener;
class DataSourceInitializerInvoker
implements ApplicationListener<DataSourceSchemaCreatedEvent>, InitializingBean {
private static final Log logger = LogFactory.getLog(DataSourceInitializerInvoker.class);
private static final Log logger = LogFactory
.getLog(DataSourceInitializerInvoker.class);
private final ObjectProvider<DataSource> dataSource;
@ -50,8 +51,7 @@ class DataSourceInitializerInvoker
private boolean initialized;
DataSourceInitializerInvoker(ObjectProvider<DataSource> dataSource,
DataSourceProperties properties,
ApplicationContext applicationContext) {
DataSourceProperties properties, ApplicationContext applicationContext) {
this.dataSource = dataSource;
this.properties = properties;
this.applicationContext = applicationContext;
@ -63,24 +63,27 @@ class DataSourceInitializerInvoker
if (initializer != null) {
boolean schemaCreated = this.dataSourceInitializer.createSchema();
if (schemaCreated) {
try {
this.applicationContext
.publishEvent(new DataSourceSchemaCreatedEvent(
initializer.getDataSource()));
// The listener might not be registered yet, so don't rely on it.
if (!this.initialized) {
this.dataSourceInitializer.initSchema();
this.initialized = true;
}
}
catch (IllegalStateException ex) {
logger.warn("Could not send event to complete DataSource initialization ("
+ ex.getMessage() + ")");
}
initialize(initializer);
}
}
}
private void initialize(DataSourceInitializer initializer) {
try {
this.applicationContext.publishEvent(
new DataSourceSchemaCreatedEvent(initializer.getDataSource()));
// The listener might not be registered yet, so don't rely on it.
if (!this.initialized) {
this.dataSourceInitializer.initSchema();
this.initialized = true;
}
}
catch (IllegalStateException ex) {
logger.warn("Could not send event to complete DataSource initialization ("
+ ex.getMessage() + ")");
}
}
@Override
public void onApplicationEvent(DataSourceSchemaCreatedEvent event) {
// NOTE the event can happen more than once and

@ -26,7 +26,8 @@ import org.springframework.context.ApplicationEvent;
* are executed or when Hibernate initializes the database.
*
* @author Dave Syer
* @since 1.1.0
* @author Stephane Nicoll
* @since 2.0.0
*/
@SuppressWarnings("serial")
public class DataSourceSchemaCreatedEvent extends ApplicationEvent {

@ -53,7 +53,7 @@ import org.springframework.util.ClassUtils;
@Conditional(HibernateEntityManagerCondition.class)
@EnableConfigurationProperties(JpaProperties.class)
@AutoConfigureAfter({ DataSourceAutoConfiguration.class })
@Import(JpaHibernateConfiguration.class)
@Import(HibernateJpaConfiguration.class)
public class HibernateJpaAutoConfiguration {
@Order(Ordered.HIGHEST_PRECEDENCE + 20)

@ -50,10 +50,9 @@ import org.springframework.util.ClassUtils;
*/
@Configuration
@ConditionalOnSingleCandidate(DataSource.class)
public class JpaHibernateConfiguration extends JpaBaseConfiguration {
class HibernateJpaConfiguration extends JpaBaseConfiguration {
private static final Log logger = LogFactory
.getLog(JpaHibernateConfiguration.class);
private static final Log logger = LogFactory.getLog(HibernateJpaConfiguration.class);
private static final String JTA_PLATFORM = "hibernate.transaction.jta.platform";
@ -74,8 +73,7 @@ public class JpaHibernateConfiguration extends JpaBaseConfiguration {
private final HibernateDefaultDdlAutoProvider defaultDdlAutoProvider;
public JpaHibernateConfiguration(DataSource dataSource,
JpaProperties jpaProperties,
HibernateJpaConfiguration(DataSource dataSource, JpaProperties jpaProperties,
ObjectProvider<JtaTransactionManager> jtaTransactionManager,
ObjectProvider<TransactionManagerCustomizers> transactionManagerCustomizers,
ObjectProvider<List<SchemaManagementProvider>> providers) {

@ -99,7 +99,8 @@ public enum CommonOAuth2Provider {
protected final ClientRegistration.Builder getBuilder(String registrationId,
ClientAuthenticationMethod method, String redirectUri) {
ClientRegistration.Builder builder = new ClientRegistration.Builder(registrationId);
ClientRegistration.Builder builder = new ClientRegistration.Builder(
registrationId);
builder.clientAuthenticationMethod(method);
builder.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE);
builder.redirectUri(redirectUri);

@ -42,4 +42,3 @@ import org.springframework.security.oauth2.client.registration.ClientRegistratio
public class OAuth2ClientAutoConfiguration {
}

@ -98,8 +98,7 @@ public class OAuth2ClientProperties {
private ClientAuthenticationMethod clientAuthenticationMethod;
/**
* Authorization grant type. May be left bank then using a pre-defined
* provider.
* Authorization grant type. May be left bank then using a pre-defined provider.
*/
private AuthorizationGrantType authorizationGrantType;
@ -204,8 +203,8 @@ public class OAuth2ClientProperties {
private String userInfoUri;
/**
* Name of the attribute that will be used to extract the username from the
* call to 'userInfoUri'.
* Name of the attribute that will be used to extract the username from the call
* to 'userInfoUri'.
*/
private String userNameAttribute;

@ -51,10 +51,9 @@ final class OAuth2ClientPropertiesRegistrationAdapter {
return clientRegistrations;
}
private static ClientRegistration getClientRegistration(String registrationId, Registration properties,
Map<String, Provider> providers) {
Builder builder = getBuilder(registrationId, properties.getProvider(),
providers);
private static ClientRegistration getClientRegistration(String registrationId,
Registration properties, Map<String, Provider> providers) {
Builder builder = getBuilder(registrationId, properties.getProvider(), providers);
copyIfNotNull(properties::getClientId, builder::clientId);
copyIfNotNull(properties::getClientSecret, builder::clientSecret);
copyIfNotNull(properties::getClientAuthenticationMethod,
@ -75,7 +74,8 @@ final class OAuth2ClientPropertiesRegistrationAdapter {
if (provider == null && !providers.containsKey(providerId)) {
throw new IllegalStateException("Unknown provider ID '" + providerId + "'");
}
Builder builder = (provider != null ? provider.getBuilder(registrationId) : new Builder(registrationId));
Builder builder = (provider != null ? provider.getBuilder(registrationId)
: new Builder(registrationId));
if (providers.containsKey(providerId)) {
return getBuilder(builder, providers.get(providerId));
}

@ -54,8 +54,7 @@ class OAuth2ClientRegistrationRepositoryConfiguration {
private final OAuth2ClientProperties properties;
OAuth2ClientRegistrationRepositoryConfiguration(
OAuth2ClientProperties properties) {
OAuth2ClientRegistrationRepositoryConfiguration(OAuth2ClientProperties properties) {
this.properties = properties;
}
@ -103,4 +102,3 @@ class OAuth2ClientRegistrationRepositoryConfiguration {
}
}

@ -36,7 +36,8 @@ import org.springframework.security.oauth2.client.registration.ClientRegistratio
class OAuth2WebSecurityConfiguration {
@Configuration
static class OAuth2WebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {
static class OAuth2WebSecurityConfigurationAdapter
extends WebSecurityConfigurerAdapter {
private final ClientRegistrationRepository clientRegistrationRepository;
@ -47,15 +48,10 @@ class OAuth2WebSecurityConfiguration {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest()
.authenticated().and()
.oauth2Login()
http.authorizeRequests().anyRequest().authenticated().and().oauth2Login()
.clients(this.clientRegistrationRepository);
}
}
}

@ -44,86 +44,97 @@ import static org.assertj.core.api.Assertions.assertThat;
public class MessageSourceAutoConfigurationTests {
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(
MessageSourceAutoConfiguration.class));
.withConfiguration(
AutoConfigurations.of(MessageSourceAutoConfiguration.class));
@Test
public void testDefaultMessageSource() {
this.contextRunner.run((context) ->
assertThat(context.getMessage("foo", null, "Foo message", Locale.UK))
this.contextRunner.run((context) -> assertThat(
context.getMessage("foo", null, "Foo message", Locale.UK))
.isEqualTo("Foo message"));
}
@Test
public void testMessageSourceCreated() {
this.contextRunner.withPropertyValues("spring.messages.basename:test/messages")
.run((context) -> assertThat(context.getMessage(
"foo", null, "Foo message", Locale.UK)).isEqualTo("bar"));
.run((context) -> assertThat(
context.getMessage("foo", null, "Foo message", Locale.UK))
.isEqualTo("bar"));
}
@Test
public void testEncodingWorks() {
this.contextRunner.withPropertyValues("spring.messages.basename:test/swedish")
.run((context) -> assertThat(context.getMessage(
"foo", null, "Foo message", Locale.UK)).isEqualTo(
"Some text with some swedish öäå!"));
.run((context) -> assertThat(
context.getMessage("foo", null, "Foo message", Locale.UK))
.isEqualTo("Some text with some swedish öäå!"));
}
@Test
public void testMultipleMessageSourceCreated() {
this.contextRunner.withPropertyValues(
"spring.messages.basename:test/messages,test/messages2").run((context) -> {
assertThat(context.getMessage("foo", null, "Foo message", Locale.UK))
.isEqualTo("bar");
assertThat(context.getMessage("foo-foo", null, "Foo-Foo message", Locale.UK))
.isEqualTo("bar-bar");
});
this.contextRunner
.withPropertyValues(
"spring.messages.basename:test/messages,test/messages2")
.run((context) -> {
assertThat(context.getMessage("foo", null, "Foo message", Locale.UK))
.isEqualTo("bar");
assertThat(context.getMessage("foo-foo", null, "Foo-Foo message",
Locale.UK)).isEqualTo("bar-bar");
});
}
@Test
public void testBadEncoding() {
// Bad encoding just means the messages are ignored
this.contextRunner.withPropertyValues("spring.messages.encoding:rubbish")
.run((context) -> assertThat(context.getMessage(
"foo", null, "blah", Locale.UK)).isEqualTo("blah"));
.run((context) -> assertThat(
context.getMessage("foo", null, "blah", Locale.UK))
.isEqualTo("blah"));
}
@Test
@Ignore("Expected to fail per gh-1075")
public void testMessageSourceFromPropertySourceAnnotation() {
this.contextRunner.withUserConfiguration(Config.class).run((context) ->
assertThat(context.getMessage("foo", null, "Foo message", Locale.UK))
.isEqualTo("bar"));
this.contextRunner.withUserConfiguration(Config.class)
.run((context) -> assertThat(
context.getMessage("foo", null, "Foo message", Locale.UK))
.isEqualTo("bar"));
}
@Test
public void testFallbackDefault() {
this.contextRunner.withPropertyValues("spring.messages.basename:test/messages")
.run((context) -> assertThat(isFallbackToSystemLocale(
context.getBean(MessageSource.class))).isTrue());
.run((context) -> assertThat(
isFallbackToSystemLocale(context.getBean(MessageSource.class)))
.isTrue());
}
@Test
public void testFallbackTurnOff() {
this.contextRunner.withPropertyValues("spring.messages.basename:test/messages",
"spring.messages.fallback-to-system-locale:false").run((context) ->
assertThat(isFallbackToSystemLocale(context.getBean(MessageSource.class)))
.isFalse());
this.contextRunner
.withPropertyValues("spring.messages.basename:test/messages",
"spring.messages.fallback-to-system-locale:false")
.run((context) -> assertThat(
isFallbackToSystemLocale(context.getBean(MessageSource.class)))
.isFalse());
}
@Test
public void testFormatMessageDefault() {
this.contextRunner.withPropertyValues("spring.messages.basename:test/messages")
.run((context) -> assertThat(isAlwaysUseMessageFormat(
context.getBean(MessageSource.class))).isFalse());
.run((context) -> assertThat(
isAlwaysUseMessageFormat(context.getBean(MessageSource.class)))
.isFalse());
}
@Test
public void testFormatMessageOn() throws Exception {
this.contextRunner.withPropertyValues("spring.messages.basename:test/messages",
"spring.messages.always-use-message-format:true").run((context) ->
assertThat(isAlwaysUseMessageFormat(context.getBean(MessageSource.class)))
.isTrue());
this.contextRunner
.withPropertyValues("spring.messages.basename:test/messages",
"spring.messages.always-use-message-format:true")
.run((context) -> assertThat(
isAlwaysUseMessageFormat(context.getBean(MessageSource.class)))
.isTrue());
}
private boolean isFallbackToSystemLocale(MessageSource messageSource) {
@ -139,16 +150,19 @@ public class MessageSourceAutoConfigurationTests {
@Test
public void testUseCodeAsDefaultMessageDefault() {
this.contextRunner.withPropertyValues("spring.messages.basename:test/messages")
.run((context) -> assertThat(isUseCodeAsDefaultMessage(
context.getBean(MessageSource.class))).isFalse());
.run((context) -> assertThat(
isUseCodeAsDefaultMessage(context.getBean(MessageSource.class)))
.isFalse());
}
@Test
public void testUseCodeAsDefaultMessageOn() {
this.contextRunner.withPropertyValues("spring.messages.basename:test/messages",
"spring.messages.use-code-as-default-message:true").run((context) ->
assertThat(isUseCodeAsDefaultMessage(
context.getBean(MessageSource.class))).isTrue());
this.contextRunner
.withPropertyValues("spring.messages.basename:test/messages",
"spring.messages.use-code-as-default-message:true")
.run((context) -> assertThat(
isUseCodeAsDefaultMessage(context.getBean(MessageSource.class)))
.isTrue());
}
private boolean isUseCodeAsDefaultMessage(MessageSource messageSource) {
@ -167,8 +181,9 @@ public class MessageSourceAutoConfigurationTests {
public void existingMessageSourceInParentIsIgnored() {
this.contextRunner.run((parent) -> this.contextRunner.withParent(parent)
.withPropertyValues("spring.messages.basename:test/messages")
.run((context) -> assertThat(context.getMessage(
"foo", null, "Foo message", Locale.UK)).isEqualTo("bar")));
.run((context) -> assertThat(
context.getMessage("foo", null, "Foo message", Locale.UK))
.isEqualTo("bar")));
}
@Configuration

@ -114,8 +114,8 @@ public class HttpMessageConvertersTests {
@Override
protected List<HttpMessageConverter<?>> postProcessConverters(
List<HttpMessageConverter<?>> converters) {
converters.removeIf((
converter) -> converter instanceof MappingJackson2XmlHttpMessageConverter);
converters.removeIf(
MappingJackson2XmlHttpMessageConverter.class::isInstance);
return converters;
}
@ -141,8 +141,8 @@ public class HttpMessageConvertersTests {
@Override
protected List<HttpMessageConverter<?>> postProcessPartConverters(
List<HttpMessageConverter<?>> converters) {
converters.removeIf((
converter) -> converter instanceof MappingJackson2XmlHttpMessageConverter);
converters.removeIf(
MappingJackson2XmlHttpMessageConverter.class::isInstance);
return converters;
}

@ -58,16 +58,14 @@ import static org.junit.Assert.fail;
public class DataSourceInitializerInvokerTests {
private ApplicationContextRunner contextRunner = new ApplicationContextRunner()
.withConfiguration(
AutoConfigurations.of(DataSourceAutoConfiguration.class))
.withConfiguration(AutoConfigurations.of(DataSourceAutoConfiguration.class))
.withPropertyValues("spring.datasource.initialize=false",
"spring.datasource.url:jdbc:hsqldb:mem:init-"
+ UUID.randomUUID().toString());
@Test
public void dataSourceInitialized() {
this.contextRunner
.withPropertyValues("spring.datasource.initialize:true")
this.contextRunner.withPropertyValues("spring.datasource.initialize:true")
.run((context) -> {
assertThat(context).hasSingleBean(DataSource.class);
DataSource dataSource = context.getBean(DataSource.class);
@ -76,11 +74,9 @@ public class DataSourceInitializerInvokerTests {
});
}
@Test
public void initializationAppliesToCustomDataSource() {
this.contextRunner
.withUserConfiguration(OneDataSource.class)
this.contextRunner.withUserConfiguration(OneDataSource.class)
.withPropertyValues("spring.datasource.initialize:true")
.run((context) -> {
assertThat(context).hasSingleBean(DataSource.class);
@ -88,11 +84,10 @@ public class DataSourceInitializerInvokerTests {
});
}
private void assertDataSourceIsInitialized(DataSource dataSource) {
JdbcOperations template = new JdbcTemplate(dataSource);
assertThat(template.queryForObject("SELECT COUNT(*) from BAR",
Integer.class)).isEqualTo(1);
assertThat(template.queryForObject("SELECT COUNT(*) from BAR", Integer.class))
.isEqualTo(1);
}
@Test
@ -133,13 +128,11 @@ public class DataSourceInitializerInvokerTests {
@Test
public void dataSourceInitializedWithExplicitSqlScriptEncoding() {
this.contextRunner
.withPropertyValues("spring.datasource.initialize:true",
"spring.datasource.sqlScriptEncoding:UTF-8",
"spring.datasource.schema:"
+ getRelativeLocationFor("encoding-schema.sql"),
"spring.datasource.data:"
+ getRelativeLocationFor("encoding-data.sql"))
this.contextRunner.withPropertyValues("spring.datasource.initialize:true",
"spring.datasource.sqlScriptEncoding:UTF-8",
"spring.datasource.schema:"
+ getRelativeLocationFor("encoding-schema.sql"),
"spring.datasource.data:" + getRelativeLocationFor("encoding-data.sql"))
.run((context) -> {
DataSource dataSource = context.getBean(DataSource.class);
assertThat(dataSource).isInstanceOf(HikariDataSource.class);
@ -161,15 +154,14 @@ public class DataSourceInitializerInvokerTests {
@Test
public void initializationDoesNotApplyWithSeveralDataSources() {
this.contextRunner
.withUserConfiguration(TwoDataSources.class)
this.contextRunner.withUserConfiguration(TwoDataSources.class)
.withPropertyValues("spring.datasource.initialize:true")
.run((context) -> {
assertThat(context.getBeanNamesForType(DataSource.class)).hasSize(2);
assertDataSourceNotInitialized(context.getBean(
"oneDataSource", DataSource.class));
assertDataSourceNotInitialized(context.getBean(
"twoDataSource", DataSource.class));
assertDataSourceNotInitialized(
context.getBean("oneDataSource", DataSource.class));
assertDataSourceNotInitialized(
context.getBean("twoDataSource", DataSource.class));
});
}
@ -185,8 +177,7 @@ public class DataSourceInitializerInvokerTests {
private void assertDataSourceNotInitialized(DataSource dataSource) {
JdbcOperations template = new JdbcTemplate(dataSource);
try {
template.queryForObject("SELECT COUNT(*) from BAR",
Integer.class);
template.queryForObject("SELECT COUNT(*) from BAR", Integer.class);
fail("Query should have failed as BAR table does not exist");
}
catch (BadSqlGrammarException ex) {
@ -199,16 +190,13 @@ public class DataSourceInitializerInvokerTests {
@Test
public void dataSourceInitializedWithSchemaCredentials() {
this.contextRunner
.withPropertyValues("spring.datasource.initialize:true",
"spring.datasource.sqlScriptEncoding:UTF-8",
"spring.datasource.schema:"
+ getRelativeLocationFor("encoding-schema.sql"),
"spring.datasource.data:"
+ getRelativeLocationFor("encoding-data.sql"),
"spring.datasource.schema-username:admin",
"spring.datasource.schema-password:admin")
.run((context) -> {
this.contextRunner.withPropertyValues("spring.datasource.initialize:true",
"spring.datasource.sqlScriptEncoding:UTF-8",
"spring.datasource.schema:"
+ getRelativeLocationFor("encoding-schema.sql"),
"spring.datasource.data:" + getRelativeLocationFor("encoding-data.sql"),
"spring.datasource.schema-username:admin",
"spring.datasource.schema-password:admin").run((context) -> {
assertThat(context).hasFailed();
assertThat(context.getStartupFailure())
.isInstanceOf(BeanCreationException.class);
@ -217,16 +205,13 @@ public class DataSourceInitializerInvokerTests {
@Test
public void dataSourceInitializedWithDataCredentials() {
this.contextRunner
.withPropertyValues("spring.datasource.initialize:true",
"spring.datasource.sqlScriptEncoding:UTF-8",
"spring.datasource.schema:"
+ getRelativeLocationFor("encoding-schema.sql"),
"spring.datasource.data:"
+ getRelativeLocationFor("encoding-data.sql"),
"spring.datasource.data-username:admin",
"spring.datasource.data-password:admin")
.run((context) -> {
this.contextRunner.withPropertyValues("spring.datasource.initialize:true",
"spring.datasource.sqlScriptEncoding:UTF-8",
"spring.datasource.schema:"
+ getRelativeLocationFor("encoding-schema.sql"),
"spring.datasource.data:" + getRelativeLocationFor("encoding-data.sql"),
"spring.datasource.data-username:admin",
"spring.datasource.data-password:admin").run((context) -> {
assertThat(context).hasFailed();
assertThat(context.getStartupFailure())
.isInstanceOf(BeanCreationException.class);

@ -67,10 +67,8 @@ public class KafkaAutoConfigurationTests {
@Test
public void consumerProperties() {
this.contextRunner
.withUserConfiguration(TestConfiguration.class)
.withPropertyValues(
"spring.kafka.bootstrap-servers=foo:1234",
this.contextRunner.withUserConfiguration(TestConfiguration.class)
.withPropertyValues("spring.kafka.bootstrap-servers=foo:1234",
"spring.kafka.properties.foo=bar",
"spring.kafka.properties.baz=qux",
"spring.kafka.properties.foo.bar.baz=qux.fiz.buz",
@ -90,53 +88,62 @@ public class KafkaAutoConfigurationTests {
"spring.kafka.consumer.group-id=bar",
"spring.kafka.consumer.heartbeat-interval=234",
"spring.kafka.consumer.key-deserializer = org.apache.kafka.common.serialization.LongDeserializer",
"spring.kafka.consumer.value-deserializer = org.apache.kafka.common.serialization.IntegerDeserializer"
).run((context) -> {
DefaultKafkaConsumerFactory<?, ?> consumerFactory = context
.getBean(DefaultKafkaConsumerFactory.class);
Map<String, Object> configs = consumerFactory.getConfigurationProperties();
// common
assertThat(configs.get(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG))
.isEqualTo(Collections.singletonList("foo:1234"));
assertThat(configs.get(SslConfigs.SSL_KEY_PASSWORD_CONFIG)).isEqualTo("p1");
assertThat((String) configs.get(SslConfigs.SSL_KEYSTORE_LOCATION_CONFIG))
.endsWith(File.separator + "ksLoc");
assertThat(configs.get(SslConfigs.SSL_KEYSTORE_PASSWORD_CONFIG)).isEqualTo("p2");
assertThat((String) configs.get(SslConfigs.SSL_TRUSTSTORE_LOCATION_CONFIG))
.endsWith(File.separator + "tsLoc");
assertThat(configs.get(SslConfigs.SSL_TRUSTSTORE_PASSWORD_CONFIG))
.isEqualTo("p3");
// consumer
assertThat(configs.get(ConsumerConfig.CLIENT_ID_CONFIG)).isEqualTo("ccid"); // override
assertThat(configs.get(ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG))
.isEqualTo(Boolean.FALSE);
assertThat(configs.get(ConsumerConfig.AUTO_COMMIT_INTERVAL_MS_CONFIG))
.isEqualTo(123);
assertThat(configs.get(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG))
.isEqualTo("earliest");
assertThat(configs.get(ConsumerConfig.FETCH_MAX_WAIT_MS_CONFIG)).isEqualTo(456);
assertThat(configs.get(ConsumerConfig.FETCH_MIN_BYTES_CONFIG)).isEqualTo(789);
assertThat(configs.get(ConsumerConfig.GROUP_ID_CONFIG)).isEqualTo("bar");
assertThat(configs.get(ConsumerConfig.HEARTBEAT_INTERVAL_MS_CONFIG))
.isEqualTo(234);
assertThat(configs.get(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG))
.isEqualTo(LongDeserializer.class);
assertThat(configs.get(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG))
.isEqualTo(IntegerDeserializer.class);
assertThat(configs.get(ConsumerConfig.MAX_POLL_RECORDS_CONFIG)).isEqualTo(42);
assertThat(configs.get("foo")).isEqualTo("bar");
assertThat(configs.get("baz")).isEqualTo("qux");
assertThat(configs.get("foo.bar.baz")).isEqualTo("qux.fiz.buz");
assertThat(configs.get("fiz.buz")).isEqualTo("fix.fox");
});
"spring.kafka.consumer.value-deserializer = org.apache.kafka.common.serialization.IntegerDeserializer")
.run((context) -> {
DefaultKafkaConsumerFactory<?, ?> consumerFactory = context
.getBean(DefaultKafkaConsumerFactory.class);
Map<String, Object> configs = consumerFactory
.getConfigurationProperties();
// common
assertThat(configs.get(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG))
.isEqualTo(Collections.singletonList("foo:1234"));
assertThat(configs.get(SslConfigs.SSL_KEY_PASSWORD_CONFIG))
.isEqualTo("p1");
assertThat(
(String) configs.get(SslConfigs.SSL_KEYSTORE_LOCATION_CONFIG))
.endsWith(File.separator + "ksLoc");
assertThat(configs.get(SslConfigs.SSL_KEYSTORE_PASSWORD_CONFIG))
.isEqualTo("p2");
assertThat((String) configs
.get(SslConfigs.SSL_TRUSTSTORE_LOCATION_CONFIG))
.endsWith(File.separator + "tsLoc");
assertThat(configs.get(SslConfigs.SSL_TRUSTSTORE_PASSWORD_CONFIG))
.isEqualTo("p3");
// consumer
assertThat(configs.get(ConsumerConfig.CLIENT_ID_CONFIG))
.isEqualTo("ccid"); // override
assertThat(configs.get(ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG))
.isEqualTo(Boolean.FALSE);
assertThat(configs.get(ConsumerConfig.AUTO_COMMIT_INTERVAL_MS_CONFIG))
.isEqualTo(123);
assertThat(configs.get(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG))
.isEqualTo("earliest");
assertThat(configs.get(ConsumerConfig.FETCH_MAX_WAIT_MS_CONFIG))
.isEqualTo(456);
assertThat(configs.get(ConsumerConfig.FETCH_MIN_BYTES_CONFIG))
.isEqualTo(789);
assertThat(configs.get(ConsumerConfig.GROUP_ID_CONFIG))
.isEqualTo("bar");
assertThat(configs.get(ConsumerConfig.HEARTBEAT_INTERVAL_MS_CONFIG))
.isEqualTo(234);
assertThat(configs.get(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG))
.isEqualTo(LongDeserializer.class);
assertThat(
configs.get(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG))
.isEqualTo(IntegerDeserializer.class);
assertThat(configs.get(ConsumerConfig.MAX_POLL_RECORDS_CONFIG))
.isEqualTo(42);
assertThat(configs.get("foo")).isEqualTo("bar");
assertThat(configs.get("baz")).isEqualTo("qux");
assertThat(configs.get("foo.bar.baz")).isEqualTo("qux.fiz.buz");
assertThat(configs.get("fiz.buz")).isEqualTo("fix.fox");
});
}
@Test
public void producerProperties() {
this.contextRunner
.withUserConfiguration(TestConfiguration.class)
.withPropertyValues(
"spring.kafka.clientId=cid",
this.contextRunner.withUserConfiguration(TestConfiguration.class)
.withPropertyValues("spring.kafka.clientId=cid",
"spring.kafka.properties.foo.bar.baz=qux.fiz.buz",
"spring.kafka.producer.acks=all",
"spring.kafka.producer.batch-size=20",
@ -152,71 +159,89 @@ public class KafkaAutoConfigurationTests {
"spring.kafka.producer.ssl.keystore-password=p5",
"spring.kafka.producer.ssl.truststore-location=classpath:tsLocP",
"spring.kafka.producer.ssl.truststore-password=p6",
"spring.kafka.producer.value-serializer=org.apache.kafka.common.serialization.IntegerSerializer"
).run((context) -> {
DefaultKafkaProducerFactory<?, ?> producerFactory = context
.getBean(DefaultKafkaProducerFactory.class);
Map<String, Object> configs = producerFactory.getConfigurationProperties();
// common
assertThat(configs.get(ProducerConfig.CLIENT_ID_CONFIG)).isEqualTo("cid");
// producer
assertThat(configs.get(ProducerConfig.ACKS_CONFIG)).isEqualTo("all");
assertThat(configs.get(ProducerConfig.BATCH_SIZE_CONFIG)).isEqualTo(20);
assertThat(configs.get(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG))
.isEqualTo(Collections.singletonList("bar:1234")); // override
assertThat(configs.get(ProducerConfig.BUFFER_MEMORY_CONFIG)).isEqualTo(12345L);
assertThat(configs.get(ProducerConfig.COMPRESSION_TYPE_CONFIG)).isEqualTo("gzip");
assertThat(configs.get(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG))
.isEqualTo(LongSerializer.class);
assertThat(configs.get(SslConfigs.SSL_KEY_PASSWORD_CONFIG)).isEqualTo("p4");
assertThat((String) configs.get(SslConfigs.SSL_KEYSTORE_LOCATION_CONFIG))
.endsWith(File.separator + "ksLocP");
assertThat(configs.get(SslConfigs.SSL_KEYSTORE_PASSWORD_CONFIG)).isEqualTo("p5");
assertThat((String) configs.get(SslConfigs.SSL_TRUSTSTORE_LOCATION_CONFIG))
.endsWith(File.separator + "tsLocP");
assertThat(configs.get(SslConfigs.SSL_TRUSTSTORE_PASSWORD_CONFIG))
.isEqualTo("p6");
assertThat(configs.get(ProducerConfig.RETRIES_CONFIG)).isEqualTo(2);
assertThat(configs.get(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG))
.isEqualTo(IntegerSerializer.class);
assertThat(context.getBeansOfType(KafkaJaasLoginModuleInitializer.class))
.isEmpty();
assertThat(configs.get("foo.bar.baz")).isEqualTo("qux.fiz.buz");
assertThat(configs.get("fiz.buz")).isEqualTo("fix.fox");
});
"spring.kafka.producer.value-serializer=org.apache.kafka.common.serialization.IntegerSerializer")
.run((context) -> {
DefaultKafkaProducerFactory<?, ?> producerFactory = context
.getBean(DefaultKafkaProducerFactory.class);
Map<String, Object> configs = producerFactory
.getConfigurationProperties();
// common
assertThat(configs.get(ProducerConfig.CLIENT_ID_CONFIG))
.isEqualTo("cid");
// producer
assertThat(configs.get(ProducerConfig.ACKS_CONFIG)).isEqualTo("all");
assertThat(configs.get(ProducerConfig.BATCH_SIZE_CONFIG))
.isEqualTo(20);
assertThat(configs.get(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG))
.isEqualTo(Collections.singletonList("bar:1234")); // override
assertThat(configs.get(ProducerConfig.BUFFER_MEMORY_CONFIG))
.isEqualTo(12345L);
assertThat(configs.get(ProducerConfig.COMPRESSION_TYPE_CONFIG))
.isEqualTo("gzip");
assertThat(configs.get(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG))
.isEqualTo(LongSerializer.class);
assertThat(configs.get(SslConfigs.SSL_KEY_PASSWORD_CONFIG))
.isEqualTo("p4");
assertThat(
(String) configs.get(SslConfigs.SSL_KEYSTORE_LOCATION_CONFIG))
.endsWith(File.separator + "ksLocP");
assertThat(configs.get(SslConfigs.SSL_KEYSTORE_PASSWORD_CONFIG))
.isEqualTo("p5");
assertThat((String) configs
.get(SslConfigs.SSL_TRUSTSTORE_LOCATION_CONFIG))
.endsWith(File.separator + "tsLocP");
assertThat(configs.get(SslConfigs.SSL_TRUSTSTORE_PASSWORD_CONFIG))
.isEqualTo("p6");
assertThat(configs.get(ProducerConfig.RETRIES_CONFIG)).isEqualTo(2);
assertThat(configs.get(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG))
.isEqualTo(IntegerSerializer.class);
assertThat(
context.getBeansOfType(KafkaJaasLoginModuleInitializer.class))
.isEmpty();
assertThat(configs.get("foo.bar.baz")).isEqualTo("qux.fiz.buz");
assertThat(configs.get("fiz.buz")).isEqualTo("fix.fox");
});
}
@Test
public void adminProperties() {
this.contextRunner.withPropertyValues("spring.kafka.clientId=cid",
"spring.kafka.properties.foo.bar.baz=qux.fiz.buz",
"spring.kafka.admin.fail-fast=true",
"spring.kafka.admin.properties.fiz.buz=fix.fox",
"spring.kafka.admin.ssl.key-password=p4",
"spring.kafka.admin.ssl.keystore-location=classpath:ksLocP",
"spring.kafka.admin.ssl.keystore-password=p5",
"spring.kafka.admin.ssl.truststore-location=classpath:tsLocP",
"spring.kafka.admin.ssl.truststore-password=p6").run((context) -> {
KafkaAdmin admin = context.getBean(KafkaAdmin.class);
Map<String, Object> configs = admin.getConfig();
// common
assertThat(configs.get(AdminClientConfig.CLIENT_ID_CONFIG)).isEqualTo("cid");
// admin
assertThat(configs.get(SslConfigs.SSL_KEY_PASSWORD_CONFIG)).isEqualTo("p4");
assertThat((String) configs.get(SslConfigs.SSL_KEYSTORE_LOCATION_CONFIG))
.endsWith(File.separator + "ksLocP");
assertThat(configs.get(SslConfigs.SSL_KEYSTORE_PASSWORD_CONFIG)).isEqualTo("p5");
assertThat((String) configs.get(SslConfigs.SSL_TRUSTSTORE_LOCATION_CONFIG))
.endsWith(File.separator + "tsLocP");
assertThat(configs.get(SslConfigs.SSL_TRUSTSTORE_PASSWORD_CONFIG))
.isEqualTo("p6");
assertThat(context.getBeansOfType(KafkaJaasLoginModuleInitializer.class))
.isEmpty();
assertThat(configs.get("foo.bar.baz")).isEqualTo("qux.fiz.buz");
assertThat(configs.get("fiz.buz")).isEqualTo("fix.fox");
assertThat(KafkaTestUtils.getPropertyValue(admin, "fatalIfBrokerNotAvailable",
Boolean.class)).isTrue();
});
this.contextRunner
.withPropertyValues("spring.kafka.clientId=cid",
"spring.kafka.properties.foo.bar.baz=qux.fiz.buz",
"spring.kafka.admin.fail-fast=true",
"spring.kafka.admin.properties.fiz.buz=fix.fox",
"spring.kafka.admin.ssl.key-password=p4",
"spring.kafka.admin.ssl.keystore-location=classpath:ksLocP",
"spring.kafka.admin.ssl.keystore-password=p5",
"spring.kafka.admin.ssl.truststore-location=classpath:tsLocP",
"spring.kafka.admin.ssl.truststore-password=p6")
.run((context) -> {
KafkaAdmin admin = context.getBean(KafkaAdmin.class);
Map<String, Object> configs = admin.getConfig();
// common
assertThat(configs.get(AdminClientConfig.CLIENT_ID_CONFIG))
.isEqualTo("cid");
// admin
assertThat(configs.get(SslConfigs.SSL_KEY_PASSWORD_CONFIG))
.isEqualTo("p4");
assertThat(
(String) configs.get(SslConfigs.SSL_KEYSTORE_LOCATION_CONFIG))
.endsWith(File.separator + "ksLocP");
assertThat(configs.get(SslConfigs.SSL_KEYSTORE_PASSWORD_CONFIG))
.isEqualTo("p5");
assertThat((String) configs
.get(SslConfigs.SSL_TRUSTSTORE_LOCATION_CONFIG))
.endsWith(File.separator + "tsLocP");
assertThat(configs.get(SslConfigs.SSL_TRUSTSTORE_PASSWORD_CONFIG))
.isEqualTo("p6");
assertThat(
context.getBeansOfType(KafkaJaasLoginModuleInitializer.class))
.isEmpty();
assertThat(configs.get("foo.bar.baz")).isEqualTo("qux.fiz.buz");
assertThat(configs.get("fiz.buz")).isEqualTo("fix.fox");
assertThat(KafkaTestUtils.getPropertyValue(admin,
"fatalIfBrokerNotAvailable", Boolean.class)).isTrue();
});
}
@SuppressWarnings("unchecked")
@ -233,48 +258,56 @@ public class KafkaAutoConfigurationTests {
"spring.kafka.jaas.enabled=true",
"spring.kafka.jaas.login-module=foo",
"spring.kafka.jaas.control-flag=REQUISITE",
"spring.kafka.jaas.options.useKeyTab=true"
).run((context) -> {
DefaultKafkaProducerFactory<?, ?> producerFactory = context
.getBean(DefaultKafkaProducerFactory.class);
DefaultKafkaConsumerFactory<?, ?> consumerFactory = context
.getBean(DefaultKafkaConsumerFactory.class);
KafkaTemplate<?, ?> kafkaTemplate = context.getBean(KafkaTemplate.class);
KafkaListenerContainerFactory<?> kafkaListenerContainerFactory = context
.getBean(KafkaListenerContainerFactory.class);
assertThat(kafkaTemplate.getMessageConverter()).isInstanceOf(
MessagingMessageConverter.class);
assertThat(new DirectFieldAccessor(kafkaTemplate)
.getPropertyValue("producerFactory")).isEqualTo(producerFactory);
assertThat(kafkaTemplate.getDefaultTopic()).isEqualTo("testTopic");
DirectFieldAccessor dfa = new DirectFieldAccessor(kafkaListenerContainerFactory);
assertThat(dfa.getPropertyValue("consumerFactory")).isEqualTo(consumerFactory);
assertThat(dfa.getPropertyValue("containerProperties.ackMode"))
.isEqualTo(AckMode.MANUAL);
assertThat(dfa.getPropertyValue("containerProperties.ackCount")).isEqualTo(123);
assertThat(dfa.getPropertyValue("containerProperties.ackTime")).isEqualTo(456L);
assertThat(dfa.getPropertyValue("concurrency")).isEqualTo(3);
assertThat(dfa.getPropertyValue("containerProperties.pollTimeout"))
.isEqualTo(2000L);
assertThat(dfa.getPropertyValue("batchListener")).isEqualTo(true);
assertThat(context.getBeansOfType(KafkaJaasLoginModuleInitializer.class))
.hasSize(1);
KafkaJaasLoginModuleInitializer jaas = context
.getBean(KafkaJaasLoginModuleInitializer.class);
dfa = new DirectFieldAccessor(jaas);
assertThat(dfa.getPropertyValue("loginModule")).isEqualTo("foo");
assertThat(dfa.getPropertyValue("controlFlag"))
.isEqualTo(AppConfigurationEntry.LoginModuleControlFlag.REQUISITE);
assertThat(((Map<String, String>) dfa.getPropertyValue("options")))
.containsExactly(entry("useKeyTab", "true"));
});
"spring.kafka.jaas.options.useKeyTab=true")
.run((context) -> {
DefaultKafkaProducerFactory<?, ?> producerFactory = context
.getBean(DefaultKafkaProducerFactory.class);
DefaultKafkaConsumerFactory<?, ?> consumerFactory = context
.getBean(DefaultKafkaConsumerFactory.class);
KafkaTemplate<?, ?> kafkaTemplate = context
.getBean(KafkaTemplate.class);
KafkaListenerContainerFactory<?> kafkaListenerContainerFactory = context
.getBean(KafkaListenerContainerFactory.class);
assertThat(kafkaTemplate.getMessageConverter())
.isInstanceOf(MessagingMessageConverter.class);
assertThat(new DirectFieldAccessor(kafkaTemplate)
.getPropertyValue("producerFactory"))
.isEqualTo(producerFactory);
assertThat(kafkaTemplate.getDefaultTopic()).isEqualTo("testTopic");
DirectFieldAccessor dfa = new DirectFieldAccessor(
kafkaListenerContainerFactory);
assertThat(dfa.getPropertyValue("consumerFactory"))
.isEqualTo(consumerFactory);
assertThat(dfa.getPropertyValue("containerProperties.ackMode"))
.isEqualTo(AckMode.MANUAL);
assertThat(dfa.getPropertyValue("containerProperties.ackCount"))
.isEqualTo(123);
assertThat(dfa.getPropertyValue("containerProperties.ackTime"))
.isEqualTo(456L);
assertThat(dfa.getPropertyValue("concurrency")).isEqualTo(3);
assertThat(dfa.getPropertyValue("containerProperties.pollTimeout"))
.isEqualTo(2000L);
assertThat(dfa.getPropertyValue("batchListener")).isEqualTo(true);
assertThat(
context.getBeansOfType(KafkaJaasLoginModuleInitializer.class))
.hasSize(1);
KafkaJaasLoginModuleInitializer jaas = context
.getBean(KafkaJaasLoginModuleInitializer.class);
dfa = new DirectFieldAccessor(jaas);
assertThat(dfa.getPropertyValue("loginModule")).isEqualTo("foo");
assertThat(dfa.getPropertyValue("controlFlag")).isEqualTo(
AppConfigurationEntry.LoginModuleControlFlag.REQUISITE);
assertThat(((Map<String, String>) dfa.getPropertyValue("options")))
.containsExactly(entry("useKeyTab", "true"));
});
}
@Test
public void testKafkaTemplateRecordMessageConverters() {
this.contextRunner.withUserConfiguration(MessageConverterConfiguration.class)
.run((context) -> {
KafkaTemplate<?, ?> kafkaTemplate = context.getBean(KafkaTemplate.class);
KafkaTemplate<?, ?> kafkaTemplate = context
.getBean(KafkaTemplate.class);
assertThat(kafkaTemplate.getMessageConverter())
.isSameAs(context.getBean("myMessageConverter"));
});

@ -113,13 +113,13 @@ public abstract class AbstractJpaAutoConfigurationTests {
@Test
public void configuredWithSingleCandidateDataSource() {
this.contextRunner.withUserConfiguration(
TestTwoDataSourcesAndPrimaryConfiguration.class).run((context) -> {
assertThat(context).getBeans(DataSource.class).hasSize(2);
assertThat(context).hasSingleBean(JpaTransactionManager.class);
assertThat(context).hasSingleBean(EntityManagerFactory.class);
});
this.contextRunner
.withUserConfiguration(TestTwoDataSourcesAndPrimaryConfiguration.class)
.run((context) -> {
assertThat(context).getBeans(DataSource.class).hasSize(2);
assertThat(context).hasSingleBean(JpaTransactionManager.class);
assertThat(context).hasSingleBean(EntityManagerFactory.class);
});
}
@Test
@ -240,18 +240,16 @@ public abstract class AbstractJpaAutoConfigurationTests {
});
}
@Configuration
protected static class TestTwoDataSourcesConfiguration {
@Bean
public DataSource firstDataSource() {
public DataSource firstDataSource() {
return createRandomDataSource();
}
@Bean
public DataSource secondDataSource() {
public DataSource secondDataSource() {
return createRandomDataSource();
}
@ -267,12 +265,12 @@ public abstract class AbstractJpaAutoConfigurationTests {
@Bean
@Primary
public DataSource firstDataSource() {
public DataSource firstDataSource() {
return createRandomDataSource();
}
@Bean
public DataSource secondDataSource() {
public DataSource secondDataSource() {
return createRandomDataSource();
}

@ -75,12 +75,12 @@ public class HibernateJpaAutoConfigurationTests
contextRunner().withPropertyValues("spring.datasource.data:classpath:/city.sql",
// Missing:
"spring.datasource.schema:classpath:/ddl.sql").run((context) -> {
assertThat(context).hasFailed();
assertThat(context.getStartupFailure())
.hasMessageContaining("ddl.sql");
assertThat(context.getStartupFailure())
.hasMessageContaining("spring.datasource.schema");
});
assertThat(context).hasFailed();
assertThat(context.getStartupFailure())
.hasMessageContaining("ddl.sql");
assertThat(context.getStartupFailure())
.hasMessageContaining("spring.datasource.schema");
});
}
@Test
@ -105,7 +105,7 @@ public class HibernateJpaAutoConfigurationTests
"spring.datasource.data:classpath:/city.sql")
.run((context) -> assertThat(
context.getBean(TestInitializedJpaConfiguration.class).called)
.isTrue());
.isTrue());
}
@Test
@ -164,7 +164,7 @@ public class HibernateJpaAutoConfigurationTests
.getJpaPropertyMap();
assertThat((String) jpaPropertyMap
.get("hibernate.transaction.jta.platform"))
.isEqualTo(TestJtaPlatform.class.getName());
.isEqualTo(TestJtaPlatform.class.getName());
});
}
@ -183,13 +183,15 @@ public class HibernateJpaAutoConfigurationTests
@Test
public void autoConfigurationBacksOffWithSeveralDataSources() {
contextRunner().withConfiguration(
AutoConfigurations.of(DataSourceTransactionManagerAutoConfiguration.class,
XADataSourceAutoConfiguration.class, JtaAutoConfiguration.class)
).withUserConfiguration(TestTwoDataSourcesConfiguration.class).run((context) -> {
assertThat(context).hasNotFailed();
assertThat(context).doesNotHaveBean(EntityManagerFactory.class);
});
contextRunner()
.withConfiguration(AutoConfigurations.of(
DataSourceTransactionManagerAutoConfiguration.class,
XADataSourceAutoConfiguration.class, JtaAutoConfiguration.class))
.withUserConfiguration(TestTwoDataSourcesConfiguration.class)
.run((context) -> {
assertThat(context).hasNotFailed();
assertThat(context).doesNotHaveBean(EntityManagerFactory.class);
});
}
@Configuration

@ -116,7 +116,8 @@ public class CommonOAuth2ProviderTests {
assertThat(providerDetails.getAuthorizationUri())
.isEqualTo("http://example.com/auth");
assertThat(providerDetails.getTokenUri()).isEqualTo("http://example.com/token");
assertThat(providerDetails.getUserInfoEndpoint().getUri()).isEqualTo("http://example.com/info");
assertThat(providerDetails.getUserInfoEndpoint().getUri())
.isEqualTo("http://example.com/info");
assertThat(providerDetails.getUserInfoEndpoint().getUserNameAttributeName())
.isEqualTo(null);
assertThat(providerDetails.getJwkSetUri()).isNull();
@ -136,9 +137,7 @@ public class CommonOAuth2ProviderTests {
}
private Builder builder(CommonOAuth2Provider provider) {
return provider.getBuilder("123")
.clientId("abcd")
.clientSecret("secret");
return provider.getBuilder("123").clientId("abcd").clientSecret("secret");
}
}

@ -67,7 +67,8 @@ public class OAuth2ClientPropertiesRegistrationAdapterTests {
assertThat(adaptedProvider.getAuthorizationUri())
.isEqualTo("http://example.com/auth");
assertThat(adaptedProvider.getTokenUri()).isEqualTo("http://example.com/token");
assertThat(adaptedProvider.getUserInfoEndpoint().getUri()).isEqualTo("http://example.com/info");
assertThat(adaptedProvider.getUserInfoEndpoint().getUri())
.isEqualTo("http://example.com/info");
assertThat(adaptedProvider.getJwkSetUri()).isEqualTo("http://example.com/jkw");
assertThat(adapted.getRegistrationId()).isEqualTo("registration");
assertThat(adapted.getClientId()).isEqualTo("clientId");

@ -64,4 +64,5 @@ public class OAuth2ClientPropertiesTests {
this.thrown.expectMessage("Provider must not be empty.");
this.properties.validate();
}
}

@ -36,20 +36,29 @@ public class OAuth2ClientRegistrationRepositoryConfigurationTests {
private static final String REGISTRATION_PREFIX = "spring.security.oauth2.client.registration";
@Test
public void clientRegistrationRepositoryBeanShouldNotBeCreatedWhenPropertiesAbsent() throws Exception {
this.contextRunner.withUserConfiguration(OAuth2ClientRegistrationRepositoryConfiguration.class)
.run(context -> assertThat(context).doesNotHaveBean(ClientRegistrationRepository.class));
public void clientRegistrationRepositoryBeanShouldNotBeCreatedWhenPropertiesAbsent()
throws Exception {
this.contextRunner
.withUserConfiguration(
OAuth2ClientRegistrationRepositoryConfiguration.class)
.run(context -> assertThat(context)
.doesNotHaveBean(ClientRegistrationRepository.class));
}
@Test
public void clientRegistrationRepositoryBeanShouldBeCreatedWhenPropertiesPresent() throws Exception {
this.contextRunner.withUserConfiguration(OAuth2ClientRegistrationRepositoryConfiguration.class)
public void clientRegistrationRepositoryBeanShouldBeCreatedWhenPropertiesPresent()
throws Exception {
this.contextRunner
.withUserConfiguration(
OAuth2ClientRegistrationRepositoryConfiguration.class)
.withPropertyValues(REGISTRATION_PREFIX + ".foo.client-id=abcd",
REGISTRATION_PREFIX + ".foo.client-secret=secret",
REGISTRATION_PREFIX + ".foo.provider=github")
.run(context -> {
ClientRegistrationRepository repository = context.getBean(ClientRegistrationRepository.class);
ClientRegistration registration = repository.findByRegistrationId("foo");
ClientRegistrationRepository repository = context
.getBean(ClientRegistrationRepository.class);
ClientRegistration registration = repository
.findByRegistrationId("foo");
assertThat(registration).isNotNull();
assertThat(registration.getClientSecret()).isEqualTo("secret");
});

@ -55,59 +55,80 @@ public class OAuth2WebSecurityConfigurationTests {
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner();
@Test
@SuppressWarnings("unchecked")
public void securityConfigurerRegistersClientRegistrations() throws Exception {
this.contextRunner.withUserConfiguration(
ClientRepositoryConfiguration.class, OAuth2WebSecurityConfiguration.class)
.run(context -> {
ClientRegistrationRepository expected = context.getBean(ClientRegistrationRepository.class);
ClientRegistrationRepository actual = (ClientRegistrationRepository) ReflectionTestUtils.getField(
getAuthCodeFilters(context).get(0), "clientRegistrationRepository");
assertThat(isEqual(expected.findByRegistrationId("first"),
actual.findByRegistrationId("first"))).isTrue();
assertThat(isEqual(expected.findByRegistrationId("second"),
actual.findByRegistrationId("second"))).isTrue();
});
this.contextRunner.withUserConfiguration(ClientRepositoryConfiguration.class,
OAuth2WebSecurityConfiguration.class).run((context) -> {
ClientRegistrationRepository expected = context
.getBean(ClientRegistrationRepository.class);
ClientRegistrationRepository actual = (ClientRegistrationRepository) ReflectionTestUtils
.getField(getAuthCodeFilters(context).get(0),
"clientRegistrationRepository");
assertThat(isEqual(expected.findByRegistrationId("first"),
actual.findByRegistrationId("first"))).isTrue();
assertThat(isEqual(expected.findByRegistrationId("second"),
actual.findByRegistrationId("second"))).isTrue();
});
}
@Test
public void securityConfigurerBacksOffWhenClientRegistrationBeanAbsent() throws Exception {
this.contextRunner.withUserConfiguration(TestConfig.class, OAuth2WebSecurityConfiguration.class)
.run(context -> assertThat(getAuthCodeFilters(context)).isEmpty());
public void securityConfigurerBacksOffWhenClientRegistrationBeanAbsent()
throws Exception {
this.contextRunner
.withUserConfiguration(TestConfig.class,
OAuth2WebSecurityConfiguration.class)
.run((context) -> assertThat(getAuthCodeFilters(context)).isEmpty());
}
@Test
public void securityConfigurerBacksOffWhenOtherWebSecurityAdapterPresent() throws Exception {
this.contextRunner.withUserConfiguration(TestWebSecurityConfigurerConfig.class, OAuth2WebSecurityConfiguration.class)
.run(context -> assertThat(getAuthCodeFilters(context)).isEmpty());
public void securityConfigurerBacksOffWhenOtherWebSecurityAdapterPresent()
throws Exception {
this.contextRunner
.withUserConfiguration(TestWebSecurityConfigurerConfig.class,
OAuth2WebSecurityConfiguration.class)
.run((context) -> assertThat(getAuthCodeFilters(context)).isEmpty());
}
@SuppressWarnings("unchecked")
@SuppressWarnings({ "unchecked", "cast" })
private List<Filter> getAuthCodeFilters(AssertableApplicationContext context) {
FilterChainProxy filterChain = (FilterChainProxy) context.getBean("springSecurityFilterChain");
FilterChainProxy filterChain = (FilterChainProxy) context
.getBean("springSecurityFilterChain");
List<SecurityFilterChain> filterChains = filterChain.getFilterChains();
List<Filter> filters = (List<Filter>) ReflectionTestUtils.getField(((List) filterChains).get(0), "filters");
List<Filter> oauth2Filters = filters.stream().filter(
f -> f instanceof AuthorizationCodeAuthenticationProcessingFilter ||
f instanceof AuthorizationCodeRequestRedirectFilter).collect(Collectors.toList());
return oauth2Filters.stream().filter(f -> f instanceof AuthorizationCodeAuthenticationProcessingFilter)
List<Filter> filters = (List<Filter>) ReflectionTestUtils
.getField(filterChains.get(0), "filters");
List<Filter> oauth2Filters = filters.stream()
.filter((
f) -> f instanceof AuthorizationCodeAuthenticationProcessingFilter
|| f instanceof AuthorizationCodeRequestRedirectFilter)
.collect(Collectors.toList());
return oauth2Filters.stream()
.filter((
f) -> f instanceof AuthorizationCodeAuthenticationProcessingFilter)
.collect(Collectors.toList());
}
private boolean isEqual(ClientRegistration reg1, ClientRegistration reg2) {
boolean result = ObjectUtils.nullSafeEquals(reg1.getClientId(), reg2.getClientId());
result = result && ObjectUtils.nullSafeEquals(reg1.getClientName(), reg2.getClientName());
result = result && ObjectUtils.nullSafeEquals(reg1.getClientSecret(), reg2.getClientSecret());
boolean result = ObjectUtils.nullSafeEquals(reg1.getClientId(),
reg2.getClientId());
result = result
&& ObjectUtils.nullSafeEquals(reg1.getClientName(), reg2.getClientName());
result = result && ObjectUtils.nullSafeEquals(reg1.getClientSecret(),
reg2.getClientSecret());
result = result && ObjectUtils.nullSafeEquals(reg1.getScope(), reg2.getScope());
result = result && ObjectUtils.nullSafeEquals(reg1.getRedirectUri(), reg2.getRedirectUri());
result = result && ObjectUtils.nullSafeEquals(reg1.getRegistrationId(), reg2.getRegistrationId());
result = result && ObjectUtils.nullSafeEquals(reg1.getAuthorizationGrantType(), reg2.getAuthorizationGrantType());
result = result && ObjectUtils.nullSafeEquals(reg1.getProviderDetails().getAuthorizationUri(),
result = result && ObjectUtils.nullSafeEquals(reg1.getRedirectUri(),
reg2.getRedirectUri());
result = result && ObjectUtils.nullSafeEquals(reg1.getRegistrationId(),
reg2.getRegistrationId());
result = result && ObjectUtils.nullSafeEquals(reg1.getAuthorizationGrantType(),
reg2.getAuthorizationGrantType());
result = result && ObjectUtils.nullSafeEquals(
reg1.getProviderDetails().getAuthorizationUri(),
reg2.getProviderDetails().getAuthorizationUri());
result = result && ObjectUtils.nullSafeEquals(reg1.getProviderDetails().getUserInfoEndpoint(),
result = result && ObjectUtils.nullSafeEquals(
reg1.getProviderDetails().getUserInfoEndpoint(),
reg2.getProviderDetails().getUserInfoEndpoint());
result = result && ObjectUtils.nullSafeEquals(reg1.getProviderDetails().getTokenUri(),
reg2.getProviderDetails().getTokenUri());
result = result
&& ObjectUtils.nullSafeEquals(reg1.getProviderDetails().getTokenUri(),
reg2.getProviderDetails().getTokenUri());
return result;
}
@ -136,16 +157,14 @@ public class OAuth2WebSecurityConfigurationTests {
private ClientRegistration getClientRegistration(String id, String userInfoUri) {
ClientRegistration.Builder builder = new ClientRegistration.Builder(id);
builder.clientName("foo")
.clientId("foo")
.clientAuthenticationMethod(org.springframework.security.oauth2.core.ClientAuthenticationMethod.BASIC)
builder.clientName("foo").clientId("foo")
.clientAuthenticationMethod(
org.springframework.security.oauth2.core.ClientAuthenticationMethod.BASIC)
.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
.scope("read")
.clientSecret("secret")
.scope("read").clientSecret("secret")
.redirectUri("http://redirect-uri.com")
.authorizationUri("http://authorization-uri.com")
.tokenUri("http://token-uri.com")
.userInfoUri(userInfoUri)
.tokenUri("http://token-uri.com").userInfoUri(userInfoUri)
.userNameAttributeName("login");
return builder.build();
}

@ -2754,54 +2754,52 @@ explicitly configure the paths that you do want to override.
=== OAuth2
=== Client
If you have `spring-security-oauth2-client` on your classpath you can take advantage of
some auto-configuration to make it easy to set up an OAuth2 Client. This configuration
makes use of the properties under `OAuth2ClientProperties`.
If you have `spring-security-oauth2-client` on your classpath you can take advantage of some
auto-configuration to make it easy to set up an OAuth2 Client. This configuration makes use of
the properties under `OAuth2ClientProperties`.
You can register multiple OAuth2 clients and providers under the `spring.security.oauth2.client` prefix.
For example,
You can register multiple OAuth2 clients and providers under the
`spring.security.oauth2.client` prefix. For example:
[source,yaml,indent=0]
----
# application.yml
spring:
security:
oauth2:
client:
registration:
my-client-1:
client-id: abcd
client-secret: password
client-name: Client for user scope
provider: my-oauth-provider
scope: user
redirect-uri: http://my-redirect-uri.com
authentication-method: basic
authorization-grant-type: authorization_code
my-client2:
client-id: abcd
client-secret: password
client-name: Client for email scope
provider: my-oauth-provider
scope: email
redirect-uri: http://my-redirect-uri.com
authentication-method: basic
authorization-grant-type: authorization_code
provider:
my-oauth-provider:
authorization-uri: http://my-auth-server/oauth/authorize
token-uri: http://my-auth-server/oauth/token
user-info-uri: http://my-auth-server/userinfo
jwk-set-uri: http://my-auth-server/token_keys
user-name-attribute: name
# additional configuration as required
----
NOTE: For common OAuth2 and OpenID providers such as Google, Github, Facebook and Okta, we provide a set of
provider defaults. If you don't need to customize these providers, you do not need to provide the `provider`
configuration. The client registration `provider` key should reference one these providers.
spring:
security:
oauth2:
client:
registration:
my-client-1:
client-id: abcd
client-secret: password
client-name: Client for user scope
provider: my-oauth-provider
scope: user
redirect-uri: http://my-redirect-uri.com
authentication-method: basic
authorization-grant-type: authorization_code
my-client2:
client-id: abcd
client-secret: password
client-name: Client for email scope
provider: my-oauth-provider
scope: email
redirect-uri: http://my-redirect-uri.com
authentication-method: basic
authorization-grant-type: authorization_code
provider:
my-oauth-provider:
authorization-uri: http://my-auth-server/oauth/authorize
token-uri: http://my-auth-server/oauth/token
user-info-uri: http://my-auth-server/userinfo
jwk-set-uri: http://my-auth-server/token_keys
user-name-attribute: name
----
NOTE: For common OAuth2 and OpenID providers such as Google, Github, Facebook and Okta,
we provide a set of provider defaults. If you don't need to customize these providers, you
do not need to provide the `provider` configuration. The client registration `provider`
key should reference one these providers.
[[boot-features-security-actuator]]

@ -73,6 +73,7 @@ public class DevToolsIntegrationTests {
@Before
public void launchApplication() throws Exception {
this.serverPortFile.delete();
System.out.println("Launching " + this.javaLauncher.getClass());
this.launchedApplication = this.applicationLauncher
.launchApplication(this.javaLauncher);
}
@ -139,6 +140,7 @@ public class DevToolsIntegrationTests {
private int awaitServerPort() throws Exception {
long end = System.currentTimeMillis() + 30000;
while (this.serverPortFile.length() == 0) {
System.out.println("Getting server port " + this.serverPortFile.length());
if (System.currentTimeMillis() > end) {
throw new IllegalStateException(String.format(
"server.port file was not written within 30 seconds. "
@ -153,6 +155,7 @@ public class DevToolsIntegrationTests {
FileReader portReader = new FileReader(this.serverPortFile);
int port = Integer.valueOf(FileCopyUtils.copyToString(portReader));
this.serverPortFile.delete();
System.out.println("Got port " + port);
return port;
}

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<!-- Your own application should inherit from spring-boot-starter-parent -->

@ -1,3 +1,19 @@
/*
* Copyright 2012-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package sample.oauth2.client;
import java.security.Principal;
@ -5,9 +21,6 @@ import java.security.Principal;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author Madhura Bhave
*/
@RestController
public class ExampleController {

@ -1,11 +1,24 @@
/*
* Copyright 2012-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package sample.oauth2.client;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* @author Madhura Bhave
*/
@SpringBootApplication
public class SampleOAuth2ClientApplication {

@ -1,3 +1,19 @@
/*
* Copyright 2012-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package sample.oauth2.client;
import java.net.URI;
@ -16,11 +32,6 @@ import org.springframework.test.context.junit4.SpringRunner;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Integration tests for an OAuth2 client application.
*
* @author Madhura Bhave
*/
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, properties = {
"APP-CLIENT-ID=my-client-id", "APP-CLIENT-SECRET=my-client-secret" })
@ -43,10 +54,13 @@ public class SampleOAuth2ClientApplicationTests {
@Test
public void loginShouldHaveBothOAuthClientsToChooseFrom() throws Exception {
ResponseEntity<String> entity = this.restTemplate.getForEntity("/login", String.class);
ResponseEntity<String> entity = this.restTemplate.getForEntity("/login",
String.class);
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
assertThat(entity.getBody()).contains("/oauth2/authorization/code/github-client-1");
assertThat(entity.getBody()).contains("/oauth2/authorization/code/github-client-2");
assertThat(entity.getBody())
.contains("/oauth2/authorization/code/github-client-1");
assertThat(entity.getBody())
.contains("/oauth2/authorization/code/github-client-2");
}
}
}

@ -148,8 +148,7 @@ public class TestRestTemplate {
interceptors = Collections.emptyList();
}
interceptors = new ArrayList<>(interceptors);
interceptors.removeIf(
(interceptor) -> interceptor instanceof BasicAuthorizationInterceptor);
interceptors.removeIf(BasicAuthorizationInterceptor.class::isInstance);
interceptors.add(new BasicAuthorizationInterceptor(username, password));
restTemplate.setInterceptors(interceptors);
}

Loading…
Cancel
Save