Skip to content

Commit 0d61f92

Browse files
committed
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
1 parent 82d4bf6 commit 0d61f92

File tree

3 files changed

+64
-41
lines changed

3 files changed

+64
-41
lines changed

spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/MongoProperties.java

Lines changed: 50 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -202,59 +202,69 @@ public String getMongoClientDatabase() {
202202
public MongoClient createMongoClient(MongoClientOptions options,
203203
Environment environment) throws UnknownHostException {
204204
try {
205-
if (hasCustomAddress() || hasCustomCredentials()) {
206-
if (this.uri != null) {
207-
throw new IllegalStateException("Invalid mongo configuration, "
208-
+ "either uri or host/port/credentials must be specified");
209-
}
210-
if (options == null) {
211-
options = MongoClientOptions.builder().build();
212-
}
213-
List<MongoCredential> credentials = new ArrayList<MongoCredential>();
214-
if (hasCustomCredentials()) {
215-
String database = this.authenticationDatabase == null
216-
? getMongoClientDatabase() : this.authenticationDatabase;
217-
credentials.add(MongoCredential.createCredential(this.username,
218-
database, this.password));
219-
}
220-
String host = this.host == null ? "localhost" : this.host;
221-
int port = determinePort(environment);
222-
return new MongoClient(
223-
Collections.singletonList(new ServerAddress(host, port)),
224-
credentials, options);
205+
Integer embeddedPort = getEmbeddedPort(environment);
206+
if (embeddedPort != null) {
207+
return createEmbeddedMongoClient(options, embeddedPort);
225208
}
226-
// The options and credentials are in the URI
227-
return new MongoClient(new MongoClientURI(determineUri(), builder(options)));
209+
return createNetworkMongoClient(options);
228210
}
229211
finally {
230212
clearPassword();
231213
}
232214
}
233215

234-
private boolean hasCustomAddress() {
235-
return this.host != null || this.port != null;
216+
private Integer getEmbeddedPort(Environment environment) {
217+
if (environment != null) {
218+
String localPort = environment.getProperty("local.mongo.port");
219+
if (localPort != null) {
220+
return Integer.valueOf(localPort);
221+
}
222+
}
223+
return null;
236224
}
237225

238-
private boolean hasCustomCredentials() {
239-
return this.username != null && this.password != null;
226+
private MongoClient createEmbeddedMongoClient(MongoClientOptions options, int port) {
227+
if (options == null) {
228+
options = MongoClientOptions.builder().build();
229+
}
230+
String host = this.host == null ? "localhost" : this.host;
231+
return new MongoClient(
232+
Collections.singletonList(new ServerAddress(host, port)),
233+
Collections.<MongoCredential>emptyList(), options);
240234
}
241235

242-
private int determinePort(Environment environment) {
243-
if (this.port == null) {
244-
return DEFAULT_PORT;
245-
}
246-
if (this.port == 0) {
247-
if (environment != null) {
248-
String localPort = environment.getProperty("local.mongo.port");
249-
if (localPort != null) {
250-
return Integer.valueOf(localPort);
251-
}
236+
private MongoClient createNetworkMongoClient(MongoClientOptions options) {
237+
if (hasCustomAddress() || hasCustomCredentials()) {
238+
if (this.uri != null) {
239+
throw new IllegalStateException("Invalid mongo configuration, "
240+
+ "either uri or host/port/credentials must be specified");
241+
}
242+
if (options == null) {
243+
options = MongoClientOptions.builder().build();
244+
}
245+
List<MongoCredential> credentials = new ArrayList<MongoCredential>();
246+
if (hasCustomCredentials()) {
247+
String database = this.authenticationDatabase == null
248+
? getMongoClientDatabase() : this.authenticationDatabase;
249+
credentials.add(MongoCredential.createCredential(this.username,
250+
database, this.password));
252251
}
253-
throw new IllegalStateException(
254-
"spring.data.mongodb.port=0 and no local mongo port configuration "
255-
+ "is available");
252+
String host = this.host == null ? "localhost" : this.host;
253+
int port = this.port != null ? this.port : DEFAULT_PORT;
254+
return new MongoClient(
255+
Collections.singletonList(new ServerAddress(host, port)),
256+
credentials, options);
256257
}
257-
return this.port;
258+
// The options and credentials are in the URI
259+
return new MongoClient(new MongoClientURI(determineUri(), builder(options)));
260+
}
261+
262+
private boolean hasCustomAddress() {
263+
return this.host != null || this.port != null;
264+
}
265+
266+
private boolean hasCustomCredentials() {
267+
return this.username != null && this.password != null;
258268
}
259269

260270
private Builder builder(MongoClientOptions options) {

spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/embedded/EmbeddedMongoAutoConfiguration.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,6 @@ private InetAddress getHost() throws UnknownHostException {
158158
}
159159

160160
private void setEmbeddedPort(int port) {
161-
this.properties.setPort(port);
162161
setPortProperty(this.context, port);
163162
}
164163

spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mongo/MongoPropertiesTests.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import org.springframework.boot.test.util.EnvironmentTestUtils;
3434
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
3535
import org.springframework.context.annotation.Configuration;
36+
import org.springframework.mock.env.MockEnvironment;
3637
import org.springframework.test.util.ReflectionTestUtils;
3738

3839
import static org.assertj.core.api.Assertions.assertThat;
@@ -49,6 +50,8 @@ public class MongoPropertiesTests {
4950
@Rule
5051
public ExpectedException thrown = ExpectedException.none();
5152

53+
private MockEnvironment environment = new MockEnvironment();
54+
5255
@Test
5356
public void canBindCharArrayPassword() {
5457
// gh-1572
@@ -151,6 +154,17 @@ public void uriCannotBeSetWithHostPort() throws UnknownHostException {
151154
properties.createMongoClient(null, null);
152155
}
153156

157+
@Test
158+
public void uriIsIgnoredInEmbeddedMode() throws UnknownHostException {
159+
MongoProperties properties = new MongoProperties();
160+
properties.setUri("mongodb://mongo.example.com:1234/mydb");
161+
this.environment.setProperty("local.mongo.port", "4000");
162+
MongoClient client = properties.createMongoClient(null, this.environment);
163+
List<ServerAddress> allAddresses = extractServerAddresses(client);
164+
assertThat(allAddresses).hasSize(1);
165+
assertServerAddress(allAddresses.get(0), "localhost", 4000);
166+
}
167+
154168
@Test
155169
public void allMongoClientOptionsCanBeSet() throws UnknownHostException {
156170
MongoClientOptions.Builder builder = MongoClientOptions.builder();

0 commit comments

Comments
 (0)