DATAMONGO-2199 - Fix deprecation warnings.
Fix those deprecations with alternatives available. Some still have to remain in code as it is unclear which API to use with the 4.x driver. Leave some TODOs in the code to find those spots when upgrading to the 4.0 MongoDB Java Driver. Original pull request: #643.
This commit is contained in:
committed by
Mark Paluch
parent
89fde7f8e9
commit
f7f004ec8a
@@ -17,6 +17,7 @@ package org.springframework.data.mongodb.config;
|
||||
|
||||
import java.beans.PropertyEditorSupport;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.URLDecoder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
@@ -26,6 +27,7 @@ import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import com.mongodb.MongoCredential;
|
||||
@@ -78,12 +80,23 @@ public class MongoCredentialPropertyEditor extends PropertyEditorSupport {
|
||||
|
||||
verifyUserNamePresent(userNameAndPassword);
|
||||
credentials.add(MongoCredential.createGSSAPICredential(userNameAndPassword[0]));
|
||||
} else if (MongoCredential.MONGODB_CR_MECHANISM.equals(authMechanism)) {
|
||||
} else if ("MONGODB-CR".equals(authMechanism)) {
|
||||
|
||||
verifyUsernameAndPasswordPresent(userNameAndPassword);
|
||||
verifyDatabasePresent(database);
|
||||
credentials.add(MongoCredential.createMongoCRCredential(userNameAndPassword[0], database,
|
||||
userNameAndPassword[1].toCharArray()));
|
||||
|
||||
Method createCRCredentialMethod = ReflectionUtils.findMethod(MongoCredential.class,
|
||||
"createMongoCRCredential", String.class, String.class, char[].class);
|
||||
|
||||
if (createCRCredentialMethod == null) {
|
||||
throw new IllegalArgumentException("MONGODB-CR is no longer supported.");
|
||||
}
|
||||
|
||||
MongoCredential credential = MongoCredential.class
|
||||
.cast(ReflectionUtils.invokeMethod(createCRCredentialMethod, null, userNameAndPassword[0], database,
|
||||
userNameAndPassword[1].toCharArray()));
|
||||
credentials.add(credential);
|
||||
|
||||
} else if (MongoCredential.MONGODB_X509_MECHANISM.equals(authMechanism)) {
|
||||
|
||||
verifyUserNamePresent(userNameAndPassword);
|
||||
|
||||
@@ -38,11 +38,10 @@ import org.springframework.data.mongodb.core.query.Criteria;
|
||||
import org.springframework.data.mongodb.core.query.Query;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.LinkedMultiValueMap;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
|
||||
import com.mongodb.util.JSONParseException;
|
||||
|
||||
/**
|
||||
* Common operations performed on an entity in the context of it's mapping metadata.
|
||||
*
|
||||
@@ -165,8 +164,15 @@ class EntityOperations {
|
||||
|
||||
try {
|
||||
return Document.parse(source);
|
||||
} catch (JSONParseException | org.bson.json.JsonParseException o_O) {
|
||||
} catch (org.bson.json.JsonParseException o_O) {
|
||||
throw new MappingException("Could not parse given String to save into a JSON document!", o_O);
|
||||
} catch (RuntimeException o_O) {
|
||||
|
||||
// legacy 3.x exception
|
||||
if (ClassUtils.matchesTypeName(o_O.getClass(), "JSONParseException")) {
|
||||
throw new MappingException("Could not parse given String to save into a JSON document!", o_O);
|
||||
}
|
||||
throw o_O;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ public class MongoClientOptionsFactoryBean extends AbstractFactoryBean<MongoClie
|
||||
|
||||
private static final MongoClientOptions DEFAULT_MONGO_OPTIONS = MongoClientOptions.builder().build();
|
||||
|
||||
private @Nullable String description = DEFAULT_MONGO_OPTIONS.getDescription();
|
||||
private @Nullable String description = DEFAULT_MONGO_OPTIONS.getApplicationName(); // TODO: Mongo Driver 4 - use application name insetad of desription if not available
|
||||
private int minConnectionsPerHost = DEFAULT_MONGO_OPTIONS.getMinConnectionsPerHost();
|
||||
private int connectionsPerHost = DEFAULT_MONGO_OPTIONS.getConnectionsPerHost();
|
||||
private int threadsAllowedToBlockForConnectionMultiplier = DEFAULT_MONGO_OPTIONS
|
||||
@@ -51,14 +51,14 @@ public class MongoClientOptionsFactoryBean extends AbstractFactoryBean<MongoClie
|
||||
private int maxConnectionLifeTime = DEFAULT_MONGO_OPTIONS.getMaxConnectionLifeTime();
|
||||
private int connectTimeout = DEFAULT_MONGO_OPTIONS.getConnectTimeout();
|
||||
private int socketTimeout = DEFAULT_MONGO_OPTIONS.getSocketTimeout();
|
||||
private boolean socketKeepAlive = DEFAULT_MONGO_OPTIONS.isSocketKeepAlive();
|
||||
private boolean socketKeepAlive = DEFAULT_MONGO_OPTIONS.isSocketKeepAlive(); // TODO: Mongo Driver 4 - check if available
|
||||
private @Nullable ReadPreference readPreference = DEFAULT_MONGO_OPTIONS.getReadPreference();
|
||||
private DBDecoderFactory dbDecoderFactory = DEFAULT_MONGO_OPTIONS.getDbDecoderFactory();
|
||||
private DBEncoderFactory dbEncoderFactory = DEFAULT_MONGO_OPTIONS.getDbEncoderFactory();
|
||||
private @Nullable WriteConcern writeConcern = DEFAULT_MONGO_OPTIONS.getWriteConcern();
|
||||
private @Nullable SocketFactory socketFactory = DEFAULT_MONGO_OPTIONS.getSocketFactory();
|
||||
private boolean cursorFinalizerEnabled = DEFAULT_MONGO_OPTIONS.isCursorFinalizerEnabled();
|
||||
private boolean alwaysUseMBeans = DEFAULT_MONGO_OPTIONS.isAlwaysUseMBeans();
|
||||
private boolean alwaysUseMBeans = DEFAULT_MONGO_OPTIONS.isAlwaysUseMBeans(); // TODO: Mongo Driver 4 - remove this option
|
||||
private int heartbeatFrequency = DEFAULT_MONGO_OPTIONS.getHeartbeatFrequency();
|
||||
private int minHeartbeatFrequency = DEFAULT_MONGO_OPTIONS.getMinHeartbeatFrequency();
|
||||
private int heartbeatConnectTimeout = DEFAULT_MONGO_OPTIONS.getHeartbeatConnectTimeout();
|
||||
@@ -74,6 +74,7 @@ public class MongoClientOptionsFactoryBean extends AbstractFactoryBean<MongoClie
|
||||
*
|
||||
* @param description
|
||||
*/
|
||||
// TODO: Mongo Driver 4 - deprecate that one and add application name
|
||||
public void setDescription(@Nullable String description) {
|
||||
this.description = description;
|
||||
}
|
||||
@@ -285,7 +286,7 @@ public class MongoClientOptionsFactoryBean extends AbstractFactoryBean<MongoClie
|
||||
.cursorFinalizerEnabled(cursorFinalizerEnabled) //
|
||||
.dbDecoderFactory(dbDecoderFactory) //
|
||||
.dbEncoderFactory(dbEncoderFactory) //
|
||||
.description(description) //
|
||||
.applicationName(description) // TODO: Mongo Driver 4 - use applicatoin name if description not available
|
||||
.heartbeatConnectTimeout(heartbeatConnectTimeout) //
|
||||
.heartbeatFrequency(heartbeatFrequency) //
|
||||
.heartbeatSocketTimeout(heartbeatSocketTimeout) //
|
||||
@@ -297,8 +298,8 @@ public class MongoClientOptionsFactoryBean extends AbstractFactoryBean<MongoClie
|
||||
.readPreference(readPreference) //
|
||||
.requiredReplicaSetName(requiredReplicaSetName) //
|
||||
.serverSelectionTimeout(serverSelectionTimeout) //
|
||||
.socketFactory(socketFactoryToUse) //
|
||||
.socketKeepAlive(socketKeepAlive) //
|
||||
.socketFactory(socketFactoryToUse) // TODO: Mongo Driver 4 - remove if not available
|
||||
.socketKeepAlive(socketKeepAlive) // TODO: Mongo Driver 4 - remove if not available
|
||||
.socketTimeout(socketTimeout) //
|
||||
.threadsAllowedToBlockForConnectionMultiplier(threadsAllowedToBlockForConnectionMultiplier) //
|
||||
.writeConcern(writeConcern).build();
|
||||
|
||||
@@ -26,7 +26,6 @@ import java.util.Map.Entry;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.bson.BSON;
|
||||
import org.bson.BsonRegularExpression;
|
||||
import org.bson.Document;
|
||||
import org.bson.types.Binary;
|
||||
@@ -67,6 +66,20 @@ public class Criteria implements CriteriaDefinition {
|
||||
*/
|
||||
private static final Object NOT_SET = new Object();
|
||||
|
||||
private static final int[] FLAG_LOOKUP = new int[Character.MAX_VALUE];
|
||||
|
||||
static {
|
||||
FLAG_LOOKUP['g'] = 256;
|
||||
FLAG_LOOKUP['i'] = Pattern.CASE_INSENSITIVE;
|
||||
FLAG_LOOKUP['m'] = Pattern.MULTILINE;
|
||||
FLAG_LOOKUP['s'] = Pattern.DOTALL;
|
||||
FLAG_LOOKUP['c'] = Pattern.CANON_EQ;
|
||||
FLAG_LOOKUP['x'] = Pattern.COMMENTS;
|
||||
FLAG_LOOKUP['d'] = Pattern.UNIX_LINES;
|
||||
FLAG_LOOKUP['t'] = Pattern.LITERAL;
|
||||
FLAG_LOOKUP['u'] = Pattern.UNICODE_CASE;
|
||||
}
|
||||
|
||||
private @Nullable String key;
|
||||
private List<Criteria> criteriaChain;
|
||||
private LinkedHashMap<String, Object> criteria = new LinkedHashMap<String, Object>();
|
||||
@@ -450,7 +463,7 @@ public class Criteria implements CriteriaDefinition {
|
||||
|
||||
Assert.notNull(regex, "Regex string must not be null!");
|
||||
|
||||
return Pattern.compile(regex, options == null ? 0 : BSON.regexFlags(options));
|
||||
return Pattern.compile(regex, regexFlags(options));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -905,6 +918,47 @@ public class Criteria implements CriteriaDefinition {
|
||||
|| (value instanceof GeoCommand && ((GeoCommand) value).getShape() instanceof GeoJson);
|
||||
}
|
||||
|
||||
/**
|
||||
* Lookup the MongoDB specific flags for a given regex option string.
|
||||
*
|
||||
* @param s the Regex option/flag to look up. Can be {@literal null}.
|
||||
* @return zero if given {@link String} is {@literal null} or empty.
|
||||
* @since 2.2
|
||||
*/
|
||||
private static int regexFlags(@Nullable String s) {
|
||||
|
||||
int flags = 0;
|
||||
|
||||
if (s == null) {
|
||||
return flags;
|
||||
}
|
||||
|
||||
for (final char f : s.toLowerCase().toCharArray()) {
|
||||
flags |= regexFlag(f);
|
||||
}
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lookup the MongoDB specific flags for a given character.
|
||||
*
|
||||
* @param c the Regex option/flag to look up.
|
||||
* @return
|
||||
* @throws IllegalArgumentException for unkown flags
|
||||
* @since 2.2
|
||||
*/
|
||||
private static int regexFlag(final char c) {
|
||||
|
||||
int flag = FLAG_LOOKUP[c];
|
||||
|
||||
if (flag == 0) {
|
||||
throw new IllegalArgumentException(String.format("Unrecognized flag [%c]", c));
|
||||
}
|
||||
|
||||
return flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* MongoDB specific <a href="https://docs.mongodb.com/manual/reference/operator/query-bitwise/">bitwise query
|
||||
* operators</a> like {@code $bitsAllClear, $bitsAllSet,...} for usage with {@link Criteria#bits()} and {@link Query}.
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package org.springframework.data.mongodb.core.query;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
@@ -22,10 +23,11 @@ import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.bson.Document;
|
||||
import org.bson.json.JsonMode;
|
||||
import org.bson.json.JsonWriterSettings;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
import com.mongodb.util.JSON;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
/**
|
||||
* Utility methods for JSON serialization.
|
||||
@@ -118,19 +120,34 @@ public abstract class SerializationUtils {
|
||||
}
|
||||
|
||||
try {
|
||||
return value instanceof Document ? ((Document) value).toJson() : JSON.serialize(value);
|
||||
String json = value instanceof Document ? ((Document) value).toJson() : serializeValue(value);
|
||||
return json.replaceAll("\"\\:", "\" :").replaceAll("\\{\"", "{ \""); //.replaceAll("\\]\\}", "] }");
|
||||
} catch (Exception e) {
|
||||
|
||||
if (value instanceof Collection) {
|
||||
return toString((Collection<?>) value);
|
||||
} else if (value instanceof Map) {
|
||||
return toString((Map<?, ?>) value);
|
||||
} else {
|
||||
} else if (ObjectUtils.isArray(value)) {
|
||||
return toString(Arrays.asList(ObjectUtils.toObjectArray(value)));
|
||||
}
|
||||
|
||||
else {
|
||||
return String.format("{ \"$java\" : %s }", value.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static String serializeValue(@Nullable Object value) {
|
||||
|
||||
if(value == null) {
|
||||
return "null";
|
||||
}
|
||||
|
||||
String documentJson = new Document("toBeEncoded", value).toJson();
|
||||
return documentJson.substring(documentJson.indexOf(':') + 1, documentJson.length() - 1).trim();
|
||||
}
|
||||
|
||||
private static String toString(Map<?, ?> source) {
|
||||
return iterableToDelimitedString(source.entrySet(), "{ ", " }",
|
||||
entry -> String.format("\"%s\" : %s", entry.getKey(), serializeToJsonSafely(entry.getValue())));
|
||||
|
||||
@@ -39,6 +39,7 @@ import org.bson.codecs.UuidCodec;
|
||||
import org.bson.json.JsonWriter;
|
||||
import org.bson.types.Binary;
|
||||
import org.springframework.data.mongodb.CodecRegistryProvider;
|
||||
import org.springframework.data.mongodb.core.query.SerializationUtils;
|
||||
import org.springframework.data.mongodb.repository.query.StringBasedMongoQuery.ParameterBinding;
|
||||
import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider;
|
||||
import org.springframework.expression.EvaluationContext;
|
||||
@@ -52,7 +53,6 @@ import org.springframework.util.StringUtils;
|
||||
|
||||
import com.mongodb.DBObject;
|
||||
import com.mongodb.MongoClient;
|
||||
import com.mongodb.util.JSON;
|
||||
|
||||
/**
|
||||
* {@link ExpressionEvaluatingParameterBinder} allows to evaluate, convert and bind parameters to placeholders within a
|
||||
@@ -221,7 +221,8 @@ class ExpressionEvaluatingParameterBinder {
|
||||
return (String) value;
|
||||
}
|
||||
|
||||
return binding.isExpression() ? JSON.serialize(value) : QuotedString.unquote(JSON.serialize(value));
|
||||
String encodedValue = serialize(value);
|
||||
return binding.isExpression() ? encodedValue : QuotedString.unquote(encodedValue);
|
||||
}
|
||||
|
||||
return EncodableValue.create(value).encode(codecRegistryProvider, binding.isQuoted());
|
||||
@@ -660,7 +661,11 @@ class ExpressionEvaluatingParameterBinder {
|
||||
*/
|
||||
@Override
|
||||
public String encode(CodecRegistryProvider provider, boolean quoted) {
|
||||
return JSON.serialize(this.value);
|
||||
return serialize(this.value);
|
||||
}
|
||||
}
|
||||
|
||||
static String serialize(Object value) {
|
||||
return SerializationUtils.serializeValue(value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -270,6 +270,7 @@ public class MongoQueryMethod extends QueryMethod {
|
||||
}
|
||||
|
||||
if (meta.maxScanDocuments() > 0) {
|
||||
// TODO: Mongo 4 - removal
|
||||
metaAttributes.setMaxScan(meta.maxScanDocuments());
|
||||
}
|
||||
|
||||
@@ -282,6 +283,8 @@ public class MongoQueryMethod extends QueryMethod {
|
||||
}
|
||||
|
||||
if (meta.snapshot()) {
|
||||
|
||||
// TODO: Mongo 4 - removal
|
||||
metaAttributes.setSnapshot(meta.snapshot());
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
package org.springframework.data.mongodb.repository.query;
|
||||
|
||||
import org.bson.Document;
|
||||
import org.bson.json.JsonParseException;
|
||||
import org.springframework.data.mapping.context.MappingContext;
|
||||
import org.springframework.data.mongodb.core.MongoOperations;
|
||||
import org.springframework.data.mongodb.core.MongoTemplate;
|
||||
@@ -31,10 +32,6 @@ import org.springframework.data.repository.query.ReturnedType;
|
||||
import org.springframework.data.repository.query.parser.PartTree;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import com.mongodb.BasicDBObject;
|
||||
import com.mongodb.util.JSON;
|
||||
import com.mongodb.util.JSONParseException;
|
||||
|
||||
/**
|
||||
* {@link RepositoryQuery} implementation for Mongo.
|
||||
*
|
||||
@@ -114,12 +111,12 @@ public class PartTreeMongoQuery extends AbstractMongoQuery {
|
||||
|
||||
try {
|
||||
|
||||
BasicQuery result = new BasicQuery(query.getQueryObject(), new Document((BasicDBObject) JSON.parse(fieldSpec)));
|
||||
BasicQuery result = new BasicQuery(query.getQueryObject(), Document.parse(fieldSpec));
|
||||
result.setSortObject(query.getSortObject());
|
||||
|
||||
return result;
|
||||
|
||||
} catch (JSONParseException o_O) {
|
||||
} catch (JsonParseException o_O) {
|
||||
throw new IllegalStateException(String.format("Invalid query or field specification in %s!", getQueryMethod()),
|
||||
o_O);
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
package org.springframework.data.mongodb.repository.query;
|
||||
|
||||
import org.bson.Document;
|
||||
import org.bson.json.JsonParseException;
|
||||
import org.springframework.data.mapping.context.MappingContext;
|
||||
import org.springframework.data.mongodb.core.MongoTemplate;
|
||||
import org.springframework.data.mongodb.core.ReactiveMongoOperations;
|
||||
@@ -30,8 +31,6 @@ import org.springframework.data.repository.query.ReturnedType;
|
||||
import org.springframework.data.repository.query.parser.PartTree;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import com.mongodb.util.JSONParseException;
|
||||
|
||||
/**
|
||||
* Reactive PartTree {@link RepositoryQuery} implementation for Mongo.
|
||||
*
|
||||
@@ -110,7 +109,7 @@ public class ReactivePartTreeMongoQuery extends AbstractReactiveMongoQuery {
|
||||
|
||||
return result;
|
||||
|
||||
} catch (JSONParseException o_O) {
|
||||
} catch (JsonParseException o_O) {
|
||||
throw new IllegalStateException(String.format("Invalid query or field specification in %s!", getQueryMethod()),
|
||||
o_O);
|
||||
}
|
||||
|
||||
@@ -228,6 +228,8 @@ public class StringBasedMongoQuery extends AbstractMongoQuery {
|
||||
String transformedInput = transformQueryAndCollectExpressionParametersIntoBindings(input, bindings);
|
||||
String parseableInput = makeParameterReferencesParseable(transformedInput);
|
||||
|
||||
// Document.parse(parseableInput)
|
||||
|
||||
collectParameterReferencesIntoBindings(bindings,
|
||||
JSON.parse(parseableInput, new LenientPatternDecodingCallback()));
|
||||
|
||||
|
||||
@@ -86,8 +86,12 @@ public class AbstractReactiveMongoConfigurationUnitTests {
|
||||
assertThat(context.getBean(SimpleReactiveMongoDatabaseFactory.class), is(notNullValue()));
|
||||
|
||||
exception.expect(NoSuchBeanDefinitionException.class);
|
||||
context.getBean(Mongo.class);
|
||||
context.close();
|
||||
|
||||
try {
|
||||
context.getBean(Mongo.class);
|
||||
} finally {
|
||||
context.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1444
|
||||
|
||||
@@ -62,7 +62,7 @@ public class MongoClientParserIntegrationTests {
|
||||
assertThat(factory.getBean("mongo-client-with-host-and-port"), instanceOf(MongoClient.class));
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1158
|
||||
@Test // DATAMONGO-1158, DATAMONGO-2199
|
||||
public void createsMongoClientWithOptionsCorrectly() {
|
||||
|
||||
reader.loadBeanDefinitions(new ClassPathResource("namespace/mongoClient-bean.xml"));
|
||||
@@ -75,7 +75,7 @@ public class MongoClientParserIntegrationTests {
|
||||
MongoClient.class);
|
||||
|
||||
assertThat(client.getReadPreference(), is(ReadPreference.secondary()));
|
||||
assertThat(client.getWriteConcern(), is(WriteConcern.NORMAL));
|
||||
assertThat(client.getWriteConcern(), is(WriteConcern.UNACKNOWLEDGED));
|
||||
} finally {
|
||||
context.close();
|
||||
}
|
||||
|
||||
@@ -23,7 +23,6 @@ import org.junit.Test;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.config.ConstructorArgumentValues;
|
||||
import org.springframework.beans.factory.config.ConstructorArgumentValues.ValueHolder;
|
||||
import org.springframework.beans.factory.parsing.BeanDefinitionParsingException;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionReader;
|
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
|
||||
@@ -58,23 +57,23 @@ public class MongoDbFactoryParserIntegrationTests {
|
||||
reader = new XmlBeanDefinitionReader(factory);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test // DATAMONGO-2199
|
||||
public void testWriteConcern() throws Exception {
|
||||
|
||||
SimpleMongoDbFactory dbFactory = new SimpleMongoDbFactory(new MongoClient("localhost"), "database");
|
||||
dbFactory.setWriteConcern(WriteConcern.SAFE);
|
||||
dbFactory.setWriteConcern(WriteConcern.ACKNOWLEDGED);
|
||||
dbFactory.getDb();
|
||||
|
||||
assertThat(ReflectionTestUtils.getField(dbFactory, "writeConcern"), is((Object) WriteConcern.SAFE));
|
||||
assertThat(ReflectionTestUtils.getField(dbFactory, "writeConcern"), is((Object) WriteConcern.ACKNOWLEDGED));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test // DATAMONGO-2199
|
||||
public void parsesWriteConcern() {
|
||||
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("namespace/db-factory-bean.xml");
|
||||
assertWriteConcern(ctx, WriteConcern.SAFE);
|
||||
assertWriteConcern(ctx, WriteConcern.ACKNOWLEDGED);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test // DATAMONGO-2199
|
||||
public void parsesCustomWriteConcern() {
|
||||
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext(
|
||||
"namespace/db-factory-bean-custom-write-concern.xml");
|
||||
@@ -89,7 +88,7 @@ public class MongoDbFactoryParserIntegrationTests {
|
||||
MongoDbFactory factory = ctx.getBean("second", MongoDbFactory.class);
|
||||
MongoDatabase db = factory.getDb();
|
||||
|
||||
assertThat(db.getWriteConcern(), is(WriteConcern.REPLICAS_SAFE));
|
||||
assertThat(db.getWriteConcern(), is(WriteConcern.W2));
|
||||
ctx.close();
|
||||
}
|
||||
|
||||
|
||||
@@ -26,14 +26,15 @@ import com.mongodb.WriteConcern;
|
||||
* Unit tests for {@link StringToWriteConcernConverter}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Christoph Strobl
|
||||
*/
|
||||
public class StringToWriteConcernConverterUnitTests {
|
||||
|
||||
StringToWriteConcernConverter converter = new StringToWriteConcernConverter();
|
||||
|
||||
@Test
|
||||
@Test // DATAMONGO-2199
|
||||
public void createsWellKnownConstantsCorrectly() {
|
||||
assertThat(converter.convert("SAFE"), is(WriteConcern.SAFE));
|
||||
assertThat(converter.convert("ACKNOWLEDGED"), is(WriteConcern.ACKNOWLEDGED));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -27,6 +27,7 @@ import com.mongodb.WriteConcern;
|
||||
* Unit tests for {@link WriteConcernPropertyEditor}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Christoph Strobl
|
||||
*/
|
||||
public class WriteConcernPropertyEditorUnitTests {
|
||||
|
||||
@@ -37,11 +38,11 @@ public class WriteConcernPropertyEditorUnitTests {
|
||||
editor = new WriteConcernPropertyEditor();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test // DATAMONGO-2199
|
||||
public void createsWriteConcernForWellKnownConstants() {
|
||||
|
||||
editor.setAsText("SAFE");
|
||||
assertThat(editor.getValue(), is((Object) WriteConcern.SAFE));
|
||||
editor.setAsText("JOURNALED");
|
||||
assertThat(editor.getValue(), is((Object) WriteConcern.JOURNALED));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -26,6 +26,7 @@ import static org.springframework.data.mongodb.core.query.Criteria.*;
|
||||
import static org.springframework.data.mongodb.core.query.Query.*;
|
||||
import static org.springframework.data.mongodb.core.query.Update.*;
|
||||
|
||||
import com.mongodb.MongoClient;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
@@ -108,7 +109,6 @@ import org.springframework.util.StringUtils;
|
||||
import com.mongodb.BasicDBObject;
|
||||
import com.mongodb.DBObject;
|
||||
import com.mongodb.DBRef;
|
||||
import com.mongodb.Mongo;
|
||||
import com.mongodb.MongoException;
|
||||
import com.mongodb.ReadPreference;
|
||||
import com.mongodb.WriteConcern;
|
||||
@@ -160,7 +160,7 @@ public class MongoTemplateTests {
|
||||
}
|
||||
|
||||
@Autowired
|
||||
public void setMongo(Mongo mongo) throws Exception {
|
||||
public void setMongoClient(MongoClient mongo) throws Exception {
|
||||
|
||||
CustomConversions conversions = new MongoCustomConversions(
|
||||
Arrays.asList(DateToDateTimeConverter.INSTANCE, DateTimeToDateConverter.INSTANCE));
|
||||
@@ -2820,9 +2820,9 @@ public class MongoTemplateTests {
|
||||
|
||||
assertThat(result, hasSize(2));
|
||||
|
||||
assertThat(template.getDb().getCollection("sample").count(
|
||||
assertThat(template.getDb().getCollection("sample").countDocuments(
|
||||
new org.bson.Document("field", new org.bson.Document("$in", Arrays.asList("spring", "mongodb")))), is(0L));
|
||||
assertThat(template.getDb().getCollection("sample").count(new org.bson.Document("field", "data")), is(1L));
|
||||
assertThat(template.getDb().getCollection("sample").countDocuments(new org.bson.Document("field", "data")), is(1L));
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1001
|
||||
|
||||
@@ -116,7 +116,7 @@ public class MongoTemplateTransactionTests {
|
||||
|
||||
assertionList.forEach(it -> {
|
||||
|
||||
boolean isPresent = collection.count(Filters.eq("_id", it.getId())) != 0;
|
||||
boolean isPresent = collection.countDocuments(Filters.eq("_id", it.getId())) != 0;
|
||||
|
||||
assertThat(isPresent).isEqualTo(it.shouldBePresent())
|
||||
.withFailMessage(String.format("After transaction entity %s should %s.", it.getPersistable(),
|
||||
|
||||
@@ -140,7 +140,7 @@ public class MongoTemplateUnitTests extends MongoOperationsUnitTests {
|
||||
when(db.runCommand(any(), any(Class.class))).thenReturn(commandResultDocument);
|
||||
when(collection.find(any(org.bson.Document.class), any(Class.class))).thenReturn(findIterable);
|
||||
when(collection.mapReduce(any(), any(), eq(Document.class))).thenReturn(mapReduceIterable);
|
||||
when(collection.count(any(Bson.class), any(CountOptions.class))).thenReturn(1L);
|
||||
when(collection.count(any(Bson.class), any(CountOptions.class))).thenReturn(1L); // TODO: MongoDB 4 - fix me decprecated
|
||||
when(collection.getNamespace()).thenReturn(new MongoNamespace("db.mock-collection"));
|
||||
when(collection.aggregate(any(List.class), any())).thenReturn(aggregateIterable);
|
||||
when(collection.withReadPreference(any())).thenReturn(collection);
|
||||
|
||||
@@ -41,7 +41,7 @@ public class SerializationUtilsUnitTests {
|
||||
public void writesSimpleDocument() {
|
||||
|
||||
Document document = new Document("foo", "bar");
|
||||
assertThat(serializeToJsonSafely(document), is(document.toJson()));
|
||||
assertThat(serializeToJsonSafely(document), is("{ \"foo\" : \"bar\"}"));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -75,7 +75,7 @@ public abstract class AbstractGeoSpatialTests {
|
||||
@Before
|
||||
public void setUp() {
|
||||
|
||||
template.setWriteConcern(WriteConcern.FSYNC_SAFE);
|
||||
template.setWriteConcern(WriteConcern.JOURNALED);
|
||||
|
||||
createIndex();
|
||||
addVenues();
|
||||
|
||||
@@ -82,7 +82,7 @@ public class GeoJsonTests {
|
||||
@Before
|
||||
public void setUp() {
|
||||
|
||||
template.setWriteConcern(WriteConcern.FSYNC_SAFE);
|
||||
template.setWriteConcern(WriteConcern.JOURNALED);
|
||||
|
||||
createIndex();
|
||||
addVenues();
|
||||
|
||||
@@ -56,7 +56,7 @@ public class GeoSpatialIndexTests extends AbstractIntegrationTests {
|
||||
@Before
|
||||
public void setUp() {
|
||||
|
||||
template.setWriteConcern(WriteConcern.FSYNC_SAFE);
|
||||
template.setWriteConcern(WriteConcern.JOURNALED);
|
||||
template.setWriteResultChecking(WriteResultChecking.EXCEPTION);
|
||||
}
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ public class TextIndexTests extends AbstractIntegrationTests {
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
|
||||
template.setWriteConcern(WriteConcern.FSYNC_SAFE);
|
||||
template.setWriteConcern(WriteConcern.JOURNALED);
|
||||
this.indexOps = template.indexOps(TextIndexedDocumentRoot.class);
|
||||
}
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ import java.net.UnknownHostException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.bson.Document;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
@@ -33,12 +34,10 @@ import org.springframework.data.mongodb.core.MongoTemplate;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
import com.mongodb.DB;
|
||||
import org.bson.Document;
|
||||
import com.mongodb.Mongo;
|
||||
import com.mongodb.MongoClient;
|
||||
import com.mongodb.MongoException;
|
||||
import com.mongodb.client.MongoCollection;
|
||||
import com.mongodb.client.MongoDatabase;
|
||||
|
||||
/**
|
||||
* @author Jon Brisbin
|
||||
@@ -66,8 +65,8 @@ public class GeoIndexedTests {
|
||||
|
||||
private void cleanDb() throws UnknownHostException {
|
||||
|
||||
Mongo mongo = new MongoClient();
|
||||
DB db = mongo.getDB(GeoIndexedAppConfig.GEO_DB);
|
||||
MongoClient mongo = new MongoClient();
|
||||
MongoDatabase db = mongo.getDatabase(GeoIndexedAppConfig.GEO_DB);
|
||||
|
||||
for (String coll : collectionsToDrop) {
|
||||
db.getCollection(coll).drop();
|
||||
|
||||
@@ -90,7 +90,7 @@ public class ApplicationContextEventTests {
|
||||
|
||||
applicationContext = new AnnotationConfigApplicationContext(ApplicationContextEventTestsAppConfig.class);
|
||||
template = applicationContext.getBean(MongoTemplate.class);
|
||||
template.setWriteConcern(WriteConcern.FSYNC_SAFE);
|
||||
template.setWriteConcern(WriteConcern.JOURNALED);
|
||||
listener = applicationContext.getBean(SimpleMappingEventListener.class);
|
||||
}
|
||||
|
||||
|
||||
@@ -467,11 +467,11 @@ public class UpdateTests {
|
||||
assertThat(update.getUpdateObject()).isEqualTo(new Document("$min", new Document("key", date)));
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1777
|
||||
@Test // DATAMONGO-1777, DATAMONGO-2199
|
||||
public void toStringShouldPrettyPrintModifiers() {
|
||||
|
||||
assertThat(new Update().push("key").atPosition(Position.FIRST).value("Arya").toString()).isEqualTo(
|
||||
"{ \"$push\" : { \"key\" : { \"$java\" : { \"$position\" : { \"$java\" : { \"$position\" : 0} }, \"$each\" : { \"$java\" : { \"$each\" : [ \"Arya\"]} } } } } }");
|
||||
"{ \"$push\" : { \"key\" : { \"$java\" : { \"$position\" : { \"$java\" : { \"$position\" : 0} }, \"$each\" : { \"$java\" : { \"$each\" : [ \"Arya\" ] } } } } } }");
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1777, DATAMONGO-2198
|
||||
|
||||
@@ -19,20 +19,12 @@ import static org.springframework.data.mongodb.core.query.Criteria.*;
|
||||
import static org.springframework.data.mongodb.core.query.Query.*;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.mongodb.client.FindIterable;
|
||||
import com.mongodb.client.model.CreateCollectionOptions;
|
||||
import org.bson.Document;
|
||||
import org.bson.types.ObjectId;
|
||||
import org.junit.Before;
|
||||
@@ -53,12 +45,13 @@ import org.springframework.util.StringUtils;
|
||||
|
||||
import com.mongodb.BasicDBList;
|
||||
import com.mongodb.BasicDBObject;
|
||||
import com.mongodb.DB;
|
||||
import com.mongodb.DBCollection;
|
||||
import com.mongodb.DBCursor;
|
||||
import com.mongodb.DBObject;
|
||||
import com.mongodb.MongoClient;
|
||||
import com.mongodb.WriteConcern;
|
||||
import com.mongodb.client.MongoCollection;
|
||||
import com.mongodb.client.MongoDatabase;
|
||||
|
||||
/**
|
||||
* Test class to execute performance tests for plain MongoDB driver usage, {@link MongoTemplate} and the repositories
|
||||
@@ -76,7 +69,7 @@ public class PerformanceTests {
|
||||
private static final StopWatch watch = new StopWatch();
|
||||
private static final Collection<String> IGNORED_WRITE_CONCERNS = Arrays.asList("MAJORITY", "REPLICAS_SAFE",
|
||||
"FSYNC_SAFE", "FSYNCED", "JOURNAL_SAFE", "JOURNALED", "REPLICA_ACKNOWLEDGED", "W2", "W3");
|
||||
private static final int COLLECTION_SIZE = 1024-2018 * 1024-2018 * 256; // 256 MB
|
||||
private static final int COLLECTION_SIZE = 1024 - 2018 * 1024 - 2018 * 256; // 256 MB
|
||||
private static final Collection<String> COLLECTION_NAMES = Arrays.asList("template", "driver", "person");
|
||||
|
||||
MongoClient mongo;
|
||||
@@ -149,7 +142,7 @@ public class PerformanceTests {
|
||||
List<Person> persons = new ArrayList<PerformanceTests.Person>();
|
||||
|
||||
for (Document document : documents) {
|
||||
persons.add(Person.from(new BasicDBObject(document)));
|
||||
persons.add(Person.from(document));
|
||||
}
|
||||
|
||||
return persons;
|
||||
@@ -182,7 +175,7 @@ public class PerformanceTests {
|
||||
@Test
|
||||
public void writeAndRead() throws Exception {
|
||||
|
||||
mongo.setWriteConcern(WriteConcern.SAFE);
|
||||
mongo.setWriteConcern(WriteConcern.ACKNOWLEDGED);
|
||||
|
||||
readsAndWrites(NUMBER_OF_PERSONS, ITERATIONS);
|
||||
}
|
||||
@@ -257,19 +250,26 @@ public class PerformanceTests {
|
||||
|
||||
private void setupCollections() {
|
||||
|
||||
DB db = this.mongo.getDB(DATABASE_NAME);
|
||||
MongoDatabase db = this.mongo.getDatabase(DATABASE_NAME);
|
||||
|
||||
for (String collectionName : COLLECTION_NAMES) {
|
||||
DBCollection collection = db.getCollection(collectionName);
|
||||
|
||||
MongoCollection<Document> collection = db.getCollection(collectionName);
|
||||
collection.drop();
|
||||
collection.getDB().command(getCreateCollectionCommand(collectionName));
|
||||
collection.createIndex(new BasicDBObject("firstname", -1));
|
||||
collection.createIndex(new BasicDBObject("lastname", -1));
|
||||
|
||||
CreateCollectionOptions collectionOptions = new CreateCollectionOptions();
|
||||
collectionOptions.capped(false);
|
||||
collectionOptions.sizeInBytes(COLLECTION_SIZE);
|
||||
|
||||
db.createCollection(collectionName, collectionOptions);
|
||||
|
||||
collection.createIndex(new Document("firstname", -1));
|
||||
collection.createIndex(new Document("lastname", -1));
|
||||
}
|
||||
}
|
||||
|
||||
private DBObject getCreateCollectionCommand(String name) {
|
||||
DBObject document = new BasicDBObject();
|
||||
private Document getCreateCollectionCommand(String name) {
|
||||
Document document = new Document();
|
||||
document.put("createCollection", name);
|
||||
document.put("capped", false);
|
||||
document.put("size", COLLECTION_SIZE);
|
||||
@@ -278,10 +278,14 @@ public class PerformanceTests {
|
||||
|
||||
private long writingObjectsUsingPlainDriver(int numberOfPersons) {
|
||||
|
||||
DBCollection collection = mongo.getDB(DATABASE_NAME).getCollection("driver");
|
||||
MongoCollection<Document> collection = mongo.getDatabase(DATABASE_NAME).getCollection("driver");
|
||||
List<Person> persons = getPersonObjects(numberOfPersons);
|
||||
|
||||
executeWatched(() -> persons.stream().map(it -> collection.save(new BasicDBObject(it.toDocument()))));
|
||||
executeWatched(() -> persons.stream().map(Person::toDocument).map(it -> {
|
||||
|
||||
collection.insertOne(it);
|
||||
return true;
|
||||
}));
|
||||
|
||||
return watch.getLastTaskTimeMillis();
|
||||
}
|
||||
@@ -308,7 +312,7 @@ public class PerformanceTests {
|
||||
|
||||
private long readingUsingPlainDriver() {
|
||||
|
||||
executeWatched(() -> toPersons(mongo.getDB(DATABASE_NAME).getCollection("driver").find()));
|
||||
executeWatched(() -> toPersons(mongo.getDatabase(DATABASE_NAME).getCollection("driver").find()));
|
||||
|
||||
return watch.getLastTaskTimeMillis();
|
||||
}
|
||||
@@ -329,10 +333,10 @@ public class PerformanceTests {
|
||||
|
||||
executeWatched(() -> {
|
||||
|
||||
DBCollection collection = mongo.getDB(DATABASE_NAME).getCollection("driver");
|
||||
MongoCollection<Document> collection = mongo.getDatabase(DATABASE_NAME).getCollection("driver");
|
||||
|
||||
BasicDBObject regex = new BasicDBObject("$regex", Pattern.compile(".*1.*"));
|
||||
BasicDBObject query = new BasicDBObject("addresses.zipCode", regex);
|
||||
Document regex = new Document("$regex", Pattern.compile(".*1.*"));
|
||||
Document query = new Document("addresses.zipCode", regex);
|
||||
return toPersons(collection.find(query));
|
||||
});
|
||||
|
||||
@@ -385,12 +389,13 @@ public class PerformanceTests {
|
||||
}
|
||||
}
|
||||
|
||||
private static List<Person> toPersons(DBCursor cursor) {
|
||||
private static List<Person> toPersons(FindIterable<Document> cursor) {
|
||||
|
||||
List<Person> persons = new ArrayList<Person>();
|
||||
|
||||
while (cursor.hasNext()) {
|
||||
persons.add(Person.from(cursor.next()));
|
||||
Iterator<Document> it = cursor.iterator();
|
||||
while (it.hasNext()) {
|
||||
persons.add(Person.from(it.next()));
|
||||
}
|
||||
|
||||
return persons;
|
||||
@@ -410,15 +415,15 @@ public class PerformanceTests {
|
||||
this.orders = new HashSet<Order>();
|
||||
}
|
||||
|
||||
public static Person from(DBObject source) {
|
||||
public static Person from(Document source) {
|
||||
|
||||
BasicDBList addressesSource = (BasicDBList) source.get("addresses");
|
||||
List addressesSource = (List) source.get("addresses");
|
||||
List<Address> addresses = new ArrayList<Address>(addressesSource.size());
|
||||
for (Object addressSource : addressesSource) {
|
||||
addresses.add(Address.from((Document) addressSource));
|
||||
}
|
||||
|
||||
BasicDBList ordersSource = (BasicDBList) source.get("orders");
|
||||
List ordersSource = (List) source.get("orders");
|
||||
Set<Order> orders = new HashSet<Order>(ordersSource.size());
|
||||
for (Object orderSource : ordersSource) {
|
||||
orders.add(Order.from((Document) orderSource));
|
||||
|
||||
@@ -196,7 +196,7 @@ public class ReactivePerformanceTests {
|
||||
@Test // DATAMONGO-1444
|
||||
public void writeAndRead() throws Exception {
|
||||
|
||||
readsAndWrites(NUMBER_OF_PERSONS, ITERATIONS, WriteConcern.SAFE);
|
||||
readsAndWrites(NUMBER_OF_PERSONS, ITERATIONS, WriteConcern.ACKNOWLEDGED);
|
||||
}
|
||||
|
||||
private void readsAndWrites(int numberOfPersons, int iterations, WriteConcern concern) {
|
||||
|
||||
@@ -25,6 +25,7 @@ import java.lang.reflect.Method;
|
||||
import java.util.List;
|
||||
|
||||
import org.bson.Document;
|
||||
import org.bson.json.JsonParseException;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
@@ -51,8 +52,6 @@ import org.springframework.data.projection.ProjectionFactory;
|
||||
import org.springframework.data.projection.SpelAwareProxyProjectionFactory;
|
||||
import org.springframework.data.repository.core.support.DefaultRepositoryMetadata;
|
||||
|
||||
import com.mongodb.util.JSONParseException;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link PartTreeMongoQuery}.
|
||||
*
|
||||
@@ -130,7 +129,7 @@ public class PartTreeMongoQueryUnitTests {
|
||||
public void propagatesRootExceptionForInvalidQuery() {
|
||||
|
||||
exception.expect(IllegalStateException.class);
|
||||
exception.expectCause(is(instanceOf(JSONParseException.class)));
|
||||
exception.expectCause(is(instanceOf(JsonParseException.class)));
|
||||
|
||||
deriveQueryFromMethod("findByAge", 1);
|
||||
}
|
||||
|
||||
@@ -218,7 +218,7 @@ public class ReactiveStringBasedMongoQueryUnitTests {
|
||||
|
||||
org.springframework.data.mongodb.core.query.Query query = mongoQuery.createQuery(accesor);
|
||||
org.springframework.data.mongodb.core.query.Query reference = new BasicQuery("{'lastname' : { '$binary' : '"
|
||||
+ Base64Utils.encodeToString(binaryData) + "', '$type' : '" + BSON.B_GENERAL + "'}}");
|
||||
+ Base64Utils.encodeToString(binaryData) + "', '$type' : '" + 0 + "'}}");
|
||||
|
||||
assertThat(query.getQueryObject().toJson(), is(reference.getQueryObject().toJson()));
|
||||
}
|
||||
|
||||
@@ -20,8 +20,10 @@ import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.bson.Document;
|
||||
import org.junit.rules.TestRule;
|
||||
import org.junit.runner.Description;
|
||||
import org.junit.runners.model.Statement;
|
||||
@@ -33,6 +35,8 @@ import org.springframework.util.StringUtils;
|
||||
import com.mongodb.DB;
|
||||
import com.mongodb.DBCollection;
|
||||
import com.mongodb.MongoClient;
|
||||
import com.mongodb.client.MongoCollection;
|
||||
import com.mongodb.client.MongoDatabase;
|
||||
|
||||
/**
|
||||
* {@link CleanMongoDB} is a junit {@link TestRule} implementation to be used as for wiping data from MongoDB instance.
|
||||
@@ -55,7 +59,7 @@ public class CleanMongoDB implements TestRule {
|
||||
DATABASE, COLLECTION, INDEX;
|
||||
}
|
||||
|
||||
@SuppressWarnings("serial")//
|
||||
@SuppressWarnings("serial") //
|
||||
private Set<String> preserveDatabases = new HashSet<String>() {
|
||||
{
|
||||
add("admin");
|
||||
@@ -274,7 +278,7 @@ public class CleanMongoDB implements TestRule {
|
||||
continue;
|
||||
}
|
||||
|
||||
DB db = client.getDB(dbName);
|
||||
MongoDatabase db = client.getDatabase(dbName);
|
||||
dropCollectionsOrIndexIfRequried(db, initCollectionNames(db));
|
||||
}
|
||||
}
|
||||
@@ -290,13 +294,15 @@ public class CleanMongoDB implements TestRule {
|
||||
return true;
|
||||
}
|
||||
|
||||
private void dropCollectionsOrIndexIfRequried(DB db, Collection<String> collectionsToUse) {
|
||||
private void dropCollectionsOrIndexIfRequried(MongoDatabase db, Collection<String> collectionsToUse) {
|
||||
|
||||
Collection<String> availableCollections = db.listCollectionNames().into(new LinkedHashSet<>());
|
||||
|
||||
for (String collectionName : collectionsToUse) {
|
||||
|
||||
if (db.collectionExists(collectionName)) {
|
||||
if (availableCollections.contains(collectionName)) {
|
||||
|
||||
DBCollection collection = db.getCollectionFromString(collectionName);
|
||||
MongoCollection<Document> collection = db.getCollection(collectionName);
|
||||
if (collection != null) {
|
||||
|
||||
if (types.contains(Struct.COLLECTION)) {
|
||||
@@ -319,16 +325,16 @@ public class CleanMongoDB implements TestRule {
|
||||
|
||||
Collection<String> dbNamesToUse = dbNames;
|
||||
if (dbNamesToUse.isEmpty()) {
|
||||
dbNamesToUse = client.getDatabaseNames();
|
||||
dbNamesToUse = client.listDatabaseNames().into(new LinkedHashSet<>());
|
||||
}
|
||||
return dbNamesToUse;
|
||||
}
|
||||
|
||||
private Collection<String> initCollectionNames(DB db) {
|
||||
private Collection<String> initCollectionNames(MongoDatabase db) {
|
||||
|
||||
Collection<String> collectionsToUse = collectionNames;
|
||||
if (CollectionUtils.isEmpty(collectionsToUse)) {
|
||||
collectionsToUse = db.getCollectionNames();
|
||||
collectionsToUse = db.listCollectionNames().into(new LinkedHashSet<>());
|
||||
}
|
||||
return collectionsToUse;
|
||||
}
|
||||
|
||||
@@ -18,9 +18,13 @@ package org.springframework.data.mongodb.test.util;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.bson.Document;
|
||||
import org.bson.conversions.Bson;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.Description;
|
||||
@@ -30,9 +34,15 @@ import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
import org.springframework.data.mongodb.test.util.CleanMongoDB.Struct;
|
||||
|
||||
import com.mongodb.DB;
|
||||
import com.mongodb.DBCollection;
|
||||
import com.mongodb.Block;
|
||||
import com.mongodb.Function;
|
||||
import com.mongodb.MongoClient;
|
||||
import com.mongodb.client.ListCollectionsIterable;
|
||||
import com.mongodb.client.ListDatabasesIterable;
|
||||
import com.mongodb.client.MongoCollection;
|
||||
import com.mongodb.client.MongoCursor;
|
||||
import com.mongodb.client.MongoDatabase;
|
||||
import com.mongodb.client.MongoIterable;
|
||||
|
||||
/**
|
||||
* @author Christoph Strobl
|
||||
@@ -50,35 +60,152 @@ public class CleanMongoDBTests {
|
||||
private @Mock MongoClient mongoClientMock;
|
||||
|
||||
// Some Mock DBs
|
||||
private @Mock DB db1mock, db2mock;
|
||||
private @Mock DBCollection db1collection1mock, db1collection2mock, db2collection1mock;
|
||||
private @Mock MongoDatabase db1mock, db2mock;
|
||||
private @Mock MongoCollection<Document> db1collection1mock, db1collection2mock, db2collection1mock;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
@Before
|
||||
public void setUp() {
|
||||
|
||||
// DB setup
|
||||
when(mongoClientMock.getDatabaseNames()).thenReturn(Arrays.asList("admin", "db1", "db2"));
|
||||
when(mongoClientMock.getDB(eq("db1"))).thenReturn(db1mock);
|
||||
when(mongoClientMock.getDB(eq("db2"))).thenReturn(db2mock);
|
||||
when(mongoClientMock.listDatabaseNames()).thenReturn(new ListDatabasesIterable<String>() {
|
||||
@Override
|
||||
public ListDatabasesIterable<String> maxTime(long maxTime, TimeUnit timeUnit) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// collections have to exist
|
||||
when(db1mock.collectionExists(anyString())).thenReturn(true);
|
||||
when(db2mock.collectionExists(anyString())).thenReturn(true);
|
||||
@Override
|
||||
public ListDatabasesIterable<String> batchSize(int batchSize) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// init collection names per database
|
||||
when(db1mock.getCollectionNames()).thenReturn(new HashSet<String>() {
|
||||
{
|
||||
add("db1collection1");
|
||||
add("db1collection2");
|
||||
@Override
|
||||
public ListDatabasesIterable<String> filter(Bson filter) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListDatabasesIterable<String> nameOnly(Boolean nameOnly) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MongoCursor<String> iterator() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String first() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <U> MongoIterable<U> map(Function<String, U> mapper) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void forEach(Block<? super String> block) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public <A extends Collection<? super String>> A into(A target) {
|
||||
return (A) Arrays.asList("admin", "db1", "db2");
|
||||
}
|
||||
});
|
||||
when(mongoClientMock.getDatabase(eq("db1"))).thenReturn(db1mock);
|
||||
when(mongoClientMock.getDatabase(eq("db2"))).thenReturn(db2mock);
|
||||
|
||||
// collections have to exist
|
||||
when(db1mock.listCollectionNames()).thenReturn(new ListCollectionsIterable<String>() {
|
||||
@Override
|
||||
public ListCollectionsIterable<String> filter(Bson filter) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListCollectionsIterable<String> maxTime(long maxTime, TimeUnit timeUnit) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListCollectionsIterable<String> batchSize(int batchSize) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MongoCursor<String> iterator() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String first() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <U> MongoIterable<U> map(Function<String, U> mapper) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void forEach(Block<? super String> block) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public <A extends Collection<? super String>> A into(A target) {
|
||||
return (A) Arrays.asList("db1collection1", "db1collection2");
|
||||
}
|
||||
});
|
||||
|
||||
when(db2mock.listCollectionNames()).thenReturn(new ListCollectionsIterable<String>() {
|
||||
@Override
|
||||
public ListCollectionsIterable<String> filter(Bson filter) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListCollectionsIterable<String> maxTime(long maxTime, TimeUnit timeUnit) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListCollectionsIterable<String> batchSize(int batchSize) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MongoCursor<String> iterator() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String first() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <U> MongoIterable<U> map(Function<String, U> mapper) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void forEach(Block<? super String> block) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public <A extends Collection<? super String>> A into(A target) {
|
||||
return (A) Arrays.asList("db2collection1");
|
||||
}
|
||||
});
|
||||
when(db2mock.getCollectionNames()).thenReturn(Collections.singleton("db2collection1"));
|
||||
|
||||
// return collections according to names
|
||||
when(db1mock.getCollectionFromString(eq("db1collection1"))).thenReturn(db1collection1mock);
|
||||
when(db1mock.getCollectionFromString(eq("db1collection2"))).thenReturn(db1collection2mock);
|
||||
when(db2mock.getCollectionFromString(eq("db2collection1"))).thenReturn(db2collection1mock);
|
||||
when(db1mock.getCollection(eq("db1collection1"))).thenReturn(db1collection1mock);
|
||||
when(db1mock.getCollection(eq("db1collection2"))).thenReturn(db1collection2mock);
|
||||
when(db2mock.getCollection(eq("db2collection1"))).thenReturn(db2collection1mock);
|
||||
|
||||
cleaner = new CleanMongoDB(mongoClientMock);
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
<mongo:client-options />
|
||||
</mongo:mongo-client>
|
||||
|
||||
<mongo:db-factory id="second" write-concern="REPLICAS_SAFE" />
|
||||
<mongo:db-factory id="second" write-concern="W2" />
|
||||
|
||||
<!-- now part of the namespace
|
||||
<bean class="org.springframework.beans.factory.config.CustomEditorConfigurer">
|
||||
@@ -23,4 +23,4 @@
|
||||
</bean>
|
||||
-->
|
||||
|
||||
</beans>
|
||||
</beans>
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<mongo:mongo-client id="mongo-client-with-host-and-port" host="localhost" port="42" />
|
||||
|
||||
<mongo:mongo-client id="mongo-client-with-options-for-write-concern-and-read-preference">
|
||||
<mongo:client-options write-concern="NORMAL" read-preference="SECONDARY" />
|
||||
<mongo:client-options write-concern="UNACKNOWLEDGED" read-preference="SECONDARY" />
|
||||
</mongo:mongo-client>
|
||||
|
||||
<mongo:mongo-client id="mongo-client-with-credentials" credentials="jon:warg@snow?uri.authMechanism=PLAIN" />
|
||||
|
||||
Reference in New Issue
Block a user