DATADOC-14 added WriteConcern for MongoTemplate to be used for write operations when specified and also methods to set WriteConcern for DB and Collections
This commit is contained in:
@@ -20,6 +20,7 @@ import java.util.Set;
|
||||
|
||||
import com.mongodb.DBCollection;
|
||||
import com.mongodb.DBObject;
|
||||
import com.mongodb.WriteConcern;
|
||||
|
||||
/**
|
||||
* Interface that specifies a basic set of MongoDB operations. Implemented by {@link MongoTemplate}.
|
||||
@@ -44,6 +45,31 @@ public interface MongoOperations {
|
||||
*/
|
||||
DBCollection getDefaultCollection();
|
||||
|
||||
/**
|
||||
* Set the {@link com.mongodb.WriteConcern} to be used for the Database.
|
||||
* @param writeConcern
|
||||
*/
|
||||
void setDatabaseWriteConcern(WriteConcern writeConcern);
|
||||
|
||||
/**
|
||||
* Get the {@link com.mongodb.WriteConcern} currently used by the Database.
|
||||
* @return the WriteConcern
|
||||
*/
|
||||
WriteConcern getDatabaseWriteConcern();
|
||||
|
||||
/**
|
||||
* Set the {@link com.mongodb.WriteConcern} to be used for the Collection.
|
||||
* @param collectionName
|
||||
* @param writeConcern
|
||||
*/
|
||||
void setCollectionWriteConcern(String collectionName, WriteConcern writeConcern);
|
||||
|
||||
/**
|
||||
* Get the {@link com.mongodb.WriteConcern} currently used by the Collection.
|
||||
* @param collectionName
|
||||
* @return the WriteConcern
|
||||
*/
|
||||
WriteConcern getCollectionWriteConcern(String collectionName);
|
||||
|
||||
/**
|
||||
* Execute the a MongoDB command expressed as a JSON string. This will call the method
|
||||
|
||||
@@ -39,6 +39,7 @@ import com.mongodb.DBCursor;
|
||||
import com.mongodb.DBObject;
|
||||
import com.mongodb.Mongo;
|
||||
import com.mongodb.MongoException;
|
||||
import com.mongodb.WriteConcern;
|
||||
import com.mongodb.util.JSON;
|
||||
|
||||
/**
|
||||
@@ -53,6 +54,12 @@ public class MongoTemplate implements InitializingBean, MongoOperations {
|
||||
|
||||
private static final String ID = "_id";
|
||||
|
||||
/*
|
||||
* WriteConcern to be used for write operations if it has been specified. Otherwise
|
||||
* we should not use a WriteConcern defaulting to the one set for the DB or Collection.
|
||||
*/
|
||||
private WriteConcern writeConcern = null;
|
||||
|
||||
private final MongoConverter mongoConverter;
|
||||
private final Mongo mongo;
|
||||
private final MongoExceptionTranslator exceptionTranslator = new MongoExceptionTranslator();
|
||||
@@ -62,20 +69,70 @@ public class MongoTemplate implements InitializingBean, MongoOperations {
|
||||
private String username;
|
||||
private String password;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Constructor used for a basic template configuration
|
||||
* @param mongo
|
||||
* @param databaseName
|
||||
*/
|
||||
public MongoTemplate(Mongo mongo, String databaseName) {
|
||||
this(mongo, databaseName, null, null);
|
||||
this(mongo, databaseName, null, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor used for a basic template configuration with a specific {@link com.mongodb.WriteConcern}
|
||||
* to be used for all database write operations
|
||||
* @param mongo
|
||||
* @param databaseName
|
||||
* @param writeConcern
|
||||
*/
|
||||
public MongoTemplate(Mongo mongo, String databaseName, WriteConcern writeConcern) {
|
||||
this(mongo, databaseName, null, null, writeConcern);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor used for a basic template configuration with a default collection name
|
||||
* @param mongo
|
||||
* @param databaseName
|
||||
* @param defaultCollectionName
|
||||
*/
|
||||
public MongoTemplate(Mongo mongo, String databaseName, String defaultCollectionName) {
|
||||
this(mongo, databaseName, defaultCollectionName, null);
|
||||
this(mongo, databaseName, defaultCollectionName, null, null);
|
||||
}
|
||||
|
||||
public MongoTemplate(Mongo mongo, String databaseName, MongoConverter mongoConverter) {
|
||||
this(mongo, databaseName, null, mongoConverter);
|
||||
/**
|
||||
* Constructor used for a basic template configuration with a default collection name and
|
||||
* with a specific {@link com.mongodb.WriteConcern} to be used for all database write operations
|
||||
* @param mongo
|
||||
* @param databaseName
|
||||
* @param defaultCollectionName
|
||||
* @param writeConcern
|
||||
*/
|
||||
public MongoTemplate(Mongo mongo, String databaseName, String defaultCollectionName, WriteConcern writeConcern) {
|
||||
this(mongo, databaseName, defaultCollectionName, null, writeConcern);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor used for a template configuration with a default collection name and a custom {@link MongoConverter}
|
||||
* @param mongo
|
||||
* @param databaseName
|
||||
* @param defaultCollectionName
|
||||
* @param mongoConverter
|
||||
*/
|
||||
public MongoTemplate(Mongo mongo, String databaseName, String defaultCollectionName, MongoConverter mongoConverter) {
|
||||
this(mongo, databaseName, defaultCollectionName, mongoConverter, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor used for a template configuration with a default collection name and a custom {@link MongoConverter}
|
||||
* and with a specific {@link com.mongodb.WriteConcern} to be used for all database write operations
|
||||
* @param mongo
|
||||
* @param databaseName
|
||||
* @param defaultCollectionName
|
||||
* @param mongoConverter
|
||||
* @param writeConcern
|
||||
*/
|
||||
public MongoTemplate(Mongo mongo, String databaseName, String defaultCollectionName, MongoConverter mongoConverter, WriteConcern writeConcern) {
|
||||
|
||||
Assert.notNull(mongo);
|
||||
Assert.notNull(databaseName);
|
||||
@@ -84,6 +141,7 @@ public class MongoTemplate implements InitializingBean, MongoOperations {
|
||||
this.defaultCollectionName = defaultCollectionName;
|
||||
this.mongo = mongo;
|
||||
this.databaseName = databaseName;
|
||||
this.writeConcern = writeConcern;
|
||||
}
|
||||
|
||||
|
||||
@@ -153,6 +211,23 @@ public class MongoTemplate implements InitializingBean, MongoOperations {
|
||||
});
|
||||
}
|
||||
|
||||
// TODO:
|
||||
public void setDatabaseWriteConcern(WriteConcern writeConcern) {
|
||||
getDb().setWriteConcern(writeConcern);
|
||||
}
|
||||
|
||||
public WriteConcern getDatabaseWriteConcern() {
|
||||
return getDb().getWriteConcern();
|
||||
}
|
||||
|
||||
public void setCollectionWriteConcern(String collectionName, WriteConcern writeConcern) {
|
||||
getCollection(collectionName).setWriteConcern(writeConcern);
|
||||
}
|
||||
|
||||
public WriteConcern getCollectionWriteConcern(String collectionName) {
|
||||
return getCollection(collectionName).getWriteConcern();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.document.mongodb.MongoOperations#executeCommand(java.lang.String)
|
||||
*/
|
||||
@@ -430,7 +505,12 @@ public class MongoTemplate implements InitializingBean, MongoOperations {
|
||||
|
||||
return execute(new CollectionCallback<ObjectId>() {
|
||||
public ObjectId doInCollection(DBCollection collection) throws MongoException, DataAccessException {
|
||||
collection.insert(dbDoc);
|
||||
if (writeConcern == null) {
|
||||
collection.insert(dbDoc);
|
||||
}
|
||||
else {
|
||||
collection.insert(dbDoc, writeConcern);
|
||||
}
|
||||
return (ObjectId) dbDoc.get(ID);
|
||||
}
|
||||
}, collectionName);
|
||||
@@ -447,7 +527,12 @@ public class MongoTemplate implements InitializingBean, MongoOperations {
|
||||
|
||||
execute(new CollectionCallback<Void>() {
|
||||
public Void doInCollection(DBCollection collection) throws MongoException, DataAccessException {
|
||||
collection.insert(dbDocList);
|
||||
if (writeConcern == null) {
|
||||
collection.insert(dbDocList);
|
||||
}
|
||||
else {
|
||||
collection.insert(dbDocList.toArray((DBObject[]) new BasicDBObject[dbDocList.size()]), writeConcern);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}, collectionName);
|
||||
@@ -474,7 +559,12 @@ public class MongoTemplate implements InitializingBean, MongoOperations {
|
||||
|
||||
return execute(new CollectionCallback<ObjectId>() {
|
||||
public ObjectId doInCollection(DBCollection collection) throws MongoException, DataAccessException {
|
||||
collection.save(dbDoc);
|
||||
if (writeConcern == null) {
|
||||
collection.save(dbDoc);
|
||||
}
|
||||
else {
|
||||
collection.save(dbDoc, writeConcern);
|
||||
}
|
||||
return (ObjectId) dbDoc.get(ID);
|
||||
}
|
||||
}, collectionName);
|
||||
@@ -493,7 +583,12 @@ public class MongoTemplate implements InitializingBean, MongoOperations {
|
||||
public void updateFirst(String collectionName, final DBObject queryDoc, final DBObject updateDoc) {
|
||||
execute(new CollectionCallback<Void>() {
|
||||
public Void doInCollection(DBCollection collection) throws MongoException, DataAccessException {
|
||||
collection.update(queryDoc, updateDoc);
|
||||
if (writeConcern == null) {
|
||||
collection.update(queryDoc, updateDoc);
|
||||
}
|
||||
else {
|
||||
collection.update(queryDoc, updateDoc, false, false, writeConcern);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}, collectionName);
|
||||
@@ -512,7 +607,12 @@ public class MongoTemplate implements InitializingBean, MongoOperations {
|
||||
public void updateMulti(String collectionName, final DBObject queryDoc, final DBObject updateDoc) {
|
||||
execute(new CollectionCallback<Void>() {
|
||||
public Void doInCollection(DBCollection collection) throws MongoException, DataAccessException {
|
||||
collection.updateMulti(queryDoc, updateDoc);
|
||||
if (writeConcern == null) {
|
||||
collection.updateMulti(queryDoc, updateDoc);
|
||||
}
|
||||
else {
|
||||
collection.update(queryDoc, updateDoc, false, true, writeConcern);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}, collectionName);
|
||||
@@ -531,7 +631,12 @@ public class MongoTemplate implements InitializingBean, MongoOperations {
|
||||
public void remove(String collectionName, final DBObject queryDoc) {
|
||||
execute(new CollectionCallback<Void>() {
|
||||
public Void doInCollection(DBCollection collection) throws MongoException, DataAccessException {
|
||||
collection.remove(queryDoc);
|
||||
if (writeConcern == null) {
|
||||
collection.remove(queryDoc);
|
||||
}
|
||||
else {
|
||||
collection.remove(queryDoc, writeConcern);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}, collectionName);
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright 2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.document.mongodb;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNotSame;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
import com.mongodb.WriteConcern;
|
||||
|
||||
/**
|
||||
* Integration test of the WriteConcern features for {@link MongoTemplate}.
|
||||
*
|
||||
* @author Thomas Risberg
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration("classpath:infrastructure.xml")
|
||||
public class MongoTemplateWriteConcernTests {
|
||||
|
||||
@Autowired
|
||||
MongoTemplate template;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
template.dropCollection(template.getDefaultCollectionName());
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
template.setCollectionWriteConcern(template.getDefaultCollectionName(), WriteConcern.NORMAL);
|
||||
template.setDatabaseWriteConcern(WriteConcern.NORMAL);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRetrievingTheDatabaseWriteConcern() throws Exception {
|
||||
WriteConcern wc = template.getDatabaseWriteConcern();
|
||||
assertNotNull(wc);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRetrievingTheCollectionWriteConcern() throws Exception {
|
||||
WriteConcern wc = template.getCollectionWriteConcern(template.getDefaultCollectionName());
|
||||
assertNotNull(wc);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSettingTheDatabaseWriteConcern() throws Exception {
|
||||
WriteConcern wc = template.getDatabaseWriteConcern();
|
||||
WriteConcern safe = WriteConcern.SAFE;
|
||||
template.setDatabaseWriteConcern(safe);
|
||||
assertEquals(safe.getW(), template.getDatabaseWriteConcern().getW());
|
||||
assertNotSame(wc.getW(), template.getDatabaseWriteConcern().getW());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSettingTheCollectionWriteConcern() throws Exception {
|
||||
String coll = template.getDefaultCollectionName();
|
||||
WriteConcern replicasSafe = WriteConcern.REPLICAS_SAFE;
|
||||
WriteConcern fsyncSafe = WriteConcern.FSYNC_SAFE;
|
||||
template.setDatabaseWriteConcern(fsyncSafe);
|
||||
template.setCollectionWriteConcern(coll, replicasSafe);
|
||||
assertEquals(replicasSafe.getW(), template.getCollectionWriteConcern(coll).getW());
|
||||
assertEquals(replicasSafe.fsync(), template.getCollectionWriteConcern(coll).fsync());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user