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:
Thomas Risberg
2011-01-26 13:06:34 -05:00
parent 29e770a9f7
commit 325e356bb8
3 changed files with 228 additions and 11 deletions

View File

@@ -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

View File

@@ -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();
@@ -63,19 +70,69 @@ public class MongoTemplate implements InitializingBean, MongoOperations {
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);

View File

@@ -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());
}
}