Add SSL service connection support for MongoDB
See gh-41137
This commit is contained in:
parent
0ccf1b81d8
commit
109fd6f97d
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2012-2023 the original author or authors.
|
* Copyright 2012-2025 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -18,6 +18,7 @@ package org.springframework.boot.autoconfigure.data.mongo;
|
|||||||
|
|
||||||
import com.mongodb.client.MongoClient;
|
import com.mongodb.client.MongoClient;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.ObjectProvider;
|
||||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||||
@ -27,6 +28,7 @@ import org.springframework.boot.autoconfigure.mongo.MongoConnectionDetails;
|
|||||||
import org.springframework.boot.autoconfigure.mongo.MongoProperties;
|
import org.springframework.boot.autoconfigure.mongo.MongoProperties;
|
||||||
import org.springframework.boot.autoconfigure.mongo.PropertiesMongoConnectionDetails;
|
import org.springframework.boot.autoconfigure.mongo.PropertiesMongoConnectionDetails;
|
||||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||||
|
import org.springframework.boot.ssl.SslBundles;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Import;
|
import org.springframework.context.annotation.Import;
|
||||||
import org.springframework.data.mongodb.core.MongoTemplate;
|
import org.springframework.data.mongodb.core.MongoTemplate;
|
||||||
@ -59,8 +61,9 @@ public class MongoDataAutoConfiguration {
|
|||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnMissingBean(MongoConnectionDetails.class)
|
@ConditionalOnMissingBean(MongoConnectionDetails.class)
|
||||||
PropertiesMongoConnectionDetails mongoConnectionDetails(MongoProperties properties) {
|
PropertiesMongoConnectionDetails mongoConnectionDetails(MongoProperties properties,
|
||||||
return new PropertiesMongoConnectionDetails(properties);
|
ObjectProvider<SslBundles> sslBundles) {
|
||||||
|
return new PropertiesMongoConnectionDetails(properties, sslBundles.getIfAvailable());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2012-2024 the original author or authors.
|
* Copyright 2012-2025 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -48,8 +48,9 @@ public class MongoAutoConfiguration {
|
|||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnMissingBean(MongoConnectionDetails.class)
|
@ConditionalOnMissingBean(MongoConnectionDetails.class)
|
||||||
PropertiesMongoConnectionDetails mongoConnectionDetails(MongoProperties properties) {
|
PropertiesMongoConnectionDetails mongoConnectionDetails(MongoProperties properties,
|
||||||
return new PropertiesMongoConnectionDetails(properties);
|
ObjectProvider<SslBundles> sslBundles) {
|
||||||
|
return new PropertiesMongoConnectionDetails(properties, sslBundles.getIfAvailable());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@ -70,9 +71,9 @@ public class MongoAutoConfiguration {
|
|||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
StandardMongoClientSettingsBuilderCustomizer standardMongoSettingsCustomizer(MongoProperties properties,
|
StandardMongoClientSettingsBuilderCustomizer standardMongoSettingsCustomizer(MongoProperties properties,
|
||||||
MongoConnectionDetails connectionDetails, ObjectProvider<SslBundles> sslBundles) {
|
MongoConnectionDetails connectionDetails) {
|
||||||
return new StandardMongoClientSettingsBuilderCustomizer(connectionDetails.getConnectionString(),
|
return new StandardMongoClientSettingsBuilderCustomizer(connectionDetails,
|
||||||
properties.getUuidRepresentation(), properties.getSsl(), sslBundles.getIfAvailable());
|
properties.getUuidRepresentation());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2012-2023 the original author or authors.
|
* Copyright 2012-2025 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -19,6 +19,7 @@ package org.springframework.boot.autoconfigure.mongo;
|
|||||||
import com.mongodb.ConnectionString;
|
import com.mongodb.ConnectionString;
|
||||||
|
|
||||||
import org.springframework.boot.autoconfigure.service.connection.ConnectionDetails;
|
import org.springframework.boot.autoconfigure.service.connection.ConnectionDetails;
|
||||||
|
import org.springframework.boot.ssl.SslBundle;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Details required to establish a connection to a MongoDB service.
|
* Details required to establish a connection to a MongoDB service.
|
||||||
@ -36,6 +37,15 @@ public interface MongoConnectionDetails extends ConnectionDetails {
|
|||||||
*/
|
*/
|
||||||
ConnectionString getConnectionString();
|
ConnectionString getConnectionString();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SSL bundle to use.
|
||||||
|
* @return the SSL bundle to use
|
||||||
|
* @since 3.5.0
|
||||||
|
*/
|
||||||
|
default SslBundle getSslBundle() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GridFS configuration.
|
* GridFS configuration.
|
||||||
* @return the GridFS configuration or {@code null}
|
* @return the GridFS configuration or {@code null}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2012-2024 the original author or authors.
|
* Copyright 2012-2025 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -53,8 +53,9 @@ public class MongoReactiveAutoConfiguration {
|
|||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnMissingBean(MongoConnectionDetails.class)
|
@ConditionalOnMissingBean(MongoConnectionDetails.class)
|
||||||
PropertiesMongoConnectionDetails mongoConnectionDetails(MongoProperties properties) {
|
PropertiesMongoConnectionDetails mongoConnectionDetails(MongoProperties properties,
|
||||||
return new PropertiesMongoConnectionDetails(properties);
|
ObjectProvider<SslBundles> sslBundles) {
|
||||||
|
return new PropertiesMongoConnectionDetails(properties, sslBundles.getIfAvailable());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@ -77,9 +78,9 @@ public class MongoReactiveAutoConfiguration {
|
|||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
StandardMongoClientSettingsBuilderCustomizer standardMongoSettingsCustomizer(MongoProperties properties,
|
StandardMongoClientSettingsBuilderCustomizer standardMongoSettingsCustomizer(MongoProperties properties,
|
||||||
MongoConnectionDetails connectionDetails, ObjectProvider<SslBundles> sslBundles) {
|
MongoConnectionDetails connectionDetails) {
|
||||||
return new StandardMongoClientSettingsBuilderCustomizer(connectionDetails.getConnectionString(),
|
return new StandardMongoClientSettingsBuilderCustomizer(connectionDetails,
|
||||||
properties.getUuidRepresentation(), properties.getSsl(), sslBundles.getIfAvailable());
|
properties.getUuidRepresentation());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2012-2024 the original author or authors.
|
* Copyright 2012-2025 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -23,6 +23,10 @@ import java.util.List;
|
|||||||
|
|
||||||
import com.mongodb.ConnectionString;
|
import com.mongodb.ConnectionString;
|
||||||
|
|
||||||
|
import org.springframework.boot.autoconfigure.mongo.MongoProperties.Ssl;
|
||||||
|
import org.springframework.boot.ssl.SslBundle;
|
||||||
|
import org.springframework.boot.ssl.SslBundles;
|
||||||
|
import org.springframework.util.Assert;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -38,8 +42,11 @@ public class PropertiesMongoConnectionDetails implements MongoConnectionDetails
|
|||||||
|
|
||||||
private final MongoProperties properties;
|
private final MongoProperties properties;
|
||||||
|
|
||||||
public PropertiesMongoConnectionDetails(MongoProperties properties) {
|
private final SslBundles sslBundles;
|
||||||
|
|
||||||
|
public PropertiesMongoConnectionDetails(MongoProperties properties, SslBundles sslBundles) {
|
||||||
this.properties = properties;
|
this.properties = properties;
|
||||||
|
this.sslBundles = sslBundles;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -90,6 +97,19 @@ public class PropertiesMongoConnectionDetails implements MongoConnectionDetails
|
|||||||
PropertiesMongoConnectionDetails.this.properties.getGridfs().getBucket());
|
PropertiesMongoConnectionDetails.this.properties.getGridfs().getBucket());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SslBundle getSslBundle() {
|
||||||
|
Ssl ssl = this.properties.getSsl();
|
||||||
|
if (!ssl.isEnabled()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (StringUtils.hasLength(ssl.getBundle())) {
|
||||||
|
Assert.notNull(this.sslBundles, "SSL bundle name has been set but no SSL bundles found in context");
|
||||||
|
return this.sslBundles.getBundle(ssl.getBundle());
|
||||||
|
}
|
||||||
|
return SslBundle.systemDefault();
|
||||||
|
}
|
||||||
|
|
||||||
private List<String> getOptions() {
|
private List<String> getOptions() {
|
||||||
List<String> options = new ArrayList<>();
|
List<String> options = new ArrayList<>();
|
||||||
if (StringUtils.hasText(this.properties.getReplicaSetName())) {
|
if (StringUtils.hasText(this.properties.getReplicaSetName())) {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2012-2023 the original author or authors.
|
* Copyright 2012-2025 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -41,28 +41,57 @@ public class StandardMongoClientSettingsBuilderCustomizer implements MongoClient
|
|||||||
|
|
||||||
private final UuidRepresentation uuidRepresentation;
|
private final UuidRepresentation uuidRepresentation;
|
||||||
|
|
||||||
|
private final MongoConnectionDetails connectionDetails;
|
||||||
|
|
||||||
private final MongoProperties.Ssl ssl;
|
private final MongoProperties.Ssl ssl;
|
||||||
|
|
||||||
private final SslBundles sslBundles;
|
private final SslBundles sslBundles;
|
||||||
|
|
||||||
private int order = 0;
|
private int order = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new instance.
|
||||||
|
* @param connectionString the connection string
|
||||||
|
* @param uuidRepresentation the uuid representation
|
||||||
|
* @param ssl the ssl properties
|
||||||
|
* @param sslBundles the ssl bundles
|
||||||
|
* @deprecated since 3.5.0 for removal in 3.7.0 in favor of
|
||||||
|
* {@link #StandardMongoClientSettingsBuilderCustomizer(MongoConnectionDetails, UuidRepresentation)}
|
||||||
|
*/
|
||||||
|
@Deprecated(forRemoval = true, since = "3.5.0")
|
||||||
public StandardMongoClientSettingsBuilderCustomizer(ConnectionString connectionString,
|
public StandardMongoClientSettingsBuilderCustomizer(ConnectionString connectionString,
|
||||||
UuidRepresentation uuidRepresentation, MongoProperties.Ssl ssl, SslBundles sslBundles) {
|
UuidRepresentation uuidRepresentation, MongoProperties.Ssl ssl, SslBundles sslBundles) {
|
||||||
|
this.connectionDetails = null;
|
||||||
this.connectionString = connectionString;
|
this.connectionString = connectionString;
|
||||||
this.uuidRepresentation = uuidRepresentation;
|
this.uuidRepresentation = uuidRepresentation;
|
||||||
this.ssl = ssl;
|
this.ssl = ssl;
|
||||||
this.sslBundles = sslBundles;
|
this.sslBundles = sslBundles;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public StandardMongoClientSettingsBuilderCustomizer(MongoConnectionDetails connectionDetails,
|
||||||
|
UuidRepresentation uuidRepresentation) {
|
||||||
|
this.connectionString = null;
|
||||||
|
this.ssl = null;
|
||||||
|
this.sslBundles = null;
|
||||||
|
this.connectionDetails = connectionDetails;
|
||||||
|
this.uuidRepresentation = uuidRepresentation;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void customize(MongoClientSettings.Builder settingsBuilder) {
|
public void customize(MongoClientSettings.Builder settingsBuilder) {
|
||||||
|
settingsBuilder.uuidRepresentation(this.uuidRepresentation);
|
||||||
|
if (this.connectionDetails != null) {
|
||||||
|
settingsBuilder.applyConnectionString(this.connectionDetails.getConnectionString());
|
||||||
|
settingsBuilder.applyToSslSettings(this::configureSslIfNeeded);
|
||||||
|
}
|
||||||
|
else {
|
||||||
settingsBuilder.uuidRepresentation(this.uuidRepresentation);
|
settingsBuilder.uuidRepresentation(this.uuidRepresentation);
|
||||||
settingsBuilder.applyConnectionString(this.connectionString);
|
settingsBuilder.applyConnectionString(this.connectionString);
|
||||||
if (this.ssl.isEnabled()) {
|
if (this.ssl.isEnabled()) {
|
||||||
settingsBuilder.applyToSslSettings(this::configureSsl);
|
settingsBuilder.applyToSslSettings(this::configureSsl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void configureSsl(SslSettings.Builder settings) {
|
private void configureSsl(SslSettings.Builder settings) {
|
||||||
settings.enabled(true);
|
settings.enabled(true);
|
||||||
@ -73,6 +102,15 @@ public class StandardMongoClientSettingsBuilderCustomizer implements MongoClient
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void configureSslIfNeeded(SslSettings.Builder settings) {
|
||||||
|
SslBundle sslBundle = this.connectionDetails.getSslBundle();
|
||||||
|
if (sslBundle != null) {
|
||||||
|
settings.enabled(true);
|
||||||
|
Assert.state(!sslBundle.getOptions().isSpecified(), "SSL options cannot be specified with MongoDB");
|
||||||
|
settings.context(sslBundle.createSslContext());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getOrder() {
|
public int getOrder() {
|
||||||
return this.order;
|
return this.order;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2012-2024 the original author or authors.
|
* Copyright 2012-2025 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -80,7 +80,7 @@ class MongoAutoConfigurationTests {
|
|||||||
this.contextRunner.withPropertyValues("spring.data.mongodb.ssl.enabled=true").run((context) -> {
|
this.contextRunner.withPropertyValues("spring.data.mongodb.ssl.enabled=true").run((context) -> {
|
||||||
SslSettings sslSettings = getSettings(context).getSslSettings();
|
SslSettings sslSettings = getSettings(context).getSslSettings();
|
||||||
assertThat(sslSettings.isEnabled()).isTrue();
|
assertThat(sslSettings.isEnabled()).isTrue();
|
||||||
assertThat(sslSettings.getContext()).isNull();
|
assertThat(sslSettings.getContext()).isNotNull();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2012-2024 the original author or authors.
|
* Copyright 2012-2025 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -88,7 +88,7 @@ class MongoReactiveAutoConfigurationTests {
|
|||||||
this.contextRunner.withPropertyValues("spring.data.mongodb.ssl.enabled=true").run((context) -> {
|
this.contextRunner.withPropertyValues("spring.data.mongodb.ssl.enabled=true").run((context) -> {
|
||||||
SslSettings sslSettings = getSettings(context).getSslSettings();
|
SslSettings sslSettings = getSettings(context).getSslSettings();
|
||||||
assertThat(sslSettings.isEnabled()).isTrue();
|
assertThat(sslSettings.isEnabled()).isTrue();
|
||||||
assertThat(sslSettings.getContext()).isNull();
|
assertThat(sslSettings.getContext()).isNotNull();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2012-2024 the original author or authors.
|
* Copyright 2012-2025 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -19,24 +19,41 @@ package org.springframework.boot.autoconfigure.mongo;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import com.mongodb.ConnectionString;
|
import com.mongodb.ConnectionString;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import org.springframework.boot.ssl.DefaultSslBundleRegistry;
|
||||||
|
import org.springframework.boot.ssl.SslBundle;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests for {@link PropertiesMongoConnectionDetails}.
|
* Tests for {@link PropertiesMongoConnectionDetails}.
|
||||||
*
|
*
|
||||||
* @author Christoph Dreis
|
* @author Christoph Dreis
|
||||||
* @author Scott Frederick
|
* @author Scott Frederick
|
||||||
|
* @author Moritz Halbritter
|
||||||
*/
|
*/
|
||||||
class PropertiesMongoConnectionDetailsTests {
|
class PropertiesMongoConnectionDetailsTests {
|
||||||
|
|
||||||
private final MongoProperties properties = new MongoProperties();
|
private MongoProperties properties;
|
||||||
|
|
||||||
|
private DefaultSslBundleRegistry sslBundleRegistry;
|
||||||
|
|
||||||
|
private PropertiesMongoConnectionDetails connectionDetails;
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
void setUp() {
|
||||||
|
this.properties = new MongoProperties();
|
||||||
|
this.sslBundleRegistry = new DefaultSslBundleRegistry();
|
||||||
|
this.connectionDetails = new PropertiesMongoConnectionDetails(this.properties, this.sslBundleRegistry);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void credentialsCanBeConfiguredWithUsername() {
|
void credentialsCanBeConfiguredWithUsername() {
|
||||||
this.properties.setUsername("user");
|
this.properties.setUsername("user");
|
||||||
ConnectionString connectionString = getConnectionString();
|
ConnectionString connectionString = this.connectionDetails.getConnectionString();
|
||||||
assertThat(connectionString.getUsername()).isEqualTo("user");
|
assertThat(connectionString.getUsername()).isEqualTo("user");
|
||||||
assertThat(connectionString.getPassword()).isEmpty();
|
assertThat(connectionString.getPassword()).isEmpty();
|
||||||
assertThat(connectionString.getCredential().getUserName()).isEqualTo("user");
|
assertThat(connectionString.getCredential().getUserName()).isEqualTo("user");
|
||||||
@ -48,7 +65,7 @@ class PropertiesMongoConnectionDetailsTests {
|
|||||||
void credentialsCanBeConfiguredWithUsernameAndPassword() {
|
void credentialsCanBeConfiguredWithUsernameAndPassword() {
|
||||||
this.properties.setUsername("user");
|
this.properties.setUsername("user");
|
||||||
this.properties.setPassword("secret".toCharArray());
|
this.properties.setPassword("secret".toCharArray());
|
||||||
ConnectionString connectionString = getConnectionString();
|
ConnectionString connectionString = this.connectionDetails.getConnectionString();
|
||||||
assertThat(connectionString.getUsername()).isEqualTo("user");
|
assertThat(connectionString.getUsername()).isEqualTo("user");
|
||||||
assertThat(connectionString.getPassword()).isEqualTo("secret".toCharArray());
|
assertThat(connectionString.getPassword()).isEqualTo("secret".toCharArray());
|
||||||
assertThat(connectionString.getCredential().getUserName()).isEqualTo("user");
|
assertThat(connectionString.getCredential().getUserName()).isEqualTo("user");
|
||||||
@ -59,13 +76,13 @@ class PropertiesMongoConnectionDetailsTests {
|
|||||||
@Test
|
@Test
|
||||||
void databaseCanBeConfigured() {
|
void databaseCanBeConfigured() {
|
||||||
this.properties.setDatabase("db");
|
this.properties.setDatabase("db");
|
||||||
ConnectionString connectionString = getConnectionString();
|
ConnectionString connectionString = this.connectionDetails.getConnectionString();
|
||||||
assertThat(connectionString.getDatabase()).isEqualTo("db");
|
assertThat(connectionString.getDatabase()).isEqualTo("db");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void databaseHasDefaultWhenNotConfigured() {
|
void databaseHasDefaultWhenNotConfigured() {
|
||||||
ConnectionString connectionString = getConnectionString();
|
ConnectionString connectionString = this.connectionDetails.getConnectionString();
|
||||||
assertThat(connectionString.getDatabase()).isEqualTo("test");
|
assertThat(connectionString.getDatabase()).isEqualTo("test");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -74,7 +91,7 @@ class PropertiesMongoConnectionDetailsTests {
|
|||||||
this.properties.setUsername("user");
|
this.properties.setUsername("user");
|
||||||
this.properties.setDatabase("db");
|
this.properties.setDatabase("db");
|
||||||
this.properties.setAuthenticationDatabase("authdb");
|
this.properties.setAuthenticationDatabase("authdb");
|
||||||
ConnectionString connectionString = getConnectionString();
|
ConnectionString connectionString = this.connectionDetails.getConnectionString();
|
||||||
assertThat(connectionString.getDatabase()).isEqualTo("db");
|
assertThat(connectionString.getDatabase()).isEqualTo("db");
|
||||||
assertThat(connectionString.getCredential().getSource()).isEqualTo("authdb");
|
assertThat(connectionString.getCredential().getSource()).isEqualTo("authdb");
|
||||||
assertThat(connectionString.getCredential().getUserName()).isEqualTo("user");
|
assertThat(connectionString.getCredential().getUserName()).isEqualTo("user");
|
||||||
@ -83,14 +100,14 @@ class PropertiesMongoConnectionDetailsTests {
|
|||||||
@Test
|
@Test
|
||||||
void authenticationDatabaseIsNotConfiguredWhenUsernameIsNotConfigured() {
|
void authenticationDatabaseIsNotConfiguredWhenUsernameIsNotConfigured() {
|
||||||
this.properties.setAuthenticationDatabase("authdb");
|
this.properties.setAuthenticationDatabase("authdb");
|
||||||
ConnectionString connectionString = getConnectionString();
|
ConnectionString connectionString = this.connectionDetails.getConnectionString();
|
||||||
assertThat(connectionString.getCredential()).isNull();
|
assertThat(connectionString.getCredential()).isNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void replicaSetCanBeConfigured() {
|
void replicaSetCanBeConfigured() {
|
||||||
this.properties.setReplicaSetName("test");
|
this.properties.setReplicaSetName("test");
|
||||||
ConnectionString connectionString = getConnectionString();
|
ConnectionString connectionString = this.connectionDetails.getConnectionString();
|
||||||
assertThat(connectionString.getRequiredReplicaSetName()).isEqualTo("test");
|
assertThat(connectionString.getRequiredReplicaSetName()).isEqualTo("test");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,7 +116,7 @@ class PropertiesMongoConnectionDetailsTests {
|
|||||||
this.properties.setUsername("user");
|
this.properties.setUsername("user");
|
||||||
this.properties.setDatabase("db");
|
this.properties.setDatabase("db");
|
||||||
this.properties.setReplicaSetName("test");
|
this.properties.setReplicaSetName("test");
|
||||||
ConnectionString connectionString = getConnectionString();
|
ConnectionString connectionString = this.connectionDetails.getConnectionString();
|
||||||
assertThat(connectionString.getDatabase()).isEqualTo("db");
|
assertThat(connectionString.getDatabase()).isEqualTo("db");
|
||||||
assertThat(connectionString.getRequiredReplicaSetName()).isEqualTo("test");
|
assertThat(connectionString.getRequiredReplicaSetName()).isEqualTo("test");
|
||||||
}
|
}
|
||||||
@ -107,14 +124,14 @@ class PropertiesMongoConnectionDetailsTests {
|
|||||||
@Test
|
@Test
|
||||||
void replicaSetCanBeNull() {
|
void replicaSetCanBeNull() {
|
||||||
this.properties.setReplicaSetName(null);
|
this.properties.setReplicaSetName(null);
|
||||||
ConnectionString connectionString = getConnectionString();
|
ConnectionString connectionString = this.connectionDetails.getConnectionString();
|
||||||
assertThat(connectionString.getRequiredReplicaSetName()).isNull();
|
assertThat(connectionString.getRequiredReplicaSetName()).isNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void replicaSetCanBeBlank() {
|
void replicaSetCanBeBlank() {
|
||||||
this.properties.setReplicaSetName("");
|
this.properties.setReplicaSetName("");
|
||||||
ConnectionString connectionString = getConnectionString();
|
ConnectionString connectionString = this.connectionDetails.getConnectionString();
|
||||||
assertThat(connectionString.getRequiredReplicaSetName()).isNull();
|
assertThat(connectionString.getRequiredReplicaSetName()).isNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -122,18 +139,32 @@ class PropertiesMongoConnectionDetailsTests {
|
|||||||
void whenAdditionalHostsAreConfiguredThenTheyAreIncludedInHostsOfConnectionString() {
|
void whenAdditionalHostsAreConfiguredThenTheyAreIncludedInHostsOfConnectionString() {
|
||||||
this.properties.setHost("mongo1.example.com");
|
this.properties.setHost("mongo1.example.com");
|
||||||
this.properties.setAdditionalHosts(List.of("mongo2.example.com", "mongo3.example.com"));
|
this.properties.setAdditionalHosts(List.of("mongo2.example.com", "mongo3.example.com"));
|
||||||
ConnectionString connectionString = getConnectionString();
|
ConnectionString connectionString = this.connectionDetails.getConnectionString();
|
||||||
assertThat(connectionString.getHosts()).containsExactly("mongo1.example.com", "mongo2.example.com",
|
assertThat(connectionString.getHosts()).containsExactly("mongo1.example.com", "mongo2.example.com",
|
||||||
"mongo3.example.com");
|
"mongo3.example.com");
|
||||||
}
|
}
|
||||||
|
|
||||||
private PropertiesMongoConnectionDetails createConnectionDetails() {
|
@Test
|
||||||
return new PropertiesMongoConnectionDetails(this.properties);
|
void shouldReturnSslBundle() {
|
||||||
|
SslBundle bundle1 = mock(SslBundle.class);
|
||||||
|
this.sslBundleRegistry.registerBundle("bundle-1", bundle1);
|
||||||
|
this.properties.getSsl().setBundle("bundle-1");
|
||||||
|
SslBundle sslBundle = this.connectionDetails.getSslBundle();
|
||||||
|
assertThat(sslBundle).isSameAs(bundle1);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ConnectionString getConnectionString() {
|
@Test
|
||||||
PropertiesMongoConnectionDetails connectionDetails = createConnectionDetails();
|
void shouldReturnSystemDefaultBundleIfSslIsEnabledButBundleNotSet() {
|
||||||
return connectionDetails.getConnectionString();
|
this.properties.getSsl().setEnabled(true);
|
||||||
|
SslBundle sslBundle = this.connectionDetails.getSslBundle();
|
||||||
|
assertThat(sslBundle).isNotNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldReturnNullIfSslIsNotEnabled() {
|
||||||
|
this.properties.getSsl().setEnabled(false);
|
||||||
|
SslBundle sslBundle = this.connectionDetails.getSslBundle();
|
||||||
|
assertThat(sslBundle).isNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2012-2023 the original author or authors.
|
* Copyright 2012-2025 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -20,6 +20,7 @@ import com.mongodb.ConnectionString;
|
|||||||
import org.testcontainers.containers.MongoDBContainer;
|
import org.testcontainers.containers.MongoDBContainer;
|
||||||
|
|
||||||
import org.springframework.boot.autoconfigure.mongo.MongoConnectionDetails;
|
import org.springframework.boot.autoconfigure.mongo.MongoConnectionDetails;
|
||||||
|
import org.springframework.boot.ssl.SslBundle;
|
||||||
import org.springframework.boot.testcontainers.service.connection.ContainerConnectionDetailsFactory;
|
import org.springframework.boot.testcontainers.service.connection.ContainerConnectionDetailsFactory;
|
||||||
import org.springframework.boot.testcontainers.service.connection.ContainerConnectionSource;
|
import org.springframework.boot.testcontainers.service.connection.ContainerConnectionSource;
|
||||||
import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
|
import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
|
||||||
@ -59,6 +60,11 @@ class MongoContainerConnectionDetailsFactory
|
|||||||
return new ConnectionString(getContainer().getReplicaSetUrl());
|
return new ConnectionString(getContainer().getReplicaSetUrl());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SslBundle getSslBundle() {
|
||||||
|
return super.getSslBundle();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2012-2024 the original author or authors.
|
* Copyright 2012-2025 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -25,6 +25,8 @@ import org.testcontainers.junit.jupiter.Testcontainers;
|
|||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.test.context.SpringBootTest;
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
import org.springframework.boot.testcontainers.service.connection.PemKeyStore;
|
||||||
|
import org.springframework.boot.testcontainers.service.connection.PemTrustStore;
|
||||||
import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
|
import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
|
||||||
import org.springframework.boot.testsupport.container.TestImage;
|
import org.springframework.boot.testsupport.container.TestImage;
|
||||||
import org.springframework.data.mongodb.core.ReactiveMongoTemplate;
|
import org.springframework.data.mongodb.core.ReactiveMongoTemplate;
|
||||||
@ -37,14 +39,13 @@ import static org.assertj.core.api.Assertions.assertThat;
|
|||||||
* @author Scott Frederick
|
* @author Scott Frederick
|
||||||
*/
|
*/
|
||||||
@Testcontainers(disabledWithoutDocker = true)
|
@Testcontainers(disabledWithoutDocker = true)
|
||||||
@SpringBootTest(properties = { "spring.data.mongodb.ssl.bundle=client",
|
@SpringBootTest
|
||||||
"spring.ssl.bundle.pem.client.keystore.certificate=classpath:ssl/test-client.crt",
|
|
||||||
"spring.ssl.bundle.pem.client.keystore.private-key=classpath:ssl/test-client.key",
|
|
||||||
"spring.ssl.bundle.pem.client.truststore.certificate=classpath:ssl/test-ca.crt" })
|
|
||||||
class SampleMongoApplicationReactiveSslTests {
|
class SampleMongoApplicationReactiveSslTests {
|
||||||
|
|
||||||
@Container
|
@Container
|
||||||
@ServiceConnection
|
@ServiceConnection
|
||||||
|
@PemKeyStore(certificate = "classpath:ssl/test-client.crt", privateKey = "classpath:ssl/test-client.key")
|
||||||
|
@PemTrustStore("classpath:ssl/test-ca.crt")
|
||||||
static final MongoDBContainer mongoDb = TestImage.container(SecureMongoContainer.class);
|
static final MongoDBContainer mongoDb = TestImage.container(SecureMongoContainer.class);
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2012-2024 the original author or authors.
|
* Copyright 2012-2025 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -23,6 +23,8 @@ import org.testcontainers.junit.jupiter.Testcontainers;
|
|||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.test.autoconfigure.data.mongo.DataMongoTest;
|
import org.springframework.boot.test.autoconfigure.data.mongo.DataMongoTest;
|
||||||
|
import org.springframework.boot.testcontainers.service.connection.PemKeyStore;
|
||||||
|
import org.springframework.boot.testcontainers.service.connection.PemTrustStore;
|
||||||
import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
|
import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
|
||||||
import org.springframework.boot.testsupport.container.TestImage;
|
import org.springframework.boot.testsupport.container.TestImage;
|
||||||
import org.springframework.data.mongodb.core.MongoTemplate;
|
import org.springframework.data.mongodb.core.MongoTemplate;
|
||||||
@ -36,14 +38,13 @@ import static org.assertj.core.api.Assertions.assertThat;
|
|||||||
* @author Eddú Meléndez
|
* @author Eddú Meléndez
|
||||||
*/
|
*/
|
||||||
@Testcontainers(disabledWithoutDocker = true)
|
@Testcontainers(disabledWithoutDocker = true)
|
||||||
@DataMongoTest(properties = { "spring.data.mongodb.ssl.bundle=client",
|
@DataMongoTest
|
||||||
"spring.ssl.bundle.pem.client.keystore.certificate=classpath:ssl/test-client.crt",
|
|
||||||
"spring.ssl.bundle.pem.client.keystore.private-key=classpath:ssl/test-client.key",
|
|
||||||
"spring.ssl.bundle.pem.client.truststore.certificate=classpath:ssl/test-ca.crt" })
|
|
||||||
class SampleMongoApplicationSslTests {
|
class SampleMongoApplicationSslTests {
|
||||||
|
|
||||||
@Container
|
@Container
|
||||||
@ServiceConnection
|
@ServiceConnection
|
||||||
|
@PemKeyStore(certificate = "classpath:ssl/test-client.crt", privateKey = "classpath:ssl/test-client.key")
|
||||||
|
@PemTrustStore("classpath:ssl/test-ca.crt")
|
||||||
static final MongoDBContainer mongoDb = TestImage.container(SecureMongoContainer.class);
|
static final MongoDBContainer mongoDb = TestImage.container(SecureMongoContainer.class);
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
|
Loading…
x
Reference in New Issue
Block a user