From c4ffc37dd50a172ab444332ecc36340a86ca5c23 Mon Sep 17 00:00:00 2001 From: Christoph Strobl Date: Thu, 18 Jun 2015 15:26:33 +0200 Subject: [PATCH] DATAMONGO-1166 - ReadPreference is now be used for aggregations. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We now use MongoTemplate.readPreference(…) when executing commands such as geoNear(…) and aggregate(…). Original pull request: #303. --- .../data/mongodb/core/MongoTemplate.java | 6 +- .../mongodb/core/MongoTemplateUnitTests.java | 69 +++++++++++++++++++ 2 files changed, 72 insertions(+), 3 deletions(-) diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoTemplate.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoTemplate.java index c98afa631..ec50e0e85 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoTemplate.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoTemplate.java @@ -385,7 +385,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware { CommandResult result = execute(new DbCallback() { public CommandResult doInDB(DB db) throws MongoException, DataAccessException { - return db.command(command, readPreference); + return readPreference != null ? db.command(command, readPreference) : db.command(command); } }); @@ -632,7 +632,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware { BasicDBObject command = new BasicDBObject("geoNear", collection); command.putAll(near.toDBObject()); - CommandResult commandResult = executeCommand(command); + CommandResult commandResult = executeCommand(command, this.readPreference); List results = (List) commandResult.get("results"); results = results == null ? Collections.emptyList() : results; @@ -1503,7 +1503,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware { LOGGER.debug("Executing aggregation: {}", serializeToJsonSafely(command)); } - CommandResult commandResult = executeCommand(command); + CommandResult commandResult = executeCommand(command, this.readPreference); handleCommandError(commandResult, command); return new AggregationResults(returnPotentiallyMappedResults(outputType, commandResult), commandResult); diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateUnitTests.java index 08b6b0c87..918e6cc57 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateUnitTests.java @@ -43,7 +43,9 @@ import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.data.annotation.Id; import org.springframework.data.annotation.Version; import org.springframework.data.domain.Sort; +import org.springframework.data.geo.Point; import org.springframework.data.mongodb.MongoDbFactory; +import org.springframework.data.mongodb.core.aggregation.Aggregation; import org.springframework.data.mongodb.core.convert.CustomConversions; import org.springframework.data.mongodb.core.convert.DefaultDbRefResolver; import org.springframework.data.mongodb.core.convert.MappingMongoConverter; @@ -52,18 +54,21 @@ import org.springframework.data.mongodb.core.index.MongoPersistentEntityIndexCre import org.springframework.data.mongodb.core.mapping.MongoMappingContext; import org.springframework.data.mongodb.core.query.BasicQuery; 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.test.util.ReflectionTestUtils; import com.mongodb.BasicDBObject; import com.mongodb.BasicDBObjectBuilder; +import com.mongodb.CommandResult; import com.mongodb.DB; import com.mongodb.DBCollection; import com.mongodb.DBCursor; import com.mongodb.DBObject; import com.mongodb.Mongo; import com.mongodb.MongoException; +import com.mongodb.ReadPreference; /** * Unit tests for {@link MongoTemplate}. @@ -353,6 +358,70 @@ public class MongoTemplateUnitTests extends MongoOperationsUnitTests { assertThat(captor.getValue(), equalTo(new BasicDBObjectBuilder().add("foo", 1).get())); } + /** + * @see DATAMONGO-1166 + */ + @Test + public void aggregateShouldHonorReadPreferenceWhenSet() { + + when(db.command(Mockito.any(DBObject.class), Mockito.any(ReadPreference.class))).thenReturn( + mock(CommandResult.class)); + when(db.command(Mockito.any(DBObject.class))).thenReturn(mock(CommandResult.class)); + template.setReadPreference(ReadPreference.secondary()); + + template.aggregate(Aggregation.newAggregation(Aggregation.unwind("foo")), "collection-1", Wrapper.class); + + verify(this.db, times(1)).command(Mockito.any(DBObject.class), eq(ReadPreference.secondary())); + } + + /** + * @see DATAMONGO-1166 + */ + @Test + public void aggregateShouldIgnoreReadPreferenceWhenNotSet() { + + when(db.command(Mockito.any(DBObject.class), Mockito.any(ReadPreference.class))).thenReturn( + mock(CommandResult.class)); + when(db.command(Mockito.any(DBObject.class))).thenReturn(mock(CommandResult.class)); + + template.aggregate(Aggregation.newAggregation(Aggregation.unwind("foo")), "collection-1", Wrapper.class); + + verify(this.db, times(1)).command(Mockito.any(DBObject.class)); + } + + /** + * @see DATAMONGO-1166 + */ + @Test + public void geoNearShouldHonorReadPreferenceWhenSet() { + + when(db.command(Mockito.any(DBObject.class), Mockito.any(ReadPreference.class))).thenReturn( + mock(CommandResult.class)); + when(db.command(Mockito.any(DBObject.class))).thenReturn(mock(CommandResult.class)); + template.setReadPreference(ReadPreference.secondary()); + + NearQuery query = NearQuery.near(new Point(1, 1)); + template.geoNear(query, Wrapper.class); + + verify(this.db, times(1)).command(Mockito.any(DBObject.class), eq(ReadPreference.secondary())); + } + + /** + * @see DATAMONGO-1166 + */ + @Test + public void geoNearShouldIgnoreReadPreferenceWhenNotSet() { + + when(db.command(Mockito.any(DBObject.class), Mockito.any(ReadPreference.class))).thenReturn( + mock(CommandResult.class)); + when(db.command(Mockito.any(DBObject.class))).thenReturn(mock(CommandResult.class)); + + NearQuery query = NearQuery.near(new Point(1, 1)); + template.geoNear(query, Wrapper.class); + + verify(this.db, times(1)).command(Mockito.any(DBObject.class)); + } + class AutogenerateableId { @Id BigInteger id;