Skip to content

Commit 651e53b

Browse files
committed
Reinstated obedient commands for DB
JAVA-1784
1 parent 3a4b24e commit 651e53b

File tree

2 files changed

+109
-3
lines changed

2 files changed

+109
-3
lines changed

driver/src/main/com/mongodb/DB.java

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2008-2014 MongoDB, Inc.
2+
* Copyright 2008-2015 MongoDB, Inc.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -35,6 +35,7 @@
3535

3636
import java.util.ArrayList;
3737
import java.util.Collections;
38+
import java.util.HashSet;
3839
import java.util.LinkedHashSet;
3940
import java.util.List;
4041
import java.util.Set;
@@ -355,7 +356,7 @@ public CommandResult command(final DBObject command, final DBEncoder encoder) {
355356
*/
356357
public CommandResult command(final DBObject command, final ReadPreference readPreference, final DBEncoder encoder) {
357358
try {
358-
return executeCommand(wrap(command, encoder), readPreference);
359+
return executeCommand(wrap(command, encoder), getCommandReadPreference(command, readPreference));
359360
} catch (MongoCommandException ex) {
360361
return new CommandResult(ex.getResponse(), ex.getServerAddress());
361362
}
@@ -617,4 +618,43 @@ private BsonDocument wrap(final DBObject document, final DBEncoder encoder) {
617618
return new BsonDocumentWrapper<DBObject>(document, new DBEncoderAdapter(encoder));
618619
}
619620
}
621+
622+
/**
623+
* Determines the read preference that should be used for the given command.
624+
*
625+
* @param command the {@link DBObject} representing the command
626+
* @param requestedPreference the preference requested by the client.
627+
* @return the read preference to use for the given command. It will never return {@code null}.
628+
* @see com.mongodb.ReadPreference
629+
*/
630+
ReadPreference getCommandReadPreference(final DBObject command, final ReadPreference requestedPreference) {
631+
String comString = command.keySet().iterator().next().toLowerCase();
632+
boolean primaryRequired = !OBEDIENT_COMMANDS.contains(comString);
633+
634+
if (primaryRequired) {
635+
return ReadPreference.primary();
636+
} else if (requestedPreference == null) {
637+
return ReadPreference.primary();
638+
} else {
639+
return requestedPreference;
640+
}
641+
}
642+
643+
private static final Set<String> OBEDIENT_COMMANDS = new HashSet<String>();
644+
645+
static {
646+
OBEDIENT_COMMANDS.add("aggregate");
647+
OBEDIENT_COMMANDS.add("collstats");
648+
OBEDIENT_COMMANDS.add("count");
649+
OBEDIENT_COMMANDS.add("dbstats");
650+
OBEDIENT_COMMANDS.add("distinct");
651+
OBEDIENT_COMMANDS.add("geonear");
652+
OBEDIENT_COMMANDS.add("geosearch");
653+
OBEDIENT_COMMANDS.add("geowalk");
654+
OBEDIENT_COMMANDS.add("group");
655+
OBEDIENT_COMMANDS.add("listcollections");
656+
OBEDIENT_COMMANDS.add("listindexes");
657+
OBEDIENT_COMMANDS.add("parallelcollectionscan");
658+
OBEDIENT_COMMANDS.add("text");
659+
}
620660
}

driver/src/test/unit/com/mongodb/DBSpecification.groovy

Lines changed: 67 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,24 @@
1+
/*
2+
* Copyright 2014-2015 MongoDB, Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
117
package com.mongodb
218

319
import com.mongodb.operation.CreateCollectionOperation
420
import org.bson.BsonDocument
21+
import org.bson.BsonDouble
522
import spock.lang.Specification
623

724
import static com.mongodb.CustomMatchers.isTheSameAs
@@ -35,4 +52,53 @@ class DBSpecification extends Specification {
3552
.autoIndex(true)
3653
.storageEngineOptions(new BsonDocument('wiredTiger', new BsonDocument())))
3754
}
38-
}
55+
56+
57+
def 'should use provided read preference for obedient commands'() {
58+
given:
59+
def mongo = Stub(Mongo)
60+
mongo.mongoClientOptions >> MongoClientOptions.builder().build()
61+
def executor = new TestOperationExecutor([new BsonDocument('ok', new BsonDouble(1.0))])
62+
def database = new DB(mongo, 'test', executor)
63+
database.setReadPreference(ReadPreference.secondary())
64+
65+
when:
66+
database.command(cmd)
67+
68+
then:
69+
executor.getReadPreference() == expectedReadPreference
70+
71+
where:
72+
expectedReadPreference | cmd
73+
ReadPreference.secondary() | new BasicDBObject('listCollections', 1)
74+
ReadPreference.secondary() | new BasicDBObject('collStats', 1)
75+
ReadPreference.secondary() | new BasicDBObject('dbStats', 1)
76+
ReadPreference.secondary() | new BasicDBObject('distinct', 1)
77+
ReadPreference.secondary() | new BasicDBObject('geoNear', 1)
78+
ReadPreference.secondary() | new BasicDBObject('geoSearch', 1)
79+
ReadPreference.secondary() | new BasicDBObject('group', 1)
80+
ReadPreference.secondary() | new BasicDBObject('listCollections', 1)
81+
ReadPreference.secondary() | new BasicDBObject('listIndexes', 1)
82+
ReadPreference.secondary() | new BasicDBObject('parallelCollectionScan', 1)
83+
ReadPreference.secondary() | new BasicDBObject('text', 1)
84+
}
85+
86+
def 'should use primary read preference for non obedient commands'() {
87+
given:
88+
def mongo = Stub(Mongo)
89+
mongo.mongoClientOptions >> MongoClientOptions.builder().build()
90+
def executor = new TestOperationExecutor([new BsonDocument('ok', new BsonDouble(1.0))])
91+
def database = new DB(mongo, 'test', executor)
92+
database.setReadPreference(ReadPreference.secondary())
93+
94+
when:
95+
database.command(cmd)
96+
97+
then:
98+
executor.getReadPreference() == expectedReadPreference
99+
100+
where:
101+
expectedReadPreference | cmd
102+
ReadPreference.primary() | new BasicDBObject('command', 1)
103+
}
104+
}

0 commit comments

Comments
 (0)