Ignore URI when local.mongo.port is set

This commit makes sure that if `local.mongo.port` is set, a `MongoClient`
on the embedded MongoDB instance is created. When an embedded instance
is detected, only the `host` property is used and the `uri` is ignored if
set.

This makes sure that the auto-configured `MongoClient` automatically
switches to the embedded server, even if a production uri has been
specified.

Closes gh-8219
pull/8346/merge
Stephane Nicoll 8 years ago
parent 82d4bf619d
commit 0d61f92479

@ -202,59 +202,69 @@ public class MongoProperties {
public MongoClient createMongoClient(MongoClientOptions options, public MongoClient createMongoClient(MongoClientOptions options,
Environment environment) throws UnknownHostException { Environment environment) throws UnknownHostException {
try { try {
if (hasCustomAddress() || hasCustomCredentials()) { Integer embeddedPort = getEmbeddedPort(environment);
if (this.uri != null) { if (embeddedPort != null) {
throw new IllegalStateException("Invalid mongo configuration, " return createEmbeddedMongoClient(options, embeddedPort);
+ "either uri or host/port/credentials must be specified");
}
if (options == null) {
options = MongoClientOptions.builder().build();
}
List<MongoCredential> credentials = new ArrayList<MongoCredential>();
if (hasCustomCredentials()) {
String database = this.authenticationDatabase == null
? getMongoClientDatabase() : this.authenticationDatabase;
credentials.add(MongoCredential.createCredential(this.username,
database, this.password));
}
String host = this.host == null ? "localhost" : this.host;
int port = determinePort(environment);
return new MongoClient(
Collections.singletonList(new ServerAddress(host, port)),
credentials, options);
} }
// The options and credentials are in the URI return createNetworkMongoClient(options);
return new MongoClient(new MongoClientURI(determineUri(), builder(options)));
} }
finally { finally {
clearPassword(); clearPassword();
} }
} }
private boolean hasCustomAddress() { private Integer getEmbeddedPort(Environment environment) {
return this.host != null || this.port != null; if (environment != null) {
String localPort = environment.getProperty("local.mongo.port");
if (localPort != null) {
return Integer.valueOf(localPort);
}
}
return null;
} }
private boolean hasCustomCredentials() { private MongoClient createEmbeddedMongoClient(MongoClientOptions options, int port) {
return this.username != null && this.password != null; if (options == null) {
options = MongoClientOptions.builder().build();
}
String host = this.host == null ? "localhost" : this.host;
return new MongoClient(
Collections.singletonList(new ServerAddress(host, port)),
Collections.<MongoCredential>emptyList(), options);
} }
private int determinePort(Environment environment) { private MongoClient createNetworkMongoClient(MongoClientOptions options) {
if (this.port == null) { if (hasCustomAddress() || hasCustomCredentials()) {
return DEFAULT_PORT; if (this.uri != null) {
} throw new IllegalStateException("Invalid mongo configuration, "
if (this.port == 0) { + "either uri or host/port/credentials must be specified");
if (environment != null) { }
String localPort = environment.getProperty("local.mongo.port"); if (options == null) {
if (localPort != null) { options = MongoClientOptions.builder().build();
return Integer.valueOf(localPort); }
} List<MongoCredential> credentials = new ArrayList<MongoCredential>();
if (hasCustomCredentials()) {
String database = this.authenticationDatabase == null
? getMongoClientDatabase() : this.authenticationDatabase;
credentials.add(MongoCredential.createCredential(this.username,
database, this.password));
} }
throw new IllegalStateException( String host = this.host == null ? "localhost" : this.host;
"spring.data.mongodb.port=0 and no local mongo port configuration " int port = this.port != null ? this.port : DEFAULT_PORT;
+ "is available"); return new MongoClient(
Collections.singletonList(new ServerAddress(host, port)),
credentials, options);
} }
return this.port; // The options and credentials are in the URI
return new MongoClient(new MongoClientURI(determineUri(), builder(options)));
}
private boolean hasCustomAddress() {
return this.host != null || this.port != null;
}
private boolean hasCustomCredentials() {
return this.username != null && this.password != null;
} }
private Builder builder(MongoClientOptions options) { private Builder builder(MongoClientOptions options) {

@ -158,7 +158,6 @@ public class EmbeddedMongoAutoConfiguration {
} }
private void setEmbeddedPort(int port) { private void setEmbeddedPort(int port) {
this.properties.setPort(port);
setPortProperty(this.context, port); setPortProperty(this.context, port);
} }

@ -33,6 +33,7 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties
import org.springframework.boot.test.util.EnvironmentTestUtils; import org.springframework.boot.test.util.EnvironmentTestUtils;
import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.mock.env.MockEnvironment;
import org.springframework.test.util.ReflectionTestUtils; import org.springframework.test.util.ReflectionTestUtils;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
@ -49,6 +50,8 @@ public class MongoPropertiesTests {
@Rule @Rule
public ExpectedException thrown = ExpectedException.none(); public ExpectedException thrown = ExpectedException.none();
private MockEnvironment environment = new MockEnvironment();
@Test @Test
public void canBindCharArrayPassword() { public void canBindCharArrayPassword() {
// gh-1572 // gh-1572
@ -151,6 +154,17 @@ public class MongoPropertiesTests {
properties.createMongoClient(null, null); properties.createMongoClient(null, null);
} }
@Test
public void uriIsIgnoredInEmbeddedMode() throws UnknownHostException {
MongoProperties properties = new MongoProperties();
properties.setUri("mongodb://mongo.example.com:1234/mydb");
this.environment.setProperty("local.mongo.port", "4000");
MongoClient client = properties.createMongoClient(null, this.environment);
List<ServerAddress> allAddresses = extractServerAddresses(client);
assertThat(allAddresses).hasSize(1);
assertServerAddress(allAddresses.get(0), "localhost", 4000);
}
@Test @Test
public void allMongoClientOptionsCanBeSet() throws UnknownHostException { public void allMongoClientOptionsCanBeSet() throws UnknownHostException {
MongoClientOptions.Builder builder = MongoClientOptions.builder(); MongoClientOptions.Builder builder = MongoClientOptions.builder();

Loading…
Cancel
Save