DATAMONGO-1158 - Polishing.

MongoFactoryBean, MongoOptionsFactoryBean, MongoClientFactoryBean and MongoClientOptionsFactoryBean now extend AbstractFactoryBean to get a lot of the lifecycle callbacks without further code.

Added non-null assertions to newly introduced methods on MongoOperations/MongoTemplate.

Moved MongoClientVersion into util package. Introduced static imports for ReflectionUtils and MongoClientVersion for all references in the newly introduced Invoker types.

Some formatting, JavaDoc polishes, suppress deprecation warnings. Added build profile for MongoDB Java driver 3.0 as well as the following snapshot.

Original pull request: #273.
This commit is contained in:
Oliver Gierke
2015-03-02 19:54:46 +01:00
parent 57ab27aa5b
commit a86d704bec
35 changed files with 414 additions and 390 deletions

11
pom.xml
View File

@@ -122,7 +122,16 @@
<profile>
<id>mongo-3-next</id>
<id>mongo3</id>
<properties>
<mongo>3.0.0-beta3</mongo>
</properties>
</profile>
<profile>
<id>mongo3-next</id>
<properties>
<mongo>3.0.0-SNAPSHOT</mongo>
</properties>

View File

@@ -82,5 +82,4 @@ public class MongoClientParser implements BeanDefinitionParser {
return mongoComponent.getBeanDefinition();
}
}

View File

@@ -38,6 +38,10 @@ public class MongoCredentialPropertyEditor extends PropertyEditorSupport {
private static final String OPTIONS_DELIMINATOR = "?";
private static final String OPTION_VALUE_DELIMINATOR = "&";
/*
* (non-Javadoc)
* @see java.beans.PropertyEditorSupport#setAsText(java.lang.String)
*/
@Override
public void setAsText(String text) throws IllegalArgumentException {
@@ -46,6 +50,7 @@ public class MongoCredentialPropertyEditor extends PropertyEditorSupport {
}
List<MongoCredential> credentials = new ArrayList<MongoCredential>();
for (String credentialString : text.split(",")) {
if (!text.contains(USERNAME_PASSWORD_DELIMINATOR) || !text.contains(DATABASE_DELIMINATOR)) {
@@ -57,8 +62,11 @@ public class MongoCredentialPropertyEditor extends PropertyEditorSupport {
Properties options = extractOptions(credentialString);
if (!options.isEmpty()) {
if (options.containsKey(AUTH_MECHANISM_KEY)) {
String authMechanism = options.getProperty(AUTH_MECHANISM_KEY);
if (MongoCredential.GSSAPI_MECHANISM.equals(authMechanism)) {
credentials.add(MongoCredential.createGSSAPICredential(userNameAndPassword[0]));
} else if (MongoCredential.MONGODB_CR_MECHANISM.equals(authMechanism)) {
@@ -86,14 +94,14 @@ public class MongoCredentialPropertyEditor extends PropertyEditorSupport {
setValue(credentials);
}
private String[] extractUserNameAndPassword(String text) {
private static String[] extractUserNameAndPassword(String text) {
int dbSeperationIndex = text.lastIndexOf(DATABASE_DELIMINATOR);
String userNameAndPassword = text.substring(0, dbSeperationIndex);
return userNameAndPassword.split(USERNAME_PASSWORD_DELIMINATOR);
}
private String extractDB(String text) {
private static String extractDB(String text) {
int dbSeperationIndex = text.lastIndexOf(DATABASE_DELIMINATOR);
@@ -103,7 +111,7 @@ public class MongoCredentialPropertyEditor extends PropertyEditorSupport {
return optionsSeperationIndex > -1 ? tmp.substring(0, optionsSeperationIndex) : tmp;
}
private Properties extractOptions(String text) {
private static Properties extractOptions(String text) {
int optionsSeperationIndex = text.lastIndexOf(OPTIONS_DELIMINATOR);
int dbSeperationIndex = text.lastIndexOf(OPTIONS_DELIMINATOR);

View File

@@ -37,11 +37,10 @@ import org.w3c.dom.Element;
* @author Thomas Darimont
* @author Christoph Strobl
*/
@SuppressWarnings("deprecation")
abstract class MongoParsingUtils {
private MongoParsingUtils() {
}
private MongoParsingUtils() {}
/**
* Parses the mongo replica-set element.
@@ -56,12 +55,14 @@ abstract class MongoParsingUtils {
}
/**
* Parses the mongo:options sub-element. Populates the given attribute factory with the proper attributes.
* Parses the {@code mongo:options} sub-element. Populates the given attribute factory with the proper attributes.
*
* @return true if parsing actually occured, false otherwise
* @return true if parsing actually occured, {@literal false} otherwise
*/
static boolean parseMongoOptions(Element element, BeanDefinitionBuilder mongoBuilder) {
Element optionsElement = DomUtils.getChildElementByTagName(element, "options");
if (optionsElement == null) {
return false;
}
@@ -90,14 +91,18 @@ abstract class MongoParsingUtils {
}
/**
* @param element
* @param mongoClientBuilder
* Parses the {@code mongo:client-options} sub-element. Populates the given attribute factory with the proper
* attributes.
*
* @param element must not be {@literal null}.
* @param mongoClientBuilder must not be {@literal null}.
* @return
* @since 1.7
*/
public static boolean parseMongoClientOptions(Element element, BeanDefinitionBuilder mongoClientBuilder) {
Element optionsElement = DomUtils.getChildElementByTagName(element, "client-options");
if (optionsElement == null) {
return false;
}

View File

@@ -27,6 +27,10 @@ import com.mongodb.ReadPreference;
*/
public class ReadPreferencePropertyEditor extends PropertyEditorSupport {
/*
* (non-Javadoc)
* @see java.beans.PropertyEditorSupport#setAsText(java.lang.String)
*/
@Override
public void setAsText(String readPreferenceString) throws IllegalArgumentException {
@@ -35,6 +39,7 @@ public class ReadPreferencePropertyEditor extends PropertyEditorSupport {
}
ReadPreference preference = null;
try {
preference = ReadPreference.valueOf(readPreferenceString);
} catch (IllegalArgumentException ex) {

View File

@@ -52,8 +52,8 @@ public interface IndexOperations {
/**
* Clears all indices that have not yet been applied to this collection.
*
* @deprecated since 1.7. The mongo-java-driver version 3 does no longer support reseting the index cache.
* @throws {@link UnsupportedOperationException} when used with mongo-java-driver version 3.
* @deprecated since 1.7. The MongoDB Java driver version 3.0 does no longer support reseting the index cache.
* @throws {@link UnsupportedOperationException} when used with MongoDB Java driver version 3.0.
*/
@Deprecated
void resetIndexCache();

View File

@@ -20,9 +20,7 @@ import java.util.ArrayList;
import java.util.Collections;
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.beans.factory.config.AbstractFactoryBean;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.support.PersistenceExceptionTranslator;
import org.springframework.util.CollectionUtils;
@@ -40,19 +38,17 @@ import com.mongodb.ServerAddress;
* @author Christoph Strobl
* @since 1.7
*/
public class MongoClientFactoryBean implements FactoryBean<Mongo>, InitializingBean, DisposableBean,
PersistenceExceptionTranslator {
public class MongoClientFactoryBean extends AbstractFactoryBean<Mongo> implements PersistenceExceptionTranslator {
private MongoClient mongo;
private static final PersistenceExceptionTranslator DEFAULT_EXCEPTION_TRANSLATOR = new MongoExceptionTranslator();
private MongoClientOptions mongoClientOptions;
private String host;
private Integer port;
private List<ServerAddress> replicaSetSeeds;
private List<MongoCredential> credentials;
private PersistenceExceptionTranslator exceptionTranslator = new MongoExceptionTranslator();
private PersistenceExceptionTranslator exceptionTranslator = DEFAULT_EXCEPTION_TRANSLATOR;
/**
* Set the {@link MongoClientOptions} to be used when creating {@link MongoClient}.
@@ -72,15 +68,109 @@ public class MongoClientFactoryBean implements FactoryBean<Mongo>, InitializingB
this.credentials = filterNonNullElementsAsList(credentials);
}
/**
* Set the list of {@link ServerAddress} to build up a replica set for.
*
* @param replicaSetSeeds can be {@literal null}.
*/
public void setReplicaSetSeeds(ServerAddress[] replicaSetSeeds) {
this.replicaSetSeeds = filterNonNullElementsAsList(replicaSetSeeds);
}
/**
* @param elements the elements to filter <T>
* @return a new unmodifiable {@link List#} from the given elements without nulls
* Configures the host to connect to.
*
* @param host
*/
private <T> List<T> filterNonNullElementsAsList(T[] elements) {
public void setHost(String host) {
this.host = host;
}
/**
* Configures the port to connect to.
*
* @param port
*/
public void setPort(int port) {
this.port = port;
}
/**
* Configures the {@link PersistenceExceptionTranslator} to use.
*
* @param exceptionTranslator
*/
public void setExceptionTranslator(PersistenceExceptionTranslator exceptionTranslator) {
this.exceptionTranslator = exceptionTranslator == null ? DEFAULT_EXCEPTION_TRANSLATOR : exceptionTranslator;
}
/*
* (non-Javadoc)
* @see org.springframework.beans.factory.FactoryBean#getObjectType()
*/
public Class<? extends Mongo> getObjectType() {
return Mongo.class;
}
/*
* (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.config.AbstractFactoryBean#createInstance()
*/
@Override
protected Mongo createInstance() throws Exception {
if (mongoClientOptions == null) {
mongoClientOptions = MongoClientOptions.builder().build();
}
if (credentials == null) {
credentials = Collections.emptyList();
}
return createMongoClient();
}
/*
* (non-Javadoc)
* @see org.springframework.beans.factory.config.AbstractFactoryBean#destroyInstance(java.lang.Object)
*/
@Override
protected void destroyInstance(Mongo instance) throws Exception {
instance.close();
}
private MongoClient createMongoClient() throws UnknownHostException {
if (!CollectionUtils.isEmpty(replicaSetSeeds)) {
return new MongoClient(replicaSetSeeds, credentials, mongoClientOptions);
}
return new MongoClient(createConfiguredOrDefaultServerAddress(), credentials, mongoClientOptions);
}
private ServerAddress createConfiguredOrDefaultServerAddress() throws UnknownHostException {
ServerAddress defaultAddress = new ServerAddress();
return new ServerAddress(StringUtils.hasText(host) ? host : defaultAddress.getHost(),
port != null ? port.intValue() : defaultAddress.getPort());
}
/**
* Returns the given array as {@link List} with all {@literal null} elements removed.
*
* @param elements the elements to filter <T>, can be {@literal null}.
* @return a new unmodifiable {@link List#} from the given elements without {@literal null}s.
*/
private static <T> List<T> filterNonNullElementsAsList(T[] elements) {
if (elements == null) {
return Collections.emptyList();
@@ -96,91 +186,4 @@ public class MongoClientFactoryBean implements FactoryBean<Mongo>, InitializingB
return Collections.unmodifiableList(candidateElements);
}
public void setHost(String host) {
this.host = host;
}
public void setPort(int port) {
this.port = port;
}
/**
* @param exceptionTranslator
*/
public void setExceptionTranslator(PersistenceExceptionTranslator exceptionTranslator) {
this.exceptionTranslator = exceptionTranslator;
}
/*
* (non-Javadoc)
* @see org.springframework.beans.factory.FactoryBean#getObject()
*/
public Mongo getObject() throws Exception {
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;
}
/*
* (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 {
if (mongoClientOptions == null) {
mongoClientOptions = MongoClientOptions.builder().build();
}
if (credentials == null) {
credentials = Collections.emptyList();
}
this.mongo = createMongoClient();
}
private MongoClient createMongoClient() throws UnknownHostException {
if (!CollectionUtils.isEmpty(replicaSetSeeds)) {
return new MongoClient(replicaSetSeeds, credentials, mongoClientOptions);
}
return new MongoClient(createConfiguredOrDefaultServerAddress(), credentials, mongoClientOptions);
}
private ServerAddress createConfiguredOrDefaultServerAddress() throws UnknownHostException {
ServerAddress defaultAddress = new ServerAddress();
return new ServerAddress(StringUtils.hasText(host) ? host : defaultAddress.getHost(),
port != null ? port.intValue() : defaultAddress.getPort());
}
/*
* (non-Javadoc)
* @see org.springframework.beans.factory.DisposableBean#destroy()
*/
public void destroy() throws Exception {
this.mongo.close();
}
}

View File

@@ -18,12 +18,12 @@ package org.springframework.data.mongodb.core;
import javax.net.SocketFactory;
import javax.net.ssl.SSLSocketFactory;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.config.AbstractFactoryBean;
import org.springframework.data.mongodb.MongoDbFactory;
import com.mongodb.DBDecoderFactory;
import com.mongodb.DBEncoderFactory;
import com.mongodb.MongoClient;
import com.mongodb.MongoClientOptions;
import com.mongodb.ReadPreference;
import com.mongodb.WriteConcern;
@@ -32,9 +32,10 @@ import com.mongodb.WriteConcern;
* A factory bean for construction of a {@link MongoClientOptions} instance.
*
* @author Christoph Strobl
* @author Oliver Gierke
* @since 1.7
*/
public class MongoClientOptionsFactoryBean implements FactoryBean<MongoClientOptions>, InitializingBean {
public class MongoClientOptionsFactoryBean extends AbstractFactoryBean<MongoClientOptions> {
private static final MongoClientOptions DEFAULT_MONGO_OPTIONS = MongoClientOptions.builder().build();
@@ -65,10 +66,8 @@ public class MongoClientOptionsFactoryBean implements FactoryBean<MongoClientOpt
private boolean ssl;
private SSLSocketFactory sslSocketFactory;
private MongoClientOptions clientOptions;
/**
* Set the MongoClient description.
* Set the {@link MongoClient} description.
*
* @param description
*/
@@ -224,6 +223,8 @@ public class MongoClientOptionsFactoryBean implements FactoryBean<MongoClientOpt
}
/**
* Configures the name of the replica set.
*
* @param requiredReplicaSetName
*/
public void setRequiredReplicaSetName(String requiredReplicaSetName) {
@@ -231,7 +232,7 @@ public class MongoClientOptionsFactoryBean implements FactoryBean<MongoClientOpt
}
/**
* This controls if the driver should us an SSL connection. Defaults to false.
* This controls if the driver should us an SSL connection. Defaults to |@literal false}.
*
* @param ssl
*/
@@ -249,16 +250,17 @@ public class MongoClientOptionsFactoryBean implements FactoryBean<MongoClientOpt
this.sslSocketFactory = sslSocketFactory;
}
/*
/*
* (non-Javadoc)
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
* @see org.springframework.beans.factory.config.AbstractFactoryBean#createInstance()
*/
public void afterPropertiesSet() {
@Override
protected MongoClientOptions createInstance() throws Exception {
SocketFactory socketFactoryToUse = ssl ? (sslSocketFactory != null ? sslSocketFactory : SSLSocketFactory
.getDefault()) : this.socketFactory;
this.clientOptions = MongoClientOptions.builder() //
return MongoClientOptions.builder() //
.alwaysUseMBeans(this.alwaysUseMBeans) //
.connectionsPerHost(this.connectionsPerHost) //
.connectTimeout(connectTimeout) //
@@ -283,14 +285,6 @@ public class MongoClientOptionsFactoryBean implements FactoryBean<MongoClientOpt
.writeConcern(writeConcern).build();
}
/*
* (non-Javadoc)
* @see org.springframework.beans.factory.FactoryBean#getObject()
*/
public MongoClientOptions getObject() {
return this.clientOptions;
}
/*
* (non-Javadoc)
* @see org.springframework.beans.factory.FactoryBean#getObjectType()
@@ -298,12 +292,4 @@ public class MongoClientOptionsFactoryBean implements FactoryBean<MongoClientOpt
public Class<?> getObjectType() {
return MongoClientOptions.class;
}
/*
* (non-Javadoc)
* @see org.springframework.beans.factory.FactoryBean#isSingleton()
*/
public boolean isSingleton() {
return true;
}
}

View File

@@ -18,7 +18,7 @@ package org.springframework.data.mongodb.core;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.authentication.UserCredentials;
import org.springframework.data.mongodb.MongoClientVersion;
import org.springframework.data.mongodb.util.MongoClientVersion;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import org.springframework.util.Assert;
@@ -45,9 +45,7 @@ public abstract class MongoDbUtils {
/**
* Private constructor to prevent instantiation.
*/
private MongoDbUtils() {
}
private MongoDbUtils() {}
/**
* Obtains a {@link DB} connection for the given {@link Mongo} instance and database name
@@ -184,8 +182,8 @@ public abstract class MongoDbUtils {
*
* @param db the DB to close (may be <code>null</code>)
* @deprecated since 1.7. The main use case for this method is to ensure that applications can read their own
* unacknowledged writes, but this is no longer so prevalent since the mongo-java-driver version 3 started
* defaulting to acknowledged writes.
* unacknowledged writes, but this is no longer so prevalent since the MongoDB Java driver version 3
* started defaulting to acknowledged writes.
*/
@Deprecated
public static void closeDB(DB db) {
@@ -215,5 +213,4 @@ public abstract class MongoDbUtils {
return !MongoClientVersion.isMongo3Driver();
}
}

View File

@@ -15,15 +15,12 @@
*/
package org.springframework.data.mongodb.core;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
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.beans.factory.config.AbstractFactoryBean;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.support.PersistenceExceptionTranslator;
import org.springframework.data.mongodb.CannotGetMongoDbConnectionException;
@@ -46,20 +43,17 @@ import com.mongodb.WriteConcern;
* @deprecated since 1.7. Please use {@link MongoClientFactoryBean} instead.
*/
@Deprecated
public class MongoFactoryBean implements FactoryBean<Mongo>, InitializingBean, DisposableBean,
PersistenceExceptionTranslator {
public class MongoFactoryBean extends AbstractFactoryBean<Mongo> implements PersistenceExceptionTranslator {
private Mongo mongo;
private static final PersistenceExceptionTranslator DEFAULT_EXCEPTION_TRANSLATOR = new MongoExceptionTranslator();
private MongoOptions mongoOptions;
private String host;
private Integer port;
private WriteConcern writeConcern;
private List<ServerAddress> replicaSetSeeds;
private List<ServerAddress> replicaPair;
private PersistenceExceptionTranslator exceptionTranslator = new MongoExceptionTranslator();
private PersistenceExceptionTranslator exceptionTranslator = DEFAULT_EXCEPTION_TRANSLATOR;
/**
* @param mongoOptions
@@ -82,30 +76,19 @@ public class MongoFactoryBean implements FactoryBean<Mongo>, InitializingBean, D
}
/**
* @param elements the elements to filter <T>
* @return a new unmodifiable {@link List#} from the given elements without nulls
* Configures the host to connect to.
*
* @param host
*/
private <T> List<T> filterNonNullElementsAsList(T[] elements) {
if (elements == null) {
return Collections.emptyList();
}
List<T> candidateElements = new ArrayList<T>();
for (T element : elements) {
if (element != null) {
candidateElements.add(element);
}
}
return Collections.unmodifiableList(candidateElements);
}
public void setHost(String host) {
this.host = host;
}
/**
* Configures the port to connect to.
*
* @param port
*/
public void setPort(int port) {
this.port = port;
}
@@ -119,12 +102,13 @@ public class MongoFactoryBean implements FactoryBean<Mongo>, InitializingBean, D
this.writeConcern = writeConcern;
}
/**
* Configures the {@link PersistenceExceptionTranslator} to use.
*
* @param exceptionTranslator can be {@literal null}.
*/
public void setExceptionTranslator(PersistenceExceptionTranslator exceptionTranslator) {
this.exceptionTranslator = exceptionTranslator;
}
public Mongo getObject() throws Exception {
return mongo;
this.exceptionTranslator = exceptionTranslator == null ? DEFAULT_EXCEPTION_TRANSLATOR : exceptionTranslator;
}
/*
@@ -135,14 +119,6 @@ public class MongoFactoryBean implements FactoryBean<Mongo>, InitializingBean, D
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)
@@ -153,13 +129,10 @@ public class MongoFactoryBean implements FactoryBean<Mongo>, InitializingBean, D
/*
* (non-Javadoc)
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
* @see org.springframework.beans.factory.config.AbstractFactoryBean#createInstance()
*/
public void afterPropertiesSet() throws Exception {
this.mongo = createMongo();
}
private Mongo createMongo() throws UnknownHostException {
@Override
protected Mongo createInstance() throws Exception {
Mongo mongo;
ServerAddress defaultOptions = new ServerAddress();
@@ -188,15 +161,39 @@ public class MongoFactoryBean implements FactoryBean<Mongo>, InitializingBean, D
return mongo;
}
private boolean isNullOrEmpty(Collection<?> elements) {
/*
* (non-Javadoc)
* @see org.springframework.beans.factory.config.AbstractFactoryBean#destroyInstance(java.lang.Object)
*/
@Override
protected void destroyInstance(Mongo mongo) throws Exception {
mongo.close();
}
private static boolean isNullOrEmpty(Collection<?> elements) {
return elements == null || elements.isEmpty();
}
/*
* (non-Javadoc)
* @see org.springframework.beans.factory.DisposableBean#destroy()
/**
* Returns the given array as {@link List} with all {@literal null} elements removed.
*
* @param elements the elements to filter <T>
* @return a new unmodifiable {@link List#} from the given elements without nulls
*/
public void destroy() throws Exception {
this.mongo.close();
private static <T> List<T> filterNonNullElementsAsList(T[] elements) {
if (elements == null) {
return Collections.emptyList();
}
List<T> candidateElements = new ArrayList<T>();
for (T element : elements) {
if (element != null) {
candidateElements.add(element);
}
}
return Collections.unmodifiableList(candidateElements);
}
}

View File

@@ -87,18 +87,18 @@ public interface MongoOperations {
*
* @param command a MongoDB command
* @param options query options to use
* @deprecated since 1.7. Please use {@link #executeCommand(DBObject, ReadPreference)}, as the mongo-java-driver
* @deprecated since 1.7. Please use {@link #executeCommand(DBObject, ReadPreference)}, as the MongoDB Java driver
* version 3 no longer supports this operation.
*/
@Deprecated
CommandResult executeCommand(DBObject command, int options);
/**
* Execute a MongoDB command. Any errors that result from executing this command will be converted into Spring's DAO
* exception hierarchy.
* Execute a MongoDB command. Any errors that result from executing this command will be converted into Spring's data
* access exception hierarchy.
*
* @param command a MongoDB command.
* @param readPreference read preferences to use.
* @param command a MongoDB command, must not be {@literal null}.
* @param readPreference read preferences to use, can be {@literal null}.
* @return
* @since 1.7
*/
@@ -159,7 +159,7 @@ public interface MongoOperations {
* @param <T> return type
* @param action callback that specified the MongoDB actions to perform on the DB instance
* @return a result object returned by the action or <tt>null</tt>
* @deprecated since 1.7 as the mongo-java-driver version 3 does not longer support request boundaries via
* @deprecated since 1.7 as the MongoDB Java driver version 3 does not longer support request boundaries via
* {@link DB#requestStart()} and {@link DB#requestDone()}.
*/
@Deprecated

View File

@@ -17,16 +17,15 @@ package org.springframework.data.mongodb.core;
import javax.net.ssl.SSLSocketFactory;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.data.mongodb.MongoClientVersion;
import org.springframework.beans.factory.config.AbstractFactoryBean;
import org.springframework.data.mongodb.util.MongoClientVersion;
import com.mongodb.MongoOptions;
/**
* A factory bean for construction of a {@link MongoOptions} instance. In case used with mongo-java-driver version 3
* A factory bean for construction of a {@link MongoOptions} instance. In case used with MongoDB Java driver version 3
* porperties not suppprted by the driver will be ignored.
*
*
* @author Graeme Rocher
* @author Mark Pollack
* @author Mike Saavedra
@@ -35,7 +34,7 @@ import com.mongodb.MongoOptions;
* @deprecated since 1.7. Please use {@link MongoClientOptionsFactoryBean} instead.
*/
@Deprecated
public class MongoOptionsFactoryBean implements FactoryBean<MongoOptions>, InitializingBean {
public class MongoOptionsFactoryBean extends AbstractFactoryBean<MongoOptions> {
private static final MongoOptions DEFAULT_MONGO_OPTIONS = new MongoOptions();
@@ -60,8 +59,6 @@ public class MongoOptionsFactoryBean implements FactoryBean<MongoOptions>, Initi
private boolean ssl;
private SSLSocketFactory sslSocketFactory;
private MongoOptions options;
/**
* Configures the maximum number of connections allowed per host until we will block.
*
@@ -211,16 +208,17 @@ public class MongoOptionsFactoryBean implements FactoryBean<MongoOptions>, Initi
this.sslSocketFactory = sslSocketFactory;
}
/*
/*
* (non-Javadoc)
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
* @see org.springframework.beans.factory.config.AbstractFactoryBean#createInstance()
*/
public void afterPropertiesSet() {
@Override
protected MongoOptions createInstance() throws Exception {
if (MongoClientVersion.isMongo3Driver()) {
throw new IllegalArgumentException(
String
.format("Usage of 'mongo-options' is no longer supported for mongo-java-driver version 3 and above. Please use 'mongo-client-options' and refer to chapter 'MongoDB 3.0 Support' for details."));
.format("Usage of 'mongo-options' is no longer supported for MongoDB Java driver version 3 and above. Please use 'mongo-client-options' and refer to chapter 'MongoDB 3.0 Support' for details."));
}
MongoOptions options = new MongoOptions();
@@ -244,15 +242,7 @@ public class MongoOptionsFactoryBean implements FactoryBean<MongoOptions>, Initi
ReflectiveMongoOptionsInvoker.setMaxAutoConnectRetryTime(options, maxAutoConnectRetryTime);
ReflectiveMongoOptionsInvoker.setSlaveOk(options, slaveOk);
this.options = options;
}
/*
* (non-Javadoc)
* @see org.springframework.beans.factory.FactoryBean#getObject()
*/
public MongoOptions getObject() {
return this.options;
return options;
}
/*
@@ -262,13 +252,4 @@ public class MongoOptionsFactoryBean implements FactoryBean<MongoOptions>, Initi
public Class<?> getObjectType() {
return MongoOptions.class;
}
/*
* (non-Javadoc)
* @see org.springframework.beans.factory.FactoryBean#isSingleton()
*/
public boolean isSingleton() {
return true;
}
}

View File

@@ -59,7 +59,6 @@ import org.springframework.data.mapping.PersistentPropertyAccessor;
import org.springframework.data.mapping.context.MappingContext;
import org.springframework.data.mapping.model.ConvertingPropertyAccessor;
import org.springframework.data.mapping.model.MappingException;
import org.springframework.data.mongodb.MongoClientVersion;
import org.springframework.data.mongodb.MongoDbFactory;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationOperationContext;
@@ -96,6 +95,7 @@ import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.NearQuery;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.data.mongodb.util.MongoClientVersion;
import org.springframework.jca.cci.core.ConnectionCallback;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
@@ -351,6 +351,8 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
*/
public CommandResult executeCommand(final DBObject command, final ReadPreference readPreference) {
Assert.notNull(command, "Command must not be null!");
CommandResult result = execute(new DbCallback<CommandResult>() {
public CommandResult doInDB(DB db) throws MongoException, DataAccessException {
return db.command(command, readPreference);
@@ -358,6 +360,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
});
logCommandExecutionError(command, result);
return result;
}
@@ -723,7 +726,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
/**
* Prepare the WriteConcern before any processing is done using it. This allows a convenient way to apply custom
* settings in sub-classes. <br />
* In case of using mongo-java-driver version 3 the returned {@link WriteConcern} will be defaulted to
* In case of using MongoDB Java driver version 3 the returned {@link WriteConcern} will be defaulted to
* {@link WriteConcern#ACKNOWLEDGED} when {@link WriteResultChecking} is set to {@link WriteResultChecking#EXCEPTION}.
*
* @param writeConcern any WriteConcern already configured or null

View File

@@ -15,12 +15,12 @@
*/
package org.springframework.data.mongodb.core;
import static org.springframework.data.mongodb.MongoClientVersion.*;
import static org.springframework.data.mongodb.util.MongoClientVersion.*;
import static org.springframework.util.ReflectionUtils.*;
import java.lang.reflect.Method;
import org.springframework.data.mongodb.MongoClientVersion;
import org.springframework.data.mongodb.util.MongoClientVersion;
import com.mongodb.DBCollection;
import com.mongodb.DBObject;
@@ -30,6 +30,7 @@ import com.mongodb.DBObject;
* available for various driver versions.
*
* @author Christoph Strobl
* @author Oliver Gierke
* @since 1.7
*/
class ReflectiveDBCollectionInvoker {
@@ -46,9 +47,8 @@ class ReflectiveDBCollectionInvoker {
private ReflectiveDBCollectionInvoker() {}
/**
* Convenience method to generate an index name from the set of fields it is over. Will fall back to a
* mongo-java-driver version 2 compatible way of generating index name in case of
* {@link MongoClientVersion#isMongo3Driver()}.
* Convenience method to generate an index name from the set of fields it is over. Will fall back to a MongoDB Java
* driver version 2 compatible way of generating index name in case of {@link MongoClientVersion#isMongo3Driver()}.
*
* @param keys the names of the fields used in this index
* @return
@@ -62,8 +62,8 @@ class ReflectiveDBCollectionInvoker {
}
/**
* In case of mongo-java-driver version 2 all indices that have not yet been applied to this collection will be
* cleared. Since this method is not available for the mongo-java-driver version 3 the operation will throw
* In case of MongoDB Java driver version 2 all indices that have not yet been applied to this collection will be
* cleared. Since this method is not available for the MongoDB Java driver version 3 the operation will throw
* {@link UnsupportedOperationException}.
*
* @param dbCollection
@@ -79,7 +79,7 @@ class ReflectiveDBCollectionInvoker {
}
/**
* Borrowed from mongo-java-driver version 2. See <a
* Borrowed from MongoDB Java driver version 2. See <a
* href="http://github.com/mongodb/mongo-java-driver/blob/r2.13.0/src/main/com/mongodb/DBCollection.java#L754"
* >http://github.com/mongodb/mongo-java-driver/blob/r2.13.0/src/main/com/mongodb/DBCollection.java#L754</a>
*
@@ -89,14 +89,21 @@ class ReflectiveDBCollectionInvoker {
private static String genIndexName(DBObject keys) {
StringBuilder name = new StringBuilder();
for (String s : keys.keySet()) {
if (name.length() > 0)
if (name.length() > 0) {
name.append('_');
}
name.append(s).append('_');
Object val = keys.get(s);
if (val instanceof Number || val instanceof String)
if (val instanceof Number || val instanceof String) {
name.append(val.toString().replace(' ', '_'));
}
}
return name.toString();
}
}

View File

@@ -15,12 +15,14 @@
*/
package org.springframework.data.mongodb.core;
import static org.springframework.data.mongodb.util.MongoClientVersion.*;
import static org.springframework.util.ReflectionUtils.*;
import java.lang.reflect.Method;
import org.springframework.data.authentication.UserCredentials;
import org.springframework.data.mongodb.CannotGetMongoDbConnectionException;
import org.springframework.data.mongodb.MongoClientVersion;
import org.springframework.util.ReflectionUtils;
import org.springframework.data.mongodb.util.MongoClientVersion;
import com.mongodb.DB;
import com.mongodb.Mongo;
@@ -28,8 +30,9 @@ import com.mongodb.Mongo;
/**
* {@link ReflectiveDbInvoker} provides reflective access to {@link DB} API that is not consistently available for
* various driver versions.
*
*
* @author Christoph Strobl
* @author Oliver Gierke
* @since 1.7
*/
final class ReflectiveDbInvoker {
@@ -42,18 +45,18 @@ final class ReflectiveDbInvoker {
static {
DB_IS_AUTHENTICATED_METHOD = ReflectionUtils.findMethod(DB.class, "isAuthenticated");
DB_AUTHENTICATE_METHOD = ReflectionUtils.findMethod(DB.class, "authenticate", String.class, char[].class);
DB_REQUEST_DONE_METHOD = ReflectionUtils.findMethod(DB.class, "requestDone");
DB_ADD_USER_METHOD = ReflectionUtils.findMethod(DB.class, "addUser", String.class, char[].class);
DB_REQUEST_START_METHOD = ReflectionUtils.findMethod(DB.class, "requestStart");
DB_IS_AUTHENTICATED_METHOD = findMethod(DB.class, "isAuthenticated");
DB_AUTHENTICATE_METHOD = findMethod(DB.class, "authenticate", String.class, char[].class);
DB_REQUEST_DONE_METHOD = findMethod(DB.class, "requestDone");
DB_ADD_USER_METHOD = findMethod(DB.class, "addUser", String.class, char[].class);
DB_REQUEST_START_METHOD = findMethod(DB.class, "requestStart");
}
private ReflectiveDbInvoker() {}
/**
* Authenticate against database using provided credentials in case of a mongo-java-driver version 2.
*
* Authenticate against database using provided credentials in case of a MongoDB Java driver version 2.
*
* @param mongo must not be {@literal null}.
* @param db must not be {@literal null}.
* @param credentials must not be {@literal null}.
@@ -67,13 +70,13 @@ final class ReflectiveDbInvoker {
synchronized (authDb) {
Boolean isAuthenticated = (Boolean) ReflectionUtils.invokeMethod(DB_IS_AUTHENTICATED_METHOD, authDb);
Boolean isAuthenticated = (Boolean) invokeMethod(DB_IS_AUTHENTICATED_METHOD, authDb);
if (!isAuthenticated) {
String username = credentials.getUsername();
String password = credentials.hasPassword() ? credentials.getPassword() : null;
Boolean authenticated = (Boolean) ReflectionUtils.invokeMethod(DB_AUTHENTICATE_METHOD, authDb, username,
Boolean authenticated = (Boolean) invokeMethod(DB_AUTHENTICATE_METHOD, authDb, username,
password == null ? null : password.toCharArray());
if (!authenticated) {
throw new CannotGetMongoDbConnectionException("Failed to authenticate to database [" + databaseName + "], "
@@ -84,24 +87,24 @@ final class ReflectiveDbInvoker {
}
/**
* Starts a new 'consistent request' in case of mongo-java-driver version 2. Will do nothing for mongo-java-driver
* Starts a new 'consistent request' in case of MongoDB Java driver version 2. Will do nothing for MongoDB Java driver
* version 3 since the operation is no longer available.
*
*
* @param db
*/
public static void requestStart(DB db) {
if (MongoClientVersion.isMongo3Driver()) {
if (isMongo3Driver()) {
return;
}
ReflectionUtils.invokeMethod(DB_REQUEST_START_METHOD, db);
invokeMethod(DB_REQUEST_START_METHOD, db);
}
/**
* Ends the current 'consistent request'. a new 'consistent request' in case of mongo-java-driver version 2. Will do
* nothing for mongo-java-driver version 3 since the operation is no longer available
*
* Ends the current 'consistent request'. a new 'consistent request' in case of MongoDB Java driver version 2. Will do
* nothing for MongoDB Java driver version 3 since the operation is no longer available
*
* @param db
*/
public static void requestDone(DB db) {
@@ -110,7 +113,7 @@ final class ReflectiveDbInvoker {
return;
}
ReflectionUtils.invokeMethod(DB_REQUEST_DONE_METHOD, db);
invokeMethod(DB_REQUEST_DONE_METHOD, db);
}
/**
@@ -121,11 +124,11 @@ final class ReflectiveDbInvoker {
*/
public static void addUser(DB db, String username, char[] password) {
if (MongoClientVersion.isMongo3Driver()) {
throw new UnsupportedOperationException("Please DB.command to call either the createUser or updateUser command");
if (isMongo3Driver()) {
throw new UnsupportedOperationException(
"Please use DB.command(…) to call either the createUser or updateUser command!");
}
ReflectionUtils.invokeMethod(DB_ADD_USER_METHOD, db, username, password);
invokeMethod(DB_ADD_USER_METHOD, db, username, password);
}
}

View File

@@ -15,11 +15,12 @@
*/
package org.springframework.data.mongodb.core;
import static org.springframework.data.mongodb.util.MongoClientVersion.*;
import static org.springframework.util.ReflectionUtils.*;
import java.lang.reflect.Method;
import org.springframework.data.mongodb.MongoClientVersion;
import org.springframework.util.Assert;
import org.springframework.util.ReflectionUtils;
import com.mongodb.MapReduceCommand;
@@ -28,6 +29,7 @@ import com.mongodb.MapReduceCommand;
* consistently available for various driver versions.
*
* @author Christoph Strobl
* @author Oliver Gierke
* @since 1.7
*/
final class ReflectiveMapReduceInvoker {
@@ -36,27 +38,25 @@ final class ReflectiveMapReduceInvoker {
static {
ADD_EXTRA_OPTION_METHOD = ReflectionUtils.findMethod(MapReduceCommand.class, "addExtraOption", String.class,
Object.class);
ADD_EXTRA_OPTION_METHOD = findMethod(MapReduceCommand.class, "addExtraOption", String.class, Object.class);
}
private ReflectiveMapReduceInvoker() {}
/**
* Sets the extra option for mongo-java-driver version 2. Will do nothing for mongo-java-driver version 2.
* Sets the extra option for MongoDB Java driver version 2. Will do nothing for MongoDB Java driver version 2.
*
* @param cmd can be {@literal null} for mongo-java-driver version 2.
* @param cmd can be {@literal null} for MongoDB Java driver version 2.
* @param key
* @param value
*/
public static void addExtraOption(MapReduceCommand cmd, String key, Object value) {
if (MongoClientVersion.isMongo3Driver()) {
if (isMongo3Driver()) {
return;
}
Assert.notNull(cmd, "MapReduceCommand must not be null!");
ReflectionUtils.invokeMethod(ADD_EXTRA_OPTION_METHOD, cmd, key, value);
invokeMethod(ADD_EXTRA_OPTION_METHOD, cmd, key, value);
}
}

View File

@@ -15,10 +15,12 @@
*/
package org.springframework.data.mongodb.core;
import static org.springframework.data.mongodb.util.MongoClientVersion.*;
import static org.springframework.util.ReflectionUtils.*;
import java.lang.reflect.Method;
import org.springframework.beans.DirectFieldAccessor;
import org.springframework.data.mongodb.MongoClientVersion;
import org.springframework.util.ReflectionUtils;
import com.mongodb.MongoOptions;
@@ -28,8 +30,10 @@ import com.mongodb.MongoOptions;
* available for various driver versions.
*
* @author Christoph Strobl
* @author Oliver Gierke
* @since 1.7
*/
@SuppressWarnings("deprecation")
class ReflectiveMongoOptionsInvoker {
private static final Method GET_AUTO_CONNECT_RETRY_METHOD;
@@ -51,99 +55,104 @@ class ReflectiveMongoOptionsInvoker {
private ReflectiveMongoOptionsInvoker() {}
/**
* Sets the retry connection flag for mongo-java-driver version 2. Will do nothing for mongo-java-driver version 3
* Sets the retry connection flag for MongoDB Java driver version 2. Will do nothing for MongoDB Java driver version 3
* since the method has been removed.
*
* @param options can be {@literal null} for mongo-java-driver version 3.
* @param options can be {@literal null} for MongoDB Java driver version 3.
* @param autoConnectRetry
*/
public static void setAutoConnectRetry(MongoOptions options, boolean autoConnectRetry) {
if (MongoClientVersion.isMongo3Driver()) {
if (isMongo3Driver()) {
return;
}
ReflectionUtils.invokeMethod(SET_AUTO_CONNECT_RETRY_METHOD, options, autoConnectRetry);
invokeMethod(SET_AUTO_CONNECT_RETRY_METHOD, options, autoConnectRetry);
}
/**
* Sets the maxAutoConnectRetryTime attribute for mongo-java-driver version 2. Will do nothing for mongo-java-driver
* version 3 since the method has been removed.
* Sets the maxAutoConnectRetryTime attribute for MongoDB Java driver version 2. Will do nothing for MongoDB Java
* driver version 3 since the method has been removed.
*
* @param options can be {@literal null} for mongo-java-driver version 3.
* @param options can be {@literal null} for MongoDB Java driver version 3.
* @param maxAutoConnectRetryTime
*/
public static void setMaxAutoConnectRetryTime(MongoOptions options, long maxAutoConnectRetryTime) {
if (MongoClientVersion.isMongo3Driver()) {
if (isMongo3Driver()) {
return;
}
ReflectionUtils.invokeMethod(SET_MAX_AUTO_CONNECT_RETRY_TIME_METHOD, options, maxAutoConnectRetryTime);
invokeMethod(SET_MAX_AUTO_CONNECT_RETRY_TIME_METHOD, options, maxAutoConnectRetryTime);
}
/**
* Sets the slaveOk attribute for mongo-java-driver version 2. Will do nothing for mongo-java-driver version 3 since
* the method has been removed.
* Sets the slaveOk attribute for MongoDB Java driver version 2. Will do nothing for MongoDB Java driver version 3
* since the method has been removed.
*
* @param options can be {@literal null} for mongo-java-driver version 3.
* @param options can be {@literal null} for MongoDB Java driver version 3.
* @param slaveOk
*/
public static void setSlaveOk(MongoOptions options, boolean slaveOk) {
if (MongoClientVersion.isMongo3Driver()) {
if (isMongo3Driver()) {
return;
}
new DirectFieldAccessor(options).setPropertyValue("slaveOk", slaveOk);
}
/**
* Gets the slaveOk attribute for mongo-java-driver version 2. Throws {@link UnsupportedOperationException} for
* mongo-java-driver version 3 since the method has been removed.
* Gets the slaveOk attribute for MongoDB Java driver version 2. Throws {@link UnsupportedOperationException} for
* MongoDB Java driver version 3 since the method has been removed.
*
* @param options can be {@literal null} for mongo-java-driver version 3.
* @param options can be {@literal null} for MongoDB Java driver version 3.
* @return
* @throws UnsupportedOperationException
*/
public static boolean getSlaveOk(MongoOptions options) {
if (MongoClientVersion.isMongo3Driver()) {
if (isMongo3Driver()) {
throw new UnsupportedOperationException(
"Cannot get value for autoConnectRetry which has been removed in mongo-java-driver version 3.");
"Cannot get value for autoConnectRetry which has been removed in MongoDB Java driver version 3.");
}
return ((Boolean) new DirectFieldAccessor(options).getPropertyValue("slaveOk")).booleanValue();
}
/**
* Gets the autoConnectRetry attribute for mongo-java-driver version 2. Throws {@link UnsupportedOperationException}
* for mongo-java-driver version 3 since the method has been removed.
* Gets the autoConnectRetry attribute for MongoDB Java driver version 2. Throws {@link UnsupportedOperationException}
* for MongoDB Java driver version 3 since the method has been removed.
*
* @param options can be {@literal null} for mongo-java-driver version 3.
* @param options can be {@literal null} for MongoDB Java driver version 3.
* @return
* @throws UnsupportedOperationException
*/
public static boolean getAutoConnectRetry(MongoOptions options) {
if (MongoClientVersion.isMongo3Driver()) {
if (isMongo3Driver()) {
throw new UnsupportedOperationException(
"Cannot get value for autoConnectRetry which has been removed in mongo-java-driver version 3.");
"Cannot get value for autoConnectRetry which has been removed in MongoDB Java driver version 3.");
}
return ((Boolean) ReflectionUtils.invokeMethod(GET_AUTO_CONNECT_RETRY_METHOD, options)).booleanValue();
return ((Boolean) invokeMethod(GET_AUTO_CONNECT_RETRY_METHOD, options)).booleanValue();
}
/**
* Gets the maxAutoConnectRetryTime attribute for mongo-java-driver version 2. Throws
* {@link UnsupportedOperationException} for mongo-java-driver version 3 since the method has been removed.
* Gets the maxAutoConnectRetryTime attribute for MongoDB Java driver version 2. Throws
* {@link UnsupportedOperationException} for MongoDB Java driver version 3 since the method has been removed.
*
* @param options can be {@literal null} for mongo-java-driver version 3.
* @param options can be {@literal null} for MongoDB Java driver version 3.
* @return
* @throws UnsupportedOperationException
*/
public static long getMaxAutoConnectRetryTime(MongoOptions options) {
if (MongoClientVersion.isMongo3Driver()) {
if (isMongo3Driver()) {
throw new UnsupportedOperationException(
"Cannot get value for maxAutoConnectRetryTime which has been removed in mongo-java-driver version 3.");
"Cannot get value for maxAutoConnectRetryTime which has been removed in MongoDB Java driver version 3.");
}
return ((Long) ReflectionUtils.invokeMethod(GET_MAX_AUTO_CONNECT_RETRY_TIME_METHOD, options)).longValue();
return ((Long) invokeMethod(GET_MAX_AUTO_CONNECT_RETRY_TIME_METHOD, options)).longValue();
}
}

View File

@@ -15,8 +15,9 @@
*/
package org.springframework.data.mongodb.core;
import static org.springframework.data.mongodb.util.MongoClientVersion.*;
import org.springframework.beans.DirectFieldAccessor;
import org.springframework.data.mongodb.MongoClientVersion;
import com.mongodb.WriteConcern;
@@ -25,6 +26,7 @@ import com.mongodb.WriteConcern;
* available for various driver versions.
*
* @author Christoph Strobl
* @author Oliver Gierke
* @since 1.7
*/
class ReflectiveWriteConcernInvoker {
@@ -33,12 +35,12 @@ class ReflectiveWriteConcernInvoker {
static {
NONE_OR_UNACKNOWLEDGED = MongoClientVersion.isMongo3Driver() ? WriteConcern.UNACKNOWLEDGED
: (WriteConcern) new DirectFieldAccessor(new WriteConcern()).getPropertyValue("NONE");
NONE_OR_UNACKNOWLEDGED = isMongo3Driver() ? WriteConcern.UNACKNOWLEDGED : (WriteConcern) new DirectFieldAccessor(
new WriteConcern()).getPropertyValue("NONE");
}
/**
* @return {@link WriteConcern#NONE} for mongo-java-driver version 2, otherwise {@link WriteConcern#UNACKNOWLEDGED}.
* @return {@link WriteConcern#NONE} for MongoDB Java driver version 2, otherwise {@link WriteConcern#UNACKNOWLEDGED}.
*/
public static WriteConcern noneOrUnacknowledged() {
return NONE_OR_UNACKNOWLEDGED;

View File

@@ -15,13 +15,11 @@
*/
package org.springframework.data.mongodb.core;
import static org.springframework.data.mongodb.util.MongoClientVersion.*;
import static org.springframework.util.ReflectionUtils.*;
import java.lang.reflect.Method;
import org.springframework.data.mongodb.MongoClientVersion;
import org.springframework.util.ReflectionUtils;
import com.mongodb.MongoException;
import com.mongodb.WriteResult;
@@ -30,6 +28,7 @@ import com.mongodb.WriteResult;
* available for various driver versions.
*
* @author Christoph Strobl
* @author Oliver Gierke
* @since 1.7
*/
final class ReflectiveWriteResultInvoker {
@@ -46,12 +45,12 @@ final class ReflectiveWriteResultInvoker {
}
/**
* @param writeResult can be {@literal null} for mongo-java-driver version 3.
* @return null in case of mongo-java-driver version 3 since errors are thrown as {@link MongoException}.
* @param writeResult can be {@literal null} for MongoDB Java driver version 3.
* @return null in case of MongoDB Java driver version 3 since errors are thrown as {@link MongoException}.
*/
public static String getError(WriteResult writeResult) {
if (MongoClientVersion.isMongo3Driver()) {
if (isMongo3Driver()) {
return null;
}
@@ -60,11 +59,9 @@ final class ReflectiveWriteResultInvoker {
/**
* @param writeResult
* @return return in case of mongo-java-driver version 2.
* @return return in case of MongoDB Java driver version 2.
*/
public static boolean wasAcknowledged(WriteResult writeResult) {
return MongoClientVersion.isMongo3Driver() ? ((Boolean) ReflectionUtils.invokeMethod(WAS_ACKNOWLEDGED_METHOD,
writeResult)).booleanValue() : true;
return isMongo3Driver() ? ((Boolean) invokeMethod(WAS_ACKNOWLEDGED_METHOD, writeResult)).booleanValue() : true;
}
}

View File

@@ -189,6 +189,7 @@ public class SimpleMongoDbFactory implements DisposableBean, MongoDbFactory {
* (non-Javadoc)
* @see org.springframework.data.mongodb.MongoDbFactory#getDb(java.lang.String)
*/
@SuppressWarnings("deprecation")
public DB getDb(String dbName) throws DataAccessException {
Assert.hasText(dbName, "Database name must not be empty.");

View File

@@ -15,13 +15,12 @@
*/
package org.springframework.data.mongodb.core.convert;
import static org.springframework.data.mongodb.util.MongoClientVersion.*;
import static org.springframework.util.ReflectionUtils.*;
import java.lang.reflect.Method;
import org.springframework.data.mongodb.MongoClientVersion;
import org.springframework.util.Assert;
import org.springframework.util.ReflectionUtils;
import com.mongodb.DB;
import com.mongodb.DBCollection;
@@ -33,6 +32,7 @@ import com.mongodb.DBRef;
* for various driver versions.
*
* @author Christoph Strobl
* @author Oliver Gierke
* @since 1.7
*/
class ReflectiveDBRefResolver {
@@ -40,7 +40,6 @@ class ReflectiveDBRefResolver {
private static final Method FETCH_METHOD;
static {
FETCH_METHOD = findMethod(DBRef.class, "fetch");
}
@@ -48,7 +47,7 @@ class ReflectiveDBRefResolver {
* Fetches the object referenced from the database either be directly calling {@link DBRef#fetch()} or
* {@link DBCollection#findOne(Object)}.
*
* @param db can be {@literal null} when using mongo-java-driver version 2.
* @param db can be {@literal null} when using MongoDB Java driver in version 2.x.
* @param ref must not be {@literal null}.
* @return the document that this references.
*/
@@ -56,11 +55,10 @@ class ReflectiveDBRefResolver {
Assert.notNull(ref, "DBRef to fetch must not be null!");
if (MongoClientVersion.isMongo3Driver()) {
if (isMongo3Driver()) {
return db.getCollection(ref.getCollectionName()).findOne(ref.getId());
}
return (DBObject) ReflectionUtils.invokeMethod(FETCH_METHOD, ref);
return (DBObject) invokeMethod(FETCH_METHOD, ref);
}
}

View File

@@ -102,7 +102,7 @@ public class MapReduceResults<T> implements Iterable<T> {
return rawResults;
}
private MapReduceTiming parseTiming(DBObject rawResults) {
private static MapReduceTiming parseTiming(DBObject rawResults) {
DBObject timing = (DBObject) rawResults.get("timing");
@@ -125,8 +125,10 @@ public class MapReduceResults<T> implements Iterable<T> {
* @param key
* @return
*/
private Long getAsLong(DBObject source, String key) {
private static Long getAsLong(DBObject source, String key) {
Object raw = source.get(key);
return raw instanceof Long ? (Long) raw : (Integer) raw;
}
@@ -136,7 +138,7 @@ public class MapReduceResults<T> implements Iterable<T> {
* @param rawResults
* @return
*/
private MapReduceCounts parseCounts(DBObject rawResults) {
private static MapReduceCounts parseCounts(DBObject rawResults) {
DBObject counts = (DBObject) rawResults.get("counts");
@@ -157,7 +159,7 @@ public class MapReduceResults<T> implements Iterable<T> {
* @param rawResults
* @return
*/
private String parseOutputCollection(DBObject rawResults) {
private static String parseOutputCollection(DBObject rawResults) {
Object resultField = rawResults.get("result");
@@ -169,16 +171,16 @@ public class MapReduceResults<T> implements Iterable<T> {
.toString();
}
private MapReduceCounts parseCounts(final MapReduceOutput mapReduceOutput) {
private static MapReduceCounts parseCounts(final MapReduceOutput mapReduceOutput) {
return new MapReduceCounts(mapReduceOutput.getInputCount(), mapReduceOutput.getEmitCount(),
mapReduceOutput.getOutputCount());
}
private String parseOutputCollection(final MapReduceOutput mapReduceOutput) {
private static String parseOutputCollection(final MapReduceOutput mapReduceOutput) {
return mapReduceOutput.getCollectionName();
}
private MapReduceTiming parseTiming(MapReduceOutput mapReduceOutput) {
private static MapReduceTiming parseTiming(MapReduceOutput mapReduceOutput) {
return new MapReduceTiming(-1, -1, mapReduceOutput.getDuration());
}
}

View File

@@ -39,7 +39,7 @@ public class ServerInfo extends AbstractMonitor {
}
/**
* Returns the hostname of the used server reported by mongo.
* Returns the hostname of the used server reported by MongoDB.
*
* @return the reported hostname can also be an IP address.
* @throws UnknownHostException
@@ -73,5 +73,4 @@ public class ServerInfo extends AbstractMonitor {
public double getUptime() {
return (Double) getServerStatus().get("uptime");
}
}

View File

@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.mongodb;
package org.springframework.data.mongodb.util;
import org.springframework.util.ClassUtils;
@@ -32,14 +32,14 @@ public class MongoClientVersion {
MongoClientVersion.class.getClassLoader());
/**
* @return true if mongo-java-driver version 3 or later is on classpath.
* @return |literal true} if MongoDB Java driver version 3.0 or later is on classpath.
*/
public static boolean isMongo3Driver() {
return IS_MONGO_30;
}
/**
* @return true if mongodb-driver-async is on classpath.
* @return {lliteral true} if MongoDB Java driver is on classpath.
*/
public static boolean isAsyncClient() {
return IS_ASYNC_CLIENT;

View File

@@ -29,6 +29,8 @@ import org.springframework.util.StringUtils;
import com.mongodb.MongoCredential;
/**
* Unit tests for {@link MongoCredentialPropertyEditor}.
*
* @author Christoph Strobl
*/
public class MongoCredentialPropertyEditorUnitTests {

View File

@@ -18,7 +18,7 @@ package org.springframework.data.mongodb.config;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
import static org.junit.Assume.*;
import static org.springframework.data.mongodb.MongoClientVersion.*;
import static org.springframework.data.mongodb.util.MongoClientVersion.*;
import org.junit.Before;
import org.junit.BeforeClass;
@@ -104,22 +104,6 @@ public class MongoDbFactoryParserIntegrationTests {
ctx.close();
}
private void assertWriteConcern(ClassPathXmlApplicationContext ctx, WriteConcern expectedWriteConcern) {
SimpleMongoDbFactory dbFactory = ctx.getBean("first", SimpleMongoDbFactory.class);
DB db = dbFactory.getDb();
assertThat(db.getName(), is("db"));
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, is(myExpectedWriteConcern));
assertThat(myDbWriteConcern, is(myExpectedWriteConcern));
assertThat(myDbWriteConcern, is(myDbFactoryWriteConcern));
}
// This test will fail since equals in WriteConcern uses == for _w and not .equals
public void testWriteConcernEquality() {
String s1 = new String("rack1");
@@ -137,9 +121,10 @@ public class MongoDbFactoryParserIntegrationTests {
}
/**
* @see DATADOC-280
* @see DATAMONGO-280
*/
@Test
@SuppressWarnings("deprecation")
public void parsesMaxAutoConnectRetryTimeCorrectly() {
reader.loadBeanDefinitions(new ClassPathResource("namespace/db-factory-bean.xml"));
@@ -148,7 +133,7 @@ public class MongoDbFactoryParserIntegrationTests {
}
/**
* @see DATADOC-295
* @see DATAMONGO-295
*/
@Test
public void setsUpMongoDbFactoryUsingAMongoUri() {
@@ -163,7 +148,7 @@ public class MongoDbFactoryParserIntegrationTests {
}
/**
* @see DATADOC-306
* @see DATAMONGO-306
*/
@Test
public void setsUpMongoDbFactoryUsingAMongoUriWithoutCredentials() {
@@ -182,10 +167,27 @@ public class MongoDbFactoryParserIntegrationTests {
}
/**
* @see DATADOC-295
* @see DATAMONGO-295
*/
@Test(expected = BeanDefinitionParsingException.class)
public void rejectsUriPlusDetailedConfiguration() {
reader.loadBeanDefinitions(new ClassPathResource("namespace/mongo-uri-and-details.xml"));
}
private static void assertWriteConcern(ClassPathXmlApplicationContext ctx, WriteConcern expectedWriteConcern) {
SimpleMongoDbFactory dbFactory = ctx.getBean("first", SimpleMongoDbFactory.class);
DB db = dbFactory.getDb();
assertThat(db.getName(), is("db"));
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, is(myExpectedWriteConcern));
assertThat(myDbWriteConcern, is(myExpectedWriteConcern));
assertThat(myDbWriteConcern, is(myDbFactoryWriteConcern));
}
}

View File

@@ -17,7 +17,7 @@ package org.springframework.data.mongodb.config;
import static org.junit.Assert.*;
import static org.junit.Assume.*;
import static org.springframework.data.mongodb.MongoClientVersion.*;
import static org.springframework.data.mongodb.util.MongoClientVersion.*;
import static org.springframework.test.util.ReflectionTestUtils.*;
import javax.net.ssl.SSLSocketFactory;

View File

@@ -15,8 +15,9 @@
*/
package org.springframework.data.mongodb.config;
import org.hamcrest.core.Is;
import org.junit.Assert;
import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@@ -25,6 +26,8 @@ import org.junit.rules.ExpectedException;
import com.mongodb.ReadPreference;
/**
* Unit tests for {@link ReadPreferencePropertyEditor}.
*
* @author Christoph Strobl
*/
public class ReadPreferencePropertyEditorUnitTests {
@@ -59,7 +62,7 @@ public class ReadPreferencePropertyEditorUnitTests {
editor.setAsText("secondary");
Assert.assertThat(editor.getValue(), Is.<Object> is(ReadPreference.secondary()));
assertThat(editor.getValue(), is((Object) ReadPreference.secondary()));
}
/**
@@ -70,6 +73,6 @@ public class ReadPreferencePropertyEditorUnitTests {
editor.setAsText("NEAREST");
Assert.assertThat(editor.getValue(), Is.<Object> is(ReadPreference.nearest()));
assertThat(editor.getValue(), is((Object) ReadPreference.nearest()));
}
}

View File

@@ -27,6 +27,8 @@ import org.springframework.test.util.ReflectionTestUtils;
import com.mongodb.ReadPreference;
/**
* Integration tests for {@link MongoClientOptionsFactoryBean}.
*
* @author Christoph Strobl
*/
public class MongoClientOptionsFactoryBeanIntegrationTests {
@@ -48,5 +50,4 @@ public class MongoClientOptionsFactoryBeanIntegrationTests {
MongoClientOptionsFactoryBean bean = factory.getBean("&factory", MongoClientOptionsFactoryBean.class);
assertThat(ReflectionTestUtils.getField(bean, "readPreference"), is((Object) ReadPreference.nearest()));
}
}

View File

@@ -18,7 +18,7 @@ package org.springframework.data.mongodb.core;
import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;
import static org.junit.Assume.*;
import static org.springframework.data.mongodb.MongoClientVersion.*;
import static org.springframework.data.mongodb.util.MongoClientVersion.*;
import java.util.ArrayList;
import java.util.List;

View File

@@ -18,8 +18,8 @@ package org.springframework.data.mongodb.core;
import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;
import static org.junit.Assume.*;
import static org.springframework.data.mongodb.MongoClientVersion.*;
import static org.springframework.data.mongodb.core.ReflectiveMongoOptionsInvoker.*;
import static org.springframework.data.mongodb.util.MongoClientVersion.*;
import javax.net.ssl.SSLSocketFactory;
@@ -35,6 +35,7 @@ import com.mongodb.MongoOptions;
* @author Mike Saavedra
* @author Christoph Strobl
*/
@SuppressWarnings("deprecation")
public class MongoOptionsFactoryBeanUnitTests {
@BeforeClass
@@ -43,10 +44,11 @@ public class MongoOptionsFactoryBeanUnitTests {
}
/**
* @throws Exception
* @see DATADOC-280
*/
@Test
public void setsMaxConnectRetryTime() {
public void setsMaxConnectRetryTime() throws Exception {
MongoOptionsFactoryBean bean = new MongoOptionsFactoryBean();
bean.setMaxAutoConnectRetryTime(27);
@@ -57,10 +59,11 @@ public class MongoOptionsFactoryBeanUnitTests {
}
/**
* @throws Exception
* @see DATAMONGO-764
*/
@Test
public void testSslConnection() {
public void testSslConnection() throws Exception {
MongoOptionsFactoryBean bean = new MongoOptionsFactoryBean();
bean.setSsl(true);

View File

@@ -23,6 +23,7 @@ import com.mongodb.MongoOptions;
*
* @author Christoph Strobl
*/
@SuppressWarnings("deprecation")
public class ReflectiveMongoOptionsInvokerTestUtil {
public static void setAutoConnectRetry(MongoOptions options, boolean autoConnectRetry) {
@@ -48,5 +49,4 @@ public class ReflectiveMongoOptionsInvokerTestUtil {
public static long getMaxAutoConnectRetryTime(MongoOptions options) {
return ReflectiveMongoOptionsInvoker.getMaxAutoConnectRetryTime(options);
}
}

View File

@@ -42,13 +42,13 @@ import org.springframework.data.annotation.Id;
import org.springframework.data.annotation.PersistenceConstructor;
import org.springframework.data.mapping.PersistentPropertyAccessor;
import org.springframework.data.mapping.PropertyPath;
import org.springframework.data.mongodb.MongoClientVersion;
import org.springframework.data.mongodb.MongoDbFactory;
import org.springframework.data.mongodb.core.MongoExceptionTranslator;
import org.springframework.data.mongodb.core.convert.MappingMongoConverterUnitTests.Person;
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
import org.springframework.data.mongodb.util.MongoClientVersion;
import org.springframework.test.util.ReflectionTestUtils;
import org.springframework.util.SerializationUtils;

View File

@@ -190,7 +190,7 @@ public class Person {
----
====
IMPORTANT: The `@Id` annotation tells the mapper which property you want to use for the MongoDB `_id` property and the `@Indexed` annotation tells the mapping framework to call `createIndex` on that property of your document, making searches faster.
IMPORTANT: The `@Id` annotation tells the mapper which property you want to use for the MongoDB `_id` property and the `@Indexed` annotation tells the mapping framework to call `createIndex(…)` on that property of your document, making searches faster.
IMPORTANT: Automatic index creation is only done for types annotated with `@Document`.

View File

@@ -1,15 +1,15 @@
[[mongo.mongo-3]]
= MongoDB 3.0 Support
Spring Data MongoDB allows usage of both _mongo-java-driver_ generations 2 and 3 when connecting to a MongoDB 2.6/3.0 server running _MMap.v1_ or a MongoDB server 3.0 using _MMap.v1_ or the _WiredTiger_ storage engine.
Spring Data MongoDB allows usage of both MongoDB Java driver generations 2 and 3 when connecting to a MongoDB 2.6/3.0 server running _MMap.v1_ or a MongoDB server 3.0 using _MMap.v1_ or the _WiredTiger_ storage engine.
NOTE: Please refer to the driver and database specific documentation for major differences between those.
NOTE: Operations that are no longer valid using a 3.x mongo-java-driver have been deprecated within Spring Data and will be removed in a subsequent release.
[[mongodb:mongo-3-configuration]]
NOTE: Operations that are no longer valid using a 3.x MongoDB Java driver have been deprecated within Spring Data and will be removed in a subsequent release.
== Using Spring Data MongoDB with MongoDB 3.0
[[mongo.mongo-3.configuration]]
=== Configuration Options
Some of the configuration options have been changed / removed for the _mongo-java-driver_. The following options will be ignored using the generation 3 driver:
@@ -17,7 +17,7 @@ Some of the configuration options have been changed / removed for the _mongo-jav
* autoConnectRetry
* maxAutoConnectRetryTime
* slaveOk
Generally it is recommended to use the `<mongo:mongo-client ... />` and `<mongo:client-options ... />` elements instead of `<mongo:mongo ... />` when doing XML based configuration, since those elements will only provide you with attributes valid for the 3 generation java driver.
[source,xml]
@@ -28,7 +28,7 @@ Generally it is recommended to use the `<mongo:mongo-client ... />` and `<mongo:
xmlns:mongo="http://www.springframework.org/schema/data/mongo"
xsi:schemaLocation="http://www.springframework.org/schema/data/mongo http://www.springframework.org/schema/data/mongo/spring-mongo.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<mongo:mongo-client host="127.0.0.1" port="27017">
<mongo:client-options write-concern="NORMAL" />
</mongo:mongo-client>
@@ -36,10 +36,12 @@ Generally it is recommended to use the `<mongo:mongo-client ... />` and `<mongo:
</beans>
----
[[mongo.mongo-3.write-concern]]
=== WriteConcern and WriteConcernChecking
The `WriteConcern.NONE`, which had been used as default by Spring Data MongoDB, was removed in 3.0. Therefore in a MongoDB 3 environment the `WriteConcern` will be defaulted to `WriteConcern.UNACKNOWLEGED`. In case `WriteResultChecking.EXCEPTION` is enabled the `WriteConcern` will be altered to `WriteConcern.ACKNOWLEDGED` for write operations, as otherwise errors during execution would not be throw correctly, since simply not raised by the driver.
The `WriteConcern.NONE`, which had been used as default by Spring Data MongoDB, was removed in 3.0. Therefore in a MongoDB 3 environment the `WriteConcern` will be defaulted to `WriteConcern.UNACKNOWLEGED`. In case `WriteResultChecking.EXCEPTION` is enabled the `WriteConcern` will be altered to `WriteConcern.ACKNOWLEDGED` for write operations, as otherwise errors during execution would not be throw correctly, since simply not raised by the driver.
[[mongo.mongo-3.authentication]]
=== Authentication
MongoDB Server generation 3 changed the authentication model when connecting to the DB. Therefore some of the configuration options available for authentication are no longer valid. Please use the `MongoClient` specific options for setting credentials via `MongoCredential` to provide authentication data.
@@ -63,7 +65,7 @@ public class ApplicationContextEventTestsAppConfig extends AbstractMongoConfigur
}
----
In order to use authentication with XML configuration use the `credentials` attribue on `<mongo-client>`.
In order to use authentication with XML configuration use the `credentials` attribue on `<mongo-client>`.
[source,xml]
----
@@ -73,12 +75,13 @@ In order to use authentication with XML configuration use the `credentials` attr
xmlns:mongo="http://www.springframework.org/schema/data/mongo"
xsi:schemaLocation="http://www.springframework.org/schema/data/mongo http://www.springframework.org/schema/data/mongo/spring-mongo.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<mongo:mongo-client credentials="user:password@database" />
</beans>
----
[[mongo.mongo-3.misc]]
=== Other things to be aware of
This section covers additional things to keep in mind when using the 3.0 driver.
@@ -86,8 +89,7 @@ This section covers additional things to keep in mind when using the 3.0 driver.
* `IndexOperations.resetIndexCache()` is no longer supported.
* Any `MapReduceOptions.extraOption` is silently ignored.
* `WriteResult` does not longer hold error informations but throws an Exception.
* `MongoOperations.executeInSession()` no longer calls `requestStart` / `requestDone`.
* `MongoOperations.executeInSession()` no longer calls `requestStart` / `requestDone`.
* Index name generation has become a driver internal operations, still we use the 2.x schema to generate names.
* Some Exception messages differ between the generation 2 and 3 servers as well as between _MMap.v1_ and _WiredTiger_ storage engine.