Browse Source

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. Uses improved UserCredentials API introduced in DATACMNS-142.
pull/2/merge
Oliver Gierke 14 years ago
parent
commit
6373a70ca4
  1. 67
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoFactoryBean.java
  2. 60
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/SimpleMongoDbFactory.java
  3. 17
      spring-data-mongodb/src/test/java/org/springframework/data/mongodb/config/MongoDbFactoryParserIntegrationTests.java
  4. 7
      spring-data-mongodb/src/test/java/org/springframework/data/mongodb/config/MongoNamespaceTests.java
  5. 7
      spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/SimpleMongoDbFactoryUnitTests.java

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

@ -18,7 +18,9 @@ package org.springframework.data.mongodb.core; @@ -18,7 +18,9 @@ package org.springframework.data.mongodb.core;
import java.util.Arrays;
import java.util.List;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.support.PersistenceExceptionTranslator;
import org.springframework.data.mongodb.CannotGetMongoDbConnectionException;
@ -36,7 +38,10 @@ import com.mongodb.WriteConcern; @@ -36,7 +38,10 @@ import com.mongodb.WriteConcern;
* @author Oliver Gierke
* @since 1.0
*/
public class MongoFactoryBean implements FactoryBean<Mongo>, PersistenceExceptionTranslator {
public class MongoFactoryBean implements FactoryBean<Mongo>, InitializingBean, DisposableBean,
PersistenceExceptionTranslator {
private Mongo mongo;
private MongoOptions mongoOptions;
private String host;
@ -81,9 +86,40 @@ public class MongoFactoryBean implements FactoryBean<Mongo>, PersistenceExceptio @@ -81,9 +86,40 @@ public class MongoFactoryBean implements FactoryBean<Mongo>, PersistenceExceptio
}
public Mongo getObject() throws Exception {
return mongo;
}
Mongo mongo;
/*
* (non-Javadoc)
* @see org.springframework.beans.factory.FactoryBean#getObjectType()
*/
public Class<? extends Mongo> getObjectType() {
return Mongo.class;
}
/*
* (non-Javadoc)
* @see org.springframework.beans.factory.FactoryBean#isSingleton()
*/
public boolean isSingleton() {
return true;
}
/*
* (non-Javadoc)
* @see org.springframework.dao.support.PersistenceExceptionTranslator#translateExceptionIfPossible(java.lang.RuntimeException)
*/
public DataAccessException translateExceptionIfPossible(RuntimeException ex) {
return exceptionTranslator.translateExceptionIfPossible(ex);
}
/*
* (non-Javadoc)
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
*/
public void afterPropertiesSet() throws Exception {
Mongo mongo;
ServerAddress defaultOptions = new ServerAddress();
if (mongoOptions == null) {
@ -107,31 +143,14 @@ public class MongoFactoryBean implements FactoryBean<Mongo>, PersistenceExceptio @@ -107,31 +143,14 @@ public class MongoFactoryBean implements FactoryBean<Mongo>, PersistenceExceptio
mongo.setWriteConcern(writeConcern);
}
return mongo;
}
/*
* (non-Javadoc)
* @see org.springframework.beans.factory.FactoryBean#getObjectType()
*/
public Class<? extends Mongo> getObjectType() {
return Mongo.class;
}
/*
* (non-Javadoc)
* @see org.springframework.beans.factory.FactoryBean#isSingleton()
*/
public boolean isSingleton() {
return true;
this.mongo = mongo;
}
/*
/*
* (non-Javadoc)
* @see org.springframework.dao.support.PersistenceExceptionTranslator#translateExceptionIfPossible(java.lang.RuntimeException)
* @see org.springframework.beans.factory.DisposableBean#destroy()
*/
public DataAccessException translateExceptionIfPossible(RuntimeException ex) {
return exceptionTranslator.translateExceptionIfPossible(ex);
public void destroy() throws Exception {
this.mongo.close();
}
}

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

@ -39,8 +39,8 @@ public class SimpleMongoDbFactory implements DisposableBean, MongoDbFactory { @@ -39,8 +39,8 @@ public class SimpleMongoDbFactory implements DisposableBean, MongoDbFactory {
private final Mongo mongo;
private final String databaseName;
private String username;
private String password;
private final boolean mongoInstanceCreated;
private final UserCredentials credentials;
private WriteConcern writeConcern;
/**
@ -50,12 +50,7 @@ public class SimpleMongoDbFactory implements DisposableBean, MongoDbFactory { @@ -50,12 +50,7 @@ public class SimpleMongoDbFactory implements DisposableBean, MongoDbFactory {
* @param databaseName database name, not be {@literal null}.
*/
public SimpleMongoDbFactory(Mongo mongo, String databaseName) {
Assert.notNull(mongo, "Mongo must not be null");
Assert.hasText(databaseName, "Database name must not be empty");
Assert.isTrue(databaseName.matches("[\\w-]+"),
"Database name must only contain letters, numbers, underscores and dashes!");
this.mongo = mongo;
this.databaseName = databaseName;
this(mongo, databaseName, UserCredentials.NO_CREDENTIALS, false);
}
/**
@ -63,12 +58,10 @@ public class SimpleMongoDbFactory implements DisposableBean, MongoDbFactory { @@ -63,12 +58,10 @@ public class SimpleMongoDbFactory implements DisposableBean, MongoDbFactory {
*
* @param mongo Mongo instance, must not be {@literal null}.
* @param databaseName Database name, must not be {@literal null}.
* @param userCredentials username and password must not be {@literal null}.
* @param credentials username and password.
*/
public SimpleMongoDbFactory(Mongo mongo, String databaseName, UserCredentials userCredentials) {
this(mongo, databaseName);
this.username = userCredentials.getUsername();
this.password = userCredentials.getPassword();
public SimpleMongoDbFactory(Mongo mongo, String databaseName, UserCredentials credentials) {
this(mongo, databaseName, credentials, false);
}
/**
@ -80,7 +73,21 @@ public class SimpleMongoDbFactory implements DisposableBean, MongoDbFactory { @@ -80,7 +73,21 @@ public class SimpleMongoDbFactory implements DisposableBean, MongoDbFactory {
* @see MongoURI
*/
public SimpleMongoDbFactory(MongoURI uri) throws MongoException, UnknownHostException {
this(new Mongo(uri), uri.getDatabase(), new UserCredentials(uri.getUsername(), parseChars(uri.getPassword())));
this(new Mongo(uri), uri.getDatabase(), new UserCredentials(uri.getUsername(), parseChars(uri.getPassword())), true);
}
private SimpleMongoDbFactory(Mongo mongo, String databaseName, UserCredentials credentials,
boolean mongoInstanceCreated) {
Assert.notNull(mongo, "Mongo must not be null");
Assert.hasText(databaseName, "Database name must not be empty");
Assert.isTrue(databaseName.matches("[\\w-]+"),
"Database name must only contain letters, numbers, underscores and dashes!");
this.mongo = mongo;
this.databaseName = databaseName;
this.mongoInstanceCreated = mongoInstanceCreated;
this.credentials = credentials == null ? UserCredentials.NO_CREDENTIALS : credentials;
}
/**
@ -92,10 +99,6 @@ public class SimpleMongoDbFactory implements DisposableBean, MongoDbFactory { @@ -92,10 +99,6 @@ public class SimpleMongoDbFactory implements DisposableBean, MongoDbFactory {
this.writeConcern = writeConcern;
}
public WriteConcern getWriteConcern() {
return writeConcern;
}
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.MongoDbFactory#getDb()
@ -112,7 +115,10 @@ public class SimpleMongoDbFactory implements DisposableBean, MongoDbFactory { @@ -112,7 +115,10 @@ public class SimpleMongoDbFactory implements DisposableBean, MongoDbFactory {
Assert.hasText(dbName, "Database name must not be empty.");
DB db = MongoDbUtils.getDB(mongo, dbName, username, password == null ? null : password.toCharArray());
String username = credentials.getUsername();
char[] password = credentials.hasPassword() ? credentials.getPassword().toCharArray() : null;
DB db = MongoDbUtils.getDB(mongo, dbName, username, password);
if (writeConcern != null) {
db.setWriteConcern(writeConcern);
@ -122,17 +128,17 @@ public class SimpleMongoDbFactory implements DisposableBean, MongoDbFactory { @@ -122,17 +128,17 @@ public class SimpleMongoDbFactory implements DisposableBean, MongoDbFactory {
}
/**
* Clean up the Mongo instance.
* Clean up the Mongo instance if it was created by the factory itself.
*
* @see DisposableBean#destroy()
*/
public void destroy() throws Exception {
mongo.close();
if (mongoInstanceCreated) {
mongo.close();
}
}
public static String parseChars(char[] chars) {
if (chars == null) {
return null;
} else {
return String.valueOf(chars);
}
private static String parseChars(char[] chars) {
return chars == null ? null : String.valueOf(chars);
}
}

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

@ -32,6 +32,7 @@ import org.springframework.context.support.ClassPathXmlApplicationContext; @@ -32,6 +32,7 @@ import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.ClassPathResource;
import org.springframework.data.mongodb.MongoDbFactory;
import org.springframework.data.mongodb.core.SimpleMongoDbFactory;
import org.springframework.test.util.ReflectionTestUtils;
import com.mongodb.DB;
import com.mongodb.Mongo;
@ -59,7 +60,7 @@ public class MongoDbFactoryParserIntegrationTests { @@ -59,7 +60,7 @@ public class MongoDbFactoryParserIntegrationTests {
SimpleMongoDbFactory dbFactory = new SimpleMongoDbFactory(new Mongo("localhost"), "database");
dbFactory.setWriteConcern(WriteConcern.SAFE);
dbFactory.getDb();
assertThat(WriteConcern.SAFE, is(dbFactory.getWriteConcern()));
assertThat(ReflectionTestUtils.getField(dbFactory, "writeConcern"), is((Object) WriteConcern.SAFE));
}
@Test
@ -91,15 +92,17 @@ public class MongoDbFactoryParserIntegrationTests { @@ -91,15 +92,17 @@ public class MongoDbFactoryParserIntegrationTests {
private void assertWriteConcern(ClassPathXmlApplicationContext ctx, WriteConcern expectedWriteConcern) {
SimpleMongoDbFactory dbFactory = ctx.getBean("first", SimpleMongoDbFactory.class);
DB db = dbFactory.getDb();
assertThat("db", is(db.getName()));
assertThat(db.getName(), is("db"));
MyWriteConcern myDbFactoryWriteConcern = new MyWriteConcern(dbFactory.getWriteConcern());
WriteConcern configuredConcern = (WriteConcern) ReflectionTestUtils.getField(dbFactory, "writeConcern");
MyWriteConcern myDbFactoryWriteConcern = new MyWriteConcern(configuredConcern);
MyWriteConcern myDbWriteConcern = new MyWriteConcern(db.getWriteConcern());
MyWriteConcern myExpectedWriteConcern = new MyWriteConcern(expectedWriteConcern);
assertThat(myDbFactoryWriteConcern, equalTo(myExpectedWriteConcern));
assertThat(myDbWriteConcern, equalTo(myExpectedWriteConcern));
assertThat(myDbWriteConcern, equalTo(myDbFactoryWriteConcern));
assertThat(myDbFactoryWriteConcern, is(myExpectedWriteConcern));
assertThat(myDbWriteConcern, is(myExpectedWriteConcern));
assertThat(myDbWriteConcern, is(myDbFactoryWriteConcern));
}
// This test will fail since equals in WriteConcern uses == for _w and not .equals
@ -108,7 +111,7 @@ public class MongoDbFactoryParserIntegrationTests { @@ -108,7 +111,7 @@ public class MongoDbFactoryParserIntegrationTests {
String s2 = new String("rack1");
WriteConcern wc1 = new WriteConcern(s1);
WriteConcern wc2 = new WriteConcern(s2);
assertThat(wc1, equalTo(wc2));
assertThat(wc1, is(wc2));
}
@Test

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

@ -16,17 +16,19 @@ @@ -16,17 +16,19 @@
package org.springframework.data.mongodb.config;
import static org.springframework.test.util.ReflectionTestUtils.*;
import static org.junit.Assert.*;
import static org.springframework.test.util.ReflectionTestUtils.*;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.data.authentication.UserCredentials;
import org.springframework.data.mongodb.MongoDbFactory;
import org.springframework.data.mongodb.core.MongoFactoryBean;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.mongodb.Mongo;
import com.mongodb.MongoOptions;
@ -62,8 +64,7 @@ public class MongoNamespaceTests { @@ -62,8 +64,7 @@ public class MongoNamespaceTests {
Mongo mongo = (Mongo) getField(dbf, "mongo");
assertEquals("localhost", mongo.getAddress().getHost());
assertEquals(27017, mongo.getAddress().getPort());
assertEquals("joe", getField(dbf, "username"));
assertEquals("secret", getField(dbf, "password"));
assertEquals(new UserCredentials("joe", "secret"), getField(dbf, "credentials"));
assertEquals("database", getField(dbf, "databaseName"));
}

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

@ -15,8 +15,8 @@ @@ -15,8 +15,8 @@
*/
package org.springframework.data.mongodb.core;
import static org.junit.Assert.*;
import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;
import java.net.UnknownHostException;
@ -24,6 +24,7 @@ import org.junit.Test; @@ -24,6 +24,7 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import org.springframework.data.authentication.UserCredentials;
import org.springframework.data.mongodb.MongoDbFactory;
import org.springframework.test.util.ReflectionTestUtils;
@ -70,8 +71,8 @@ public class SimpleMongoDbFactoryUnitTests { @@ -70,8 +71,8 @@ public class SimpleMongoDbFactoryUnitTests {
MongoURI mongoURI = new MongoURI("mongodb://myUsername:myPassword@localhost/myDatabase.myCollection");
MongoDbFactory mongoDbFactory = new SimpleMongoDbFactory(mongoURI);
assertThat(ReflectionTestUtils.getField(mongoDbFactory, "username").toString(), is("myUsername"));
assertThat(ReflectionTestUtils.getField(mongoDbFactory, "password").toString(), is("myPassword"));
assertThat(ReflectionTestUtils.getField(mongoDbFactory, "credentials"), is((Object) new UserCredentials(
"myUsername", "myPassword")));
assertThat(ReflectionTestUtils.getField(mongoDbFactory, "databaseName").toString(), is("myDatabase"));
assertThat(ReflectionTestUtils.getField(mongoDbFactory, "databaseName").toString(), is("myDatabase"));
}

Loading…
Cancel
Save