Skip to content

Commit 775d40c

Browse files
committed
Remove dead code in ReplyHeader (#1231)
The dead code is a remnant of when the driver supported the full range of OP_REPLY wire protocol message usage. Since the driver now only runs against MongoDB releases that support OP_MSG, OP_REPLY is only used for the response to the `hello` command in the handshake, and therefore most of the OP_REPLY-handling code is no longer on any execution paths. JAVA-5204
1 parent 86452b8 commit 775d40c

File tree

9 files changed

+53
-233
lines changed

9 files changed

+53
-233
lines changed

driver-core/src/main/com/mongodb/internal/connection/InternalStreamConnection.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -546,7 +546,7 @@ private <T> void sendCommandMessageAsync(final int messageId, final Decoder<T> d
546546
}
547547

548548
private <T> T getCommandResult(final Decoder<T> decoder, final ResponseBuffers responseBuffers, final int messageId) {
549-
T result = new ReplyMessage<>(responseBuffers, decoder, messageId).getDocuments().get(0);
549+
T result = new ReplyMessage<>(responseBuffers, decoder, messageId).getDocument();
550550
MongoException writeConcernBasedError = createSpecialWriteConcernException(responseBuffers, description.getServerAddress());
551551
if (writeConcernBasedError != null) {
552552
throw new MongoWriteConcernWithResponseException(writeConcernBasedError, result);

driver-core/src/main/com/mongodb/internal/connection/ReplyHeader.java

+13-95
Original file line numberDiff line numberDiff line change
@@ -40,17 +40,10 @@ public final class ReplyHeader {
4040
*/
4141
public static final int TOTAL_REPLY_HEADER_LENGTH = REPLY_HEADER_LENGTH + MESSAGE_HEADER_LENGTH;
4242

43-
private static final int CURSOR_NOT_FOUND_RESPONSE_FLAG = 1;
44-
private static final int QUERY_FAILURE_RESPONSE_FLAG = 2;
45-
4643
private final int messageLength;
4744
private final int requestId;
4845
private final int responseTo;
49-
private final int responseFlags;
50-
private final long cursorId;
51-
private final int startingFrom;
52-
private final int numberReturned;
53-
private final int opMsgFlagBits;
46+
private final boolean hasMoreToCome;
5447

5548
ReplyHeader(final ByteBuf header, final MessageHeader messageHeader) {
5649
this(messageHeader.getMessageLength(), messageHeader.getOpCode(), messageHeader, header);
@@ -66,27 +59,23 @@ private ReplyHeader(final int messageLength, final int opCode, final MessageHead
6659
this.requestId = messageHeader.getRequestId();
6760
this.responseTo = messageHeader.getResponseTo();
6861
if (opCode == OP_MSG.getValue()) {
69-
responseFlags = 0;
70-
cursorId = 0;
71-
startingFrom = 0;
72-
numberReturned = 1;
73-
74-
opMsgFlagBits = header.getInt();
75-
header.get(); // ignore payload type
62+
int flagBits = header.getInt();
63+
hasMoreToCome = (flagBits & (1 << 1)) != 0;
64+
header.get(); // ignored payload type
7665
} else if (opCode == OP_REPLY.getValue()) {
7766
if (messageLength < TOTAL_REPLY_HEADER_LENGTH) {
78-
throw new MongoInternalException(format("The reply message length %d is less than the mimimum message length %d",
67+
throw new MongoInternalException(format("The reply message length %d is less than the minimum message length %d",
7968
messageLength, TOTAL_REPLY_HEADER_LENGTH));
8069
}
70+
hasMoreToCome = false;
8171

82-
responseFlags = header.getInt();
83-
cursorId = header.getLong();
84-
startingFrom = header.getInt();
85-
numberReturned = header.getInt();
86-
opMsgFlagBits = 0;
72+
header.getInt(); // ignored responseFlags
73+
header.getLong(); // ignored cursorId
74+
header.getInt(); // ignored startingFrom
75+
int numberReturned = header.getInt();
8776

88-
if (numberReturned < 0) {
89-
throw new MongoInternalException(format("The reply message number of returned documents, %d, is less than 0",
77+
if (numberReturned != 1) {
78+
throw new MongoInternalException(format("The reply message number of returned documents, %d, is expected to be 1",
9079
numberReturned));
9180
}
9281
} else {
@@ -123,78 +112,7 @@ public int getResponseTo() {
123112
return responseTo;
124113
}
125114

126-
/**
127-
* Gets additional information about the response.
128-
* <ul>
129-
* <li>0 - <i>CursorNotFound</i>: Set when getMore is called but the cursor id is not valid at the server. Returned with zero
130-
* results.</li>
131-
* <li>1 - <i>QueryFailure</i>: Set when query failed. Results consist of one document containing an "$err" field describing the
132-
* failure.
133-
* <li>2 - <i>ShardConfigStale</i>: Drivers should ignore this. Only mongos will ever see this set, in which case,
134-
* it needs to update config from the server.
135-
* <li>3 - <i>AwaitCapable</i>: Set when the server supports the AwaitData Query option. If it doesn't,
136-
* a client should sleep a little between getMore's of a Tailable cursor. Mongod version 1.6 supports AwaitData and thus always
137-
* sets AwaitCapable.
138-
* <li>4-31 - <i>Reserved</i>: Ignore
139-
* </ul>
140-
*
141-
* @return bit vector - see details above
142-
*/
143-
public int getResponseFlags() {
144-
return responseFlags;
145-
}
146-
147-
/**
148-
* Gets the cursor ID that this response is a part of. If there are no more documents to fetch from the server, the cursor ID will be 0.
149-
* This cursor ID must be used in any messages used to get more data, and also must be closed by the client when no longer needed.
150-
*
151-
* @return cursor ID to use if the client needs to fetch more from the server
152-
*/
153-
public long getCursorId() {
154-
return cursorId;
155-
}
156-
157-
/**
158-
* Returns the position in the cursor that is the start point of this reply.
159-
*
160-
* @return where in the cursor this reply is starting
161-
*/
162-
public int getStartingFrom() {
163-
return startingFrom;
164-
}
165-
166-
/**
167-
* Gets the number of documents to expect in the body of this reply.
168-
*
169-
* @return number of documents in the reply
170-
*/
171-
public int getNumberReturned() {
172-
return numberReturned;
173-
}
174-
175-
/**
176-
* Gets whether this query was performed with a cursor ID that was not valid on the server.
177-
*
178-
* @return true if this reply indicates the request to get more data was performed with a cursor ID that's not valid on the server
179-
*/
180-
public boolean isCursorNotFound() {
181-
return (responseFlags & CURSOR_NOT_FOUND_RESPONSE_FLAG) == CURSOR_NOT_FOUND_RESPONSE_FLAG;
182-
}
183-
184-
/**
185-
* Gets whether the query failed or not.
186-
*
187-
* @return true if this reply indicates the query failed.
188-
*/
189-
public boolean isQueryFailure() {
190-
return (responseFlags & QUERY_FAILURE_RESPONSE_FLAG) == QUERY_FAILURE_RESPONSE_FLAG;
191-
}
192-
193-
public int getOpMsgFlagBits() {
194-
return opMsgFlagBits;
195-
}
196-
197115
public boolean hasMoreToCome() {
198-
return (opMsgFlagBits & (1 << 1)) != 0;
116+
return hasMoreToCome;
199117
}
200118
}

driver-core/src/main/com/mongodb/internal/connection/ReplyMessage.java

+12-41
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,6 @@
2323
import org.bson.io.BsonInput;
2424
import org.bson.io.ByteBufferBsonInput;
2525

26-
import java.util.ArrayList;
27-
import java.util.List;
28-
2926
import static java.lang.String.format;
3027

3128
/**
@@ -35,50 +32,24 @@
3532
*/
3633
public class ReplyMessage<T> {
3734

38-
private final ReplyHeader replyHeader;
39-
private final List<T> documents;
35+
private final T document;
4036

4137
public ReplyMessage(final ResponseBuffers responseBuffers, final Decoder<T> decoder, final long requestId) {
42-
this(responseBuffers.getReplyHeader(), requestId);
43-
44-
if (replyHeader.getNumberReturned() > 0) {
45-
try (BsonInput bsonInput = new ByteBufferBsonInput(responseBuffers.getBodyByteBuffer().duplicate())) {
46-
while (documents.size() < replyHeader.getNumberReturned()) {
47-
try (BsonBinaryReader reader = new BsonBinaryReader(bsonInput)) {
48-
documents.add(decoder.decode(reader, DecoderContext.builder().build()));
49-
}
50-
}
51-
} finally {
52-
responseBuffers.reset();
53-
}
54-
}
55-
}
56-
57-
ReplyMessage(final ReplyHeader replyHeader, final long requestId) {
58-
if (requestId != replyHeader.getResponseTo()) {
38+
if (requestId != responseBuffers.getReplyHeader().getResponseTo()) {
5939
throw new MongoInternalException(format("The responseTo (%d) in the response does not match the requestId (%d) in the "
60-
+ "request", replyHeader.getResponseTo(), requestId));
40+
+ "request", responseBuffers.getReplyHeader().getResponseTo(), requestId));
6141
}
62-
this.replyHeader = replyHeader;
63-
64-
documents = new ArrayList<>(replyHeader.getNumberReturned());
65-
}
6642

67-
/**
68-
* Gets the reply header.
69-
*
70-
* @return the reply header
71-
*/
72-
public ReplyHeader getReplyHeader() {
73-
return replyHeader;
43+
try (BsonInput bsonInput = new ByteBufferBsonInput(responseBuffers.getBodyByteBuffer().duplicate())) {
44+
try (BsonBinaryReader reader = new BsonBinaryReader(bsonInput)) {
45+
document = decoder.decode(reader, DecoderContext.builder().build());
46+
}
47+
} finally {
48+
responseBuffers.reset();
49+
}
7450
}
7551

76-
/**
77-
* Gets the documents.
78-
*
79-
* @return the documents
80-
*/
81-
public List<T> getDocuments() {
82-
return documents;
52+
public T getDocument() {
53+
return document;
8354
}
8455
}

driver-core/src/main/com/mongodb/internal/connection/ResponseBuffers.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ public ReplyHeader getReplyHeader() {
4949
<T extends BsonDocument> T getResponseDocument(final int messageId, final Decoder<T> decoder) {
5050
ReplyMessage<T> replyMessage = new ReplyMessage<>(this, decoder, messageId);
5151
reset();
52-
return replyMessage.getDocuments().get(0);
52+
return replyMessage.getDocument();
5353
}
5454

5555
/**

driver-core/src/test/functional/com/mongodb/internal/connection/ReplyHeaderSpecification.groovy

+5-17
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ class ReplyHeaderSpecification extends Specification {
3535
writeInt(responseFlags)
3636
writeLong(9000)
3737
writeInt(4)
38-
writeInt(30)
38+
writeInt(1)
3939
}
4040
def byteBuf = outputBuffer.byteBuffers.get(0)
4141

@@ -46,12 +46,6 @@ class ReplyHeaderSpecification extends Specification {
4646
replyHeader.messageLength == 186
4747
replyHeader.requestId == 45
4848
replyHeader.responseTo == 23
49-
replyHeader.responseFlags == responseFlags
50-
replyHeader.cursorId == 9000
51-
replyHeader.startingFrom == 4
52-
replyHeader.numberReturned == 30
53-
replyHeader.cursorNotFound == cursorNotFound
54-
replyHeader.queryFailure == queryFailure
5549

5650
where:
5751
responseFlags << [0, 1, 2, 3]
@@ -72,7 +66,7 @@ class ReplyHeaderSpecification extends Specification {
7266
writeInt(responseFlags)
7367
writeLong(9000)
7468
writeInt(4)
75-
writeInt(30)
69+
writeInt(1)
7670
}
7771
def byteBuf = outputBuffer.byteBuffers.get(0)
7872
def compressedHeader = new CompressedHeader(byteBuf, new MessageHeader(byteBuf, getDefaultMaxMessageSize()))
@@ -84,12 +78,6 @@ class ReplyHeaderSpecification extends Specification {
8478
replyHeader.messageLength == 274
8579
replyHeader.requestId == 45
8680
replyHeader.responseTo == 23
87-
replyHeader.responseFlags == responseFlags
88-
replyHeader.cursorId == 9000
89-
replyHeader.startingFrom == 4
90-
replyHeader.numberReturned == 30
91-
replyHeader.cursorNotFound == cursorNotFound
92-
replyHeader.queryFailure == queryFailure
9381

9482
where:
9583
responseFlags << [0, 1, 2, 3]
@@ -138,7 +126,7 @@ class ReplyHeaderSpecification extends Specification {
138126

139127
then:
140128
def ex = thrown(MongoInternalException)
141-
ex.getMessage() == 'The reply message length 35 is less than the mimimum message length 36'
129+
ex.getMessage() == 'The reply message length 35 is less than the minimum message length 36'
142130
}
143131

144132
def 'should throw MongoInternalException on message size > max message size'() {
@@ -182,7 +170,7 @@ class ReplyHeaderSpecification extends Specification {
182170

183171
then:
184172
def ex = thrown(MongoInternalException)
185-
ex.getMessage() == 'The reply message number of returned documents, -1, is less than 0'
173+
ex.getMessage() == 'The reply message number of returned documents, -1, is expected to be 1'
186174
}
187175

188176
def 'should throw MongoInternalException on num documents < 0 with compressed header'() {
@@ -208,6 +196,6 @@ class ReplyHeaderSpecification extends Specification {
208196

209197
then:
210198
def ex = thrown(MongoInternalException)
211-
ex.getMessage() == 'The reply message number of returned documents, -1, is less than 0'
199+
ex.getMessage() == 'The reply message number of returned documents, -1, is expected to be 1'
212200
}
213201
}

driver-core/src/test/unit/com/mongodb/internal/connection/CommandMessageSpecification.groovy

+4-16
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ import com.mongodb.internal.session.SessionContext
2828
import com.mongodb.internal.validator.NoOpFieldNameValidator
2929
import org.bson.BsonArray
3030
import org.bson.BsonBinary
31-
import org.bson.BsonBinaryReader
3231
import org.bson.BsonDocument
3332
import org.bson.BsonInt32
3433
import org.bson.BsonMaximumSizeExceededException
@@ -37,10 +36,7 @@ import org.bson.BsonTimestamp
3736
import org.bson.ByteBuf
3837
import org.bson.ByteBufNIO
3938
import org.bson.codecs.BsonDocumentCodec
40-
import org.bson.codecs.DecoderContext
4139
import org.bson.io.BasicOutputBuffer
42-
import org.bson.io.BsonInput
43-
import org.bson.io.ByteBufferBsonInput
4440
import spock.lang.Specification
4541

4642
import java.nio.ByteBuffer
@@ -63,7 +59,7 @@ class CommandMessageSpecification extends Specification {
6359
.serverType(serverType as ServerType)
6460
.sessionSupported(true)
6561
.build(),
66-
responseExpected, exhaustAllowed, null, null, clusterConnectionMode, null)
62+
responseExpected, null, null, clusterConnectionMode, null)
6763
def output = new BasicOutputBuffer()
6864

6965
when:
@@ -76,8 +72,7 @@ class CommandMessageSpecification extends Specification {
7672
messageHeader.opCode == OpCode.OP_MSG.value
7773
replyHeader.requestId < RequestMessage.currentGlobalId
7874
replyHeader.responseTo == 0
79-
((replyHeader.opMsgFlagBits & (1 << 16)) != 0) == exhaustAllowed
80-
((replyHeader.opMsgFlagBits & (1 << 1)) == 0) == responseExpected
75+
replyHeader.hasMoreToCome() != responseExpected
8176

8277
def expectedCommandDocument = command.clone()
8378
.append('$db', new BsonString(namespace.databaseName))
@@ -97,7 +92,7 @@ class CommandMessageSpecification extends Specification {
9792
getCommandDocument(byteBuf, replyHeader) == expectedCommandDocument
9893

9994
where:
100-
[readPreference, serverType, clusterConnectionMode, sessionContext, responseExpected, exhaustAllowed] << [
95+
[readPreference, serverType, clusterConnectionMode, sessionContext, responseExpected] << [
10196
[ReadPreference.primary(), ReadPreference.secondary()],
10297
[ServerType.REPLICA_SET_PRIMARY, ServerType.SHARD_ROUTER],
10398
[ClusterConnectionMode.SINGLE, ClusterConnectionMode.MULTIPLE],
@@ -126,7 +121,6 @@ class CommandMessageSpecification extends Specification {
126121
getReadConcern() >> ReadConcern.DEFAULT
127122
}
128123
],
129-
[true, false],
130124
[true, false]
131125
].combinations()
132126
}
@@ -372,12 +366,6 @@ class CommandMessageSpecification extends Specification {
372366
}
373367

374368
private static BsonDocument getCommandDocument(ByteBufNIO byteBuf, ReplyHeader replyHeader) {
375-
new ReplyMessage<BsonDocument>(new ResponseBuffers(replyHeader, byteBuf), new BsonDocumentCodec(), 0).documents.get(0)
376-
}
377-
378-
private static BsonDocument getCommandDocument(ByteBufNIO byteBuf) {
379-
BsonInput bsonInput = new ByteBufferBsonInput(byteBuf)
380-
BsonBinaryReader reader = new BsonBinaryReader(bsonInput)
381-
new BsonDocumentCodec().decode(reader, DecoderContext.builder().build())
369+
new ReplyMessage<BsonDocument>(new ResponseBuffers(replyHeader, byteBuf), new BsonDocumentCodec(), 0).document
382370
}
383371
}

0 commit comments

Comments
 (0)