Skip to content

Commit c8d0906

Browse files
committed
JAVA-2737: Don't include slaveOk or $readPreference for write operations
1 parent baaea7a commit c8d0906

File tree

8 files changed

+26
-33
lines changed

8 files changed

+26
-33
lines changed

driver-core/src/main/com/mongodb/connection/AsyncConnection.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ <T> void commandAsync(String database, BsonDocument command, boolean slaveOk, Fi
108108
* @param database the database to execute the command in
109109
* @param command the command document
110110
* @param fieldNameValidator the field name validator for the command document
111-
* @param readPreference the read preference that was applied to get this connection
111+
* @param readPreference the read preference that was applied to get this connection, or null if this is a write operation
112112
* @param commandResultDecoder the decoder for the result
113113
* @param sessionContext the session context
114114
* @param callback the callback to be passed the write result
@@ -124,7 +124,7 @@ <T> void commandAsync(String database, BsonDocument command, FieldNameValidator
124124
* @param database the database to execute the command in
125125
* @param command the command document
126126
* @param commandFieldNameValidator the field name validator for the command document
127-
* @param readPreference the read preference that was applied to get this connection
127+
* @param readPreference the read preference that was applied to get this connection, or null if this is a write operation
128128
* @param commandResultDecoder the decoder for the result
129129
* @param sessionContext the session context
130130
* @param responseExpected true if a response from the server is expected

driver-core/src/main/com/mongodb/connection/CommandMessage.java

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -113,10 +113,6 @@ boolean isResponseExpected() {
113113
return !useOpMsg() || requireOpMsgResponse();
114114
}
115115

116-
ReadPreference getReadPreference() {
117-
return readPreference;
118-
}
119-
120116
@Override
121117
protected EncodingMetadata encodeMessageBodyWithMetadata(final BsonOutput bsonOutput, final SessionContext sessionContext) {
122118
int messageStartPosition = bsonOutput.getPosition() - MESSAGE_PROLOGUE_LENGTH;
@@ -208,7 +204,7 @@ private int getOpQuerySlaveOkFlagBit() {
208204
}
209205

210206
private boolean isSlaveOk() {
211-
return readPreference.isSlaveOk() || isDirectConnectionToNonShardRouter();
207+
return (readPreference != null && readPreference.isSlaveOk()) || isDirectConnectionToNonShardRouter();
212208
}
213209

214210
private boolean isDirectConnectionToNonShardRouter() {
@@ -221,8 +217,8 @@ private boolean useOpMsg() {
221217

222218
private BsonDocument getCommandToEncode() {
223219
BsonDocument commandToEncode = command;
224-
if (!useOpMsg() && !isDefaultReadPreference(getReadPreference())) {
225-
commandToEncode = new BsonDocument("$query", command).append("$readPreference", getReadPreference().toDocument());
220+
if (!useOpMsg() && readPreference != null && !readPreference.equals(primary())) {
221+
commandToEncode = new BsonDocument("$query", command).append("$readPreference", readPreference.toDocument());
226222
}
227223
return commandToEncode;
228224
}
@@ -236,19 +232,16 @@ private List<BsonElement> getExtraElements(final SessionContext sessionContext)
236232
if (sessionContext.hasSession() && responseExpected) {
237233
extraElements.add(new BsonElement("lsid", sessionContext.getSessionId()));
238234
}
239-
if (!isDefaultReadPreference(getReadPreference())) {
240-
extraElements.add(new BsonElement("$readPreference", getReadPreference().toDocument()));
241-
} else if (isDirectConnectionToNonShardRouter()) {
235+
if (readPreference != null) {
236+
if (!readPreference.equals(primary())) {
237+
extraElements.add(new BsonElement("$readPreference", readPreference.toDocument()));
238+
} else if (isDirectConnectionToNonShardRouter()) {
242239
extraElements.add(new BsonElement("$readPreference", primaryPreferred().toDocument()));
240+
}
243241
}
244242
return extraElements;
245243
}
246244

247-
@SuppressWarnings("BooleanMethodIsAlwaysInverted")
248-
private boolean isDefaultReadPreference(final ReadPreference readPreference) {
249-
return readPreference.equals(primary());
250-
}
251-
252245
private static OpCode getOpCode(final MessageSettings settings) {
253246
return isServerVersionAtLeastThreeDotSix(settings) ? OpCode.OP_MSG : OpCode.OP_QUERY;
254247
}

driver-core/src/main/com/mongodb/connection/CommandProtocolImpl.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ class CommandProtocolImpl<T> implements CommandProtocol<T> {
5858
this.namespace = new MongoNamespace(notNull("database", database), MongoNamespace.COMMAND_COLLECTION_NAME);
5959
this.command = notNull("command", command);
6060
this.commandFieldNameValidator = notNull("commandFieldNameValidator", commandFieldNameValidator);
61-
this.readPreference = notNull("readPreference", readPreference);
61+
this.readPreference = readPreference;
6262
this.commandResultDecoder = notNull("commandResultDecoder", commandResultDecoder);
6363
this.responseExpected = responseExpected;
6464
this.payload = payload;

driver-core/src/main/com/mongodb/connection/Connection.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ <T> T command(String database, BsonDocument command, boolean slaveOk, FieldNameV
107107
* @param database the database to execute the command in
108108
* @param command the command document
109109
* @param fieldNameValidator the field name validator for the command document
110-
* @param readPreference the read preference that was applied to get this connection
110+
* @param readPreference the read preference that was applied to get this connection, or null if this is a write operation
111111
* @param commandResultDecoder the decoder for the result
112112
* @param sessionContext the session context
113113
* @return the command result
@@ -123,7 +123,7 @@ <T> T command(String database, BsonDocument command, FieldNameValidator fieldNam
123123
* @param database the database to execute the command in
124124
* @param command the command document
125125
* @param commandFieldNameValidator the field name validator for the command document
126-
* @param readPreference the read preference that was applied to get this connection
126+
* @param readPreference the read preference that was applied to get this connection, or null if this is a write operation
127127
* @param commandResultDecoder the decoder for the result
128128
* @param sessionContext the session context
129129
* @param responseExpected true if a response from the server is expected

driver-core/src/main/com/mongodb/operation/BaseFindAndModifyOperation.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,15 +30,15 @@ abstract class BaseFindAndModifyOperation<T> implements AsyncWriteOperation<T>,
3030

3131
@Override
3232
public T execute(final WriteBinding binding) {
33-
return executeRetryableCommand(binding, getDatabaseName(), getFieldNameValidator(),
33+
return executeRetryableCommand(binding, getDatabaseName(), null, getFieldNameValidator(),
3434
CommandResultDocumentCodec.create(getDecoder(), "value"),
3535
getCommandCreator(binding.getSessionContext()),
3636
FindAndModifyHelper.<T>transformer());
3737
}
3838

3939
@Override
4040
public void executeAsync(final AsyncWriteBinding binding, final SingleResultCallback<T> callback) {
41-
executeRetryableCommand(binding, getDatabaseName(), getFieldNameValidator(),
41+
executeRetryableCommand(binding, getDatabaseName(), null, getFieldNameValidator(),
4242
CommandResultDocumentCodec.create(getDecoder(), "value"),
4343
getCommandCreator(binding.getSessionContext()),
4444
FindAndModifyHelper.<T>transformer(), callback);

driver-core/src/main/com/mongodb/operation/CommandOperationHelper.java

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -422,7 +422,7 @@ public void onResult(final D result, final Throwable t) {
422422
}
423423

424424
/* Retryable write helpers */
425-
static <T, R> R executeRetryableCommand(final WriteBinding binding, final String database,
425+
static <T, R> R executeRetryableCommand(final WriteBinding binding, final String database, final ReadPreference readPreference,
426426
final FieldNameValidator fieldNameValidator, final Decoder<T> commandResultDecoder,
427427
final CommandCreator commandCreator,
428428
final CommandTransformer<T, R> transformer) {
@@ -433,7 +433,7 @@ public R call(final ConnectionSource source, final Connection connection) {
433433
MongoException exception = null;
434434
try {
435435
command = commandCreator.create(source.getServerDescription(), connection.getDescription());
436-
return transformer.apply(connection.command(database, command, fieldNameValidator, ReadPreference.primary(),
436+
return transformer.apply(connection.command(database, command, fieldNameValidator, readPreference,
437437
commandResultDecoder, binding.getSessionContext()), connection.getDescription().getServerAddress());
438438
} catch (MongoException e) {
439439
exception = e;
@@ -454,7 +454,7 @@ public R call(final ConnectionSource source, final Connection connection) {
454454
throw originalException;
455455
}
456456
return transformer.apply(connection.command(database, originalCommand, fieldNameValidator,
457-
ReadPreference.primary(), commandResultDecoder, binding.getSessionContext()),
457+
readPreference, commandResultDecoder, binding.getSessionContext()),
458458
connection.getDescription().getServerAddress());
459459
} finally {
460460
connection.release();
@@ -465,7 +465,7 @@ public R call(final ConnectionSource source, final Connection connection) {
465465
});
466466
}
467467

468-
static <T, R> void executeRetryableCommand(final AsyncWriteBinding binding, final String database,
468+
static <T, R> void executeRetryableCommand(final AsyncWriteBinding binding, final String database, final ReadPreference readPreference,
469469
final FieldNameValidator fieldNameValidator, final Decoder<T> commandResultDecoder,
470470
final CommandCreator commandCreator, final CommandTransformer<T, R> transformer,
471471
final SingleResultCallback<R> originalCallback) {
@@ -485,9 +485,9 @@ public void onResult(final AsyncConnection connection, final Throwable t) {
485485
try {
486486
BsonDocument command = commandCreator.create(source.getServerDescription(),
487487
connection.getDescription());
488-
connection.commandAsync(database, command, fieldNameValidator, ReadPreference.primary(),
488+
connection.commandAsync(database, command, fieldNameValidator, readPreference,
489489
commandResultDecoder, binding.getSessionContext(),
490-
createCommandCallback(binding, source, connection, database, command,
490+
createCommandCallback(binding, source, connection, database, readPreference, command,
491491
fieldNameValidator, commandResultDecoder, transformer, errorHandlingCallback));
492492
} catch (Throwable t1) {
493493
releasingCallback(errorHandlingCallback, source, connection).onResult(null, t1);
@@ -504,6 +504,7 @@ private static <T, R> SingleResultCallback<T> createCommandCallback(final AsyncW
504504
final AsyncConnectionSource oldSource,
505505
final AsyncConnection oldConnection,
506506
final String database,
507+
final ReadPreference readPreference,
507508
final BsonDocument command,
508509
final FieldNameValidator fieldNameValidator,
509510
final Decoder<T> commandResultDecoder,
@@ -526,7 +527,7 @@ public void call(final AsyncConnectionSource source, final AsyncConnection conne
526527
} else if (!canRetryWrite(source.getServerDescription(), connection.getDescription())) {
527528
releasingCallback(callback, source, connection).onResult(null, originalError);
528529
} else {
529-
connection.commandAsync(database, command, fieldNameValidator, ReadPreference.primary(),
530+
connection.commandAsync(database, command, fieldNameValidator, readPreference,
530531
commandResultDecoder, binding.getSessionContext(),
531532
new TransformingResultCallback<T, R>(transformer,
532533
connection.getDescription().getServerAddress(),

driver-core/src/main/com/mongodb/operation/MixedBulkWriteOperation.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
import com.mongodb.MongoBulkWriteException;
2020
import com.mongodb.MongoException;
2121
import com.mongodb.MongoNamespace;
22-
import com.mongodb.ReadPreference;
2322
import com.mongodb.WriteConcern;
2423
import com.mongodb.WriteConcernResult;
2524
import com.mongodb.async.SingleResultCallback;
@@ -371,7 +370,7 @@ public void onResult(final WriteConcernResult result, final Throwable t) {
371370

372371
private BsonDocument executeCommand(final Connection connection, final BulkWriteBatch batch, final WriteBinding binding) {
373372
return connection.command(namespace.getDatabaseName(), batch.getCommand(), NO_OP_FIELD_NAME_VALIDATOR,
374-
ReadPreference.primary(), batch.getDecoder(), binding.getSessionContext(), shouldAcknowledge(batch, writeConcern),
373+
null, batch.getDecoder(), binding.getSessionContext(), shouldAcknowledge(batch, writeConcern),
375374
batch.getPayload(), batch.getFieldNameValidator());
376375
}
377376

@@ -380,7 +379,7 @@ private void executeCommandAsync(final AsyncWriteBinding binding, final AsyncCon
380379
final SingleResultCallback<BsonDocument> commandCallback) {
381380
try {
382381
connection.commandAsync(namespace.getDatabaseName(), batch.getCommand(), NO_OP_FIELD_NAME_VALIDATOR,
383-
ReadPreference.primary(), batch.getDecoder(), binding.getSessionContext(), shouldAcknowledge(batch, writeConcern),
382+
null, batch.getDecoder(), binding.getSessionContext(), shouldAcknowledge(batch, writeConcern),
384383
batch.getPayload(), batch.getFieldNameValidator(), commandCallback);
385384
} catch (Throwable t) {
386385
callback.onResult(null, t);

driver/src/test/functional/com/mongodb/client/CommandMonitoringTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -314,7 +314,7 @@ private List<CommandEvent> getExpectedEvents(final BsonArray expectedEventDocume
314314
BsonDocument operation = definition.getDocument("operation");
315315
if (operation.containsKey("read_preference")) {
316316
commandDocument.put("$readPreference", operation.getDocument("read_preference"));
317-
} else if (!isDiscoverableReplicaSet() && !isSharded()) {
317+
} else if (!isDiscoverableReplicaSet() && !isSharded() && !isWriteCommand(commandName)) {
318318
commandDocument.put("$readPreference", ReadPreference.primaryPreferred().toDocument());
319319
}
320320
}

0 commit comments

Comments
 (0)