Skip to content

Commit 9421c45

Browse files
committed
DATAMONGO-181 - Improved resource handling for Mongo instance.
SimpleMongoDbFactory now only closes the Mongo instance if it created it itself. Removed public getter for WriteConcern and hold a UserCredentials instead of its parts.
1 parent 885c1b0 commit 9421c45

File tree

5 files changed

+93
-75
lines changed

5 files changed

+93
-75
lines changed

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoFactoryBean.java

Lines changed: 43 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2010-2011 the original author or authors.
2+
* Copyright 2010-2012 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -13,15 +13,14 @@
1313
* See the License for the specific language governing permissions and
1414
* limitations under the License.
1515
*/
16-
1716
package org.springframework.data.mongodb.core;
1817

1918
import java.util.Arrays;
2019
import java.util.List;
2120

22-
import org.apache.commons.logging.Log;
23-
import org.apache.commons.logging.LogFactory;
21+
import org.springframework.beans.factory.DisposableBean;
2422
import org.springframework.beans.factory.FactoryBean;
23+
import org.springframework.beans.factory.InitializingBean;
2524
import org.springframework.dao.DataAccessException;
2625
import org.springframework.dao.support.PersistenceExceptionTranslator;
2726
import org.springframework.data.mongodb.CannotGetMongoDbConnectionException;
@@ -39,12 +38,10 @@
3938
* @author Oliver Gierke
4039
* @since 1.0
4140
*/
42-
public class MongoFactoryBean implements FactoryBean<Mongo>, PersistenceExceptionTranslator {
41+
public class MongoFactoryBean implements FactoryBean<Mongo>, InitializingBean, DisposableBean,
42+
PersistenceExceptionTranslator {
4343

44-
/**
45-
* Logger, available to subclasses.
46-
*/
47-
protected final Log logger = LogFactory.getLog(getClass());
44+
private Mongo mongo;
4845

4946
private MongoOptions mongoOptions;
5047
private String host;
@@ -89,9 +86,40 @@ public void setExceptionTranslator(PersistenceExceptionTranslator exceptionTrans
8986
}
9087

9188
public Mongo getObject() throws Exception {
89+
return mongo;
90+
}
9291

93-
Mongo mongo;
92+
/*
93+
* (non-Javadoc)
94+
* @see org.springframework.beans.factory.FactoryBean#getObjectType()
95+
*/
96+
public Class<? extends Mongo> getObjectType() {
97+
return Mongo.class;
98+
}
99+
100+
/*
101+
* (non-Javadoc)
102+
* @see org.springframework.beans.factory.FactoryBean#isSingleton()
103+
*/
104+
public boolean isSingleton() {
105+
return true;
106+
}
94107

108+
/*
109+
* (non-Javadoc)
110+
* @see org.springframework.dao.support.PersistenceExceptionTranslator#translateExceptionIfPossible(java.lang.RuntimeException)
111+
*/
112+
public DataAccessException translateExceptionIfPossible(RuntimeException ex) {
113+
return exceptionTranslator.translateExceptionIfPossible(ex);
114+
}
115+
116+
/*
117+
* (non-Javadoc)
118+
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
119+
*/
120+
public void afterPropertiesSet() throws Exception {
121+
122+
Mongo mongo;
95123
ServerAddress defaultOptions = new ServerAddress();
96124

97125
if (mongoOptions == null) {
@@ -115,31 +143,14 @@ public Mongo getObject() throws Exception {
115143
mongo.setWriteConcern(writeConcern);
116144
}
117145

118-
return mongo;
119-
146+
this.mongo = mongo;
120147
}
121148

122-
/*
149+
/*
123150
* (non-Javadoc)
124-
* @see org.springframework.beans.factory.FactoryBean#getObjectType()
151+
* @see org.springframework.beans.factory.DisposableBean#destroy()
125152
*/
126-
public Class<? extends Mongo> getObjectType() {
127-
return Mongo.class;
128-
}
129-
130-
/*
131-
* (non-Javadoc)
132-
* @see org.springframework.beans.factory.FactoryBean#isSingleton()
133-
*/
134-
public boolean isSingleton() {
135-
return true;
136-
}
137-
138-
/*
139-
* (non-Javadoc)
140-
* @see org.springframework.dao.support.PersistenceExceptionTranslator#translateExceptionIfPossible(java.lang.RuntimeException)
141-
*/
142-
public DataAccessException translateExceptionIfPossible(RuntimeException ex) {
143-
return exceptionTranslator.translateExceptionIfPossible(ex);
153+
public void destroy() throws Exception {
154+
this.mongo.close();
144155
}
145156
}

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/SimpleMongoDbFactory.java

Lines changed: 32 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@
1717

1818
import java.net.UnknownHostException;
1919

20-
import org.apache.commons.logging.Log;
21-
import org.apache.commons.logging.LogFactory;
2220
import org.springframework.beans.factory.DisposableBean;
2321
import org.springframework.dao.DataAccessException;
2422
import org.springframework.data.authentication.UserCredentials;
@@ -39,12 +37,10 @@
3937
*/
4038
public class SimpleMongoDbFactory implements DisposableBean, MongoDbFactory {
4139

42-
protected final Log logger = LogFactory.getLog(getClass());
43-
4440
private final Mongo mongo;
4541
private final String databaseName;
46-
private String username;
47-
private String password;
42+
private final boolean mongoInstanceCreated;
43+
private final UserCredentials credentials;
4844
private WriteConcern writeConcern;
4945

5046
/**
@@ -54,25 +50,18 @@ public class SimpleMongoDbFactory implements DisposableBean, MongoDbFactory {
5450
* @param databaseName database name, not be {@literal null}.
5551
*/
5652
public SimpleMongoDbFactory(Mongo mongo, String databaseName) {
57-
Assert.notNull(mongo, "Mongo must not be null");
58-
Assert.hasText(databaseName, "Database name must not be empty");
59-
Assert.isTrue(databaseName.matches("[\\w-]+"),
60-
"Database name must only contain letters, numbers, underscores and dashes!");
61-
this.mongo = mongo;
62-
this.databaseName = databaseName;
53+
this(mongo, databaseName, new UserCredentials(), false);
6354
}
6455

6556
/**
6657
* Create an instance of SimpleMongoDbFactory given the Mongo instance, database name, and username/password
6758
*
6859
* @param mongo Mongo instance, must not be {@literal null}.
6960
* @param databaseName Database name, must not be {@literal null}.
70-
* @param userCredentials username and password must not be {@literal null}.
61+
* @param credentials username and password.
7162
*/
72-
public SimpleMongoDbFactory(Mongo mongo, String databaseName, UserCredentials userCredentials) {
73-
this(mongo, databaseName);
74-
this.username = userCredentials.getUsername();
75-
this.password = userCredentials.getPassword();
63+
public SimpleMongoDbFactory(Mongo mongo, String databaseName, UserCredentials credentials) {
64+
this(mongo, databaseName, credentials, false);
7665
}
7766

7867
/**
@@ -84,7 +73,21 @@ public SimpleMongoDbFactory(Mongo mongo, String databaseName, UserCredentials us
8473
* @see MongoURI
8574
*/
8675
public SimpleMongoDbFactory(MongoURI uri) throws MongoException, UnknownHostException {
87-
this(new Mongo(uri), uri.getDatabase(), new UserCredentials(uri.getUsername(), parseChars(uri.getPassword())));
76+
this(new Mongo(uri), uri.getDatabase(), new UserCredentials(uri.getUsername(), parseChars(uri.getPassword())), true);
77+
}
78+
79+
private SimpleMongoDbFactory(Mongo mongo, String databaseName, UserCredentials credentials,
80+
boolean mongoInstanceCreated) {
81+
82+
Assert.notNull(mongo, "Mongo must not be null");
83+
Assert.hasText(databaseName, "Database name must not be empty");
84+
Assert.isTrue(databaseName.matches("[\\w-]+"),
85+
"Database name must only contain letters, numbers, underscores and dashes!");
86+
87+
this.mongo = mongo;
88+
this.databaseName = databaseName;
89+
this.mongoInstanceCreated = mongoInstanceCreated;
90+
this.credentials = credentials == null ? new UserCredentials() : credentials;
8891
}
8992

9093
/**
@@ -96,10 +99,6 @@ public void setWriteConcern(WriteConcern writeConcern) {
9699
this.writeConcern = writeConcern;
97100
}
98101

99-
public WriteConcern getWriteConcern() {
100-
return writeConcern;
101-
}
102-
103102
/*
104103
* (non-Javadoc)
105104
* @see org.springframework.data.mongodb.MongoDbFactory#getDb()
@@ -116,6 +115,9 @@ public DB getDb(String dbName) throws DataAccessException {
116115

117116
Assert.hasText(dbName, "Database name must not be empty.");
118117

118+
String username = credentials.getUsername();
119+
String password = credentials.getPassword();
120+
119121
DB db = MongoDbUtils.getDB(mongo, dbName, username, password == null ? null : password.toCharArray());
120122

121123
if (writeConcern != null) {
@@ -126,17 +128,17 @@ public DB getDb(String dbName) throws DataAccessException {
126128
}
127129

128130
/**
129-
* Clean up the Mongo instance.
131+
* Clean up the Mongo instance if it was created by the factory itself.
132+
*
133+
* @see DisposableBean#destroy()
130134
*/
131135
public void destroy() throws Exception {
132-
mongo.close();
136+
if (mongoInstanceCreated) {
137+
mongo.close();
138+
}
133139
}
134140

135-
public static String parseChars(char[] chars) {
136-
if (chars == null) {
137-
return null;
138-
} else {
139-
return String.valueOf(chars);
140-
}
141+
private static String parseChars(char[] chars) {
142+
return chars == null ? null : String.valueOf(chars);
141143
}
142144
}

spring-data-mongodb/src/test/java/org/springframework/data/mongodb/config/MongoDbFactoryParserIntegrationTests.java

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import org.springframework.core.io.ClassPathResource;
3333
import org.springframework.data.mongodb.MongoDbFactory;
3434
import org.springframework.data.mongodb.core.SimpleMongoDbFactory;
35+
import org.springframework.test.util.ReflectionTestUtils;
3536

3637
import com.mongodb.DB;
3738
import com.mongodb.Mongo;
@@ -59,7 +60,7 @@ public void testWriteConcern() throws Exception {
5960
SimpleMongoDbFactory dbFactory = new SimpleMongoDbFactory(new Mongo("localhost"), "database");
6061
dbFactory.setWriteConcern(WriteConcern.SAFE);
6162
dbFactory.getDb();
62-
assertThat(WriteConcern.SAFE, is(dbFactory.getWriteConcern()));
63+
assertThat(ReflectionTestUtils.getField(dbFactory, "writeConcern"), is((Object) WriteConcern.SAFE));
6364
}
6465

6566
@Test
@@ -91,15 +92,17 @@ public void readsReplicasWriteConcernCorrectly() {
9192
private void assertWriteConcern(ClassPathXmlApplicationContext ctx, WriteConcern expectedWriteConcern) {
9293
SimpleMongoDbFactory dbFactory = ctx.getBean("first", SimpleMongoDbFactory.class);
9394
DB db = dbFactory.getDb();
94-
assertThat("db", is(db.getName()));
95+
assertThat(db.getName(), is("db"));
9596

96-
MyWriteConcern myDbFactoryWriteConcern = new MyWriteConcern(dbFactory.getWriteConcern());
97+
WriteConcern configuredConcern = (WriteConcern) ReflectionTestUtils.getField(dbFactory, "writeConcern");
98+
99+
MyWriteConcern myDbFactoryWriteConcern = new MyWriteConcern(configuredConcern);
97100
MyWriteConcern myDbWriteConcern = new MyWriteConcern(db.getWriteConcern());
98101
MyWriteConcern myExpectedWriteConcern = new MyWriteConcern(expectedWriteConcern);
99102

100-
assertThat(myDbFactoryWriteConcern, equalTo(myExpectedWriteConcern));
101-
assertThat(myDbWriteConcern, equalTo(myExpectedWriteConcern));
102-
assertThat(myDbWriteConcern, equalTo(myDbFactoryWriteConcern));
103+
assertThat(myDbFactoryWriteConcern, is(myExpectedWriteConcern));
104+
assertThat(myDbWriteConcern, is(myExpectedWriteConcern));
105+
assertThat(myDbWriteConcern, is(myDbFactoryWriteConcern));
103106
}
104107

105108
// This test will fail since equals in WriteConcern uses == for _w and not .equals
@@ -108,7 +111,7 @@ public void testWriteConcernEquality() {
108111
String s2 = new String("rack1");
109112
WriteConcern wc1 = new WriteConcern(s1);
110113
WriteConcern wc2 = new WriteConcern(s2);
111-
assertThat(wc1, equalTo(wc2));
114+
assertThat(wc1, is(wc2));
112115
}
113116

114117
@Test

spring-data-mongodb/src/test/java/org/springframework/data/mongodb/config/MongoNamespaceTests.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,19 @@
1616

1717
package org.springframework.data.mongodb.config;
1818

19-
import static org.springframework.test.util.ReflectionTestUtils.*;
2019
import static org.junit.Assert.*;
20+
import static org.springframework.test.util.ReflectionTestUtils.*;
2121

2222
import org.junit.Test;
2323
import org.junit.runner.RunWith;
2424
import org.springframework.beans.factory.annotation.Autowired;
2525
import org.springframework.context.ApplicationContext;
26+
import org.springframework.data.authentication.UserCredentials;
2627
import org.springframework.data.mongodb.MongoDbFactory;
2728
import org.springframework.data.mongodb.core.MongoFactoryBean;
2829
import org.springframework.test.context.ContextConfiguration;
2930
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
31+
3032
import com.mongodb.Mongo;
3133
import com.mongodb.MongoOptions;
3234

@@ -62,8 +64,7 @@ public void testSecondMongoDbFactory() throws Exception {
6264
Mongo mongo = (Mongo) getField(dbf, "mongo");
6365
assertEquals("localhost", mongo.getAddress().getHost());
6466
assertEquals(27017, mongo.getAddress().getPort());
65-
assertEquals("joe", getField(dbf, "username"));
66-
assertEquals("secret", getField(dbf, "password"));
67+
assertEquals(new UserCredentials("joe", "secret"), getField(dbf, "credentials"));
6768
assertEquals("database", getField(dbf, "databaseName"));
6869
}
6970

spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/SimpleMongoDbFactoryUnitTests.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,16 @@
1515
*/
1616
package org.springframework.data.mongodb.core;
1717

18-
import static org.junit.Assert.*;
1918
import static org.hamcrest.CoreMatchers.*;
19+
import static org.junit.Assert.*;
2020

2121
import java.net.UnknownHostException;
2222

2323
import org.junit.Test;
2424
import org.junit.runner.RunWith;
2525
import org.mockito.Mock;
2626
import org.mockito.runners.MockitoJUnitRunner;
27+
import org.springframework.data.authentication.UserCredentials;
2728
import org.springframework.data.mongodb.MongoDbFactory;
2829
import org.springframework.test.util.ReflectionTestUtils;
2930

@@ -70,8 +71,8 @@ public void mongoUriConstructor() throws UnknownHostException {
7071
MongoURI mongoURI = new MongoURI("mongodb://myUsername:myPassword@localhost/myDatabase.myCollection");
7172
MongoDbFactory mongoDbFactory = new SimpleMongoDbFactory(mongoURI);
7273

73-
assertThat(ReflectionTestUtils.getField(mongoDbFactory, "username").toString(), is("myUsername"));
74-
assertThat(ReflectionTestUtils.getField(mongoDbFactory, "password").toString(), is("myPassword"));
74+
assertThat(ReflectionTestUtils.getField(mongoDbFactory, "credentials"), is((Object) new UserCredentials(
75+
"myUsername", "myPassword")));
7576
assertThat(ReflectionTestUtils.getField(mongoDbFactory, "databaseName").toString(), is("myDatabase"));
7677
assertThat(ReflectionTestUtils.getField(mongoDbFactory, "databaseName").toString(), is("myDatabase"));
7778
}

0 commit comments

Comments
 (0)