Skip to content

Commit 001192c

Browse files
committed
JAVA-2160: Use default DBDecoder to decode the error document when the query failure bit is set
1 parent 807d02f commit 001192c

File tree

4 files changed

+114
-2
lines changed

4 files changed

+114
-2
lines changed

src/main/com/mongodb/Response.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,12 +77,14 @@ class Response {
7777
else
7878
_objects = new ArrayList<DBObject>( _num );
7979

80+
// always use the default decoder to decode the error document
81+
DBDecoder actualDecoder = (_flags & Bytes.RESULTFLAG_ERRSET) > 0 ? DefaultDBDecoder.FACTORY.create() : decoder;
8082
for ( int i=0; i < _num; i++ ){
8183
if ( user._toGo < 5 )
8284
throw new IOException( "should have more objects, but only " + user._toGo + " bytes left" );
8385
// TODO: By moving to generics, you can remove these casts (and requirement to impl DBOBject).
8486

85-
_objects.add( decoder.decode( user, collection ) );
87+
_objects.add( actualDecoder.decode( user, collection ) );
8688
}
8789

8890
if ( user._toGo != 0 )

src/test/com/mongodb/AggregationTest.java

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ public void testExplain() {
7979
.build());
8080
assertTrue(out.keySet().iterator().hasNext());
8181
}
82-
82+
8383
@Test(expected = IllegalArgumentException.class)
8484
public void testNullOptions() {
8585
collection.aggregate(new ArrayList<DBObject>(), (AggregationOptions) null);
@@ -242,6 +242,23 @@ public void testMaxTime() {
242242
}
243243
}
244244

245+
@Test
246+
public void testMaxTimeWithCustomDecoderThatSwallowsAllFields() {
247+
assumeFalse(isSharded(getMongoClient()));
248+
checkServerVersion(2.6);
249+
enableMaxTimeFailPoint();
250+
DBCollection collection = database.getCollection("testMaxTime");
251+
collection.setDBDecoderFactory(new SubsitutingDBDecoderFactory(new BasicDBObject()));
252+
try {
253+
collection.aggregate(prepareData(), AggregationOptions.builder().maxTime(1, SECONDS).build());
254+
fail("Show have thrown");
255+
} catch (MongoExecutionTimeoutException e) {
256+
assertEquals(50, e.getCode());
257+
} finally {
258+
disableMaxTimeFailPoint();
259+
}
260+
}
261+
245262
@Test
246263
public void testInvalidPipelineThrowsError() {
247264
checkServerVersion(2.6);

src/test/com/mongodb/DBCursorTest.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -798,6 +798,24 @@ public void testMaxTimeForSize() {
798798
}
799799
}
800800

801+
@Test
802+
public void testMaxTimeWithCustomDecoderThatSwallowsAllFields() {
803+
assumeFalse(isSharded(getMongoClient()));
804+
checkServerVersion(2.5);
805+
enableMaxTimeFailPoint();
806+
DBCursor cursor = new DBCursor(collection, new BasicDBObject("x", 1), new BasicDBObject(), ReadPreference.primary());
807+
cursor.setDecoderFactory(new SubsitutingDBDecoderFactory(new BasicDBObject()));
808+
cursor.maxTime(1, SECONDS);
809+
try {
810+
cursor.next();
811+
fail("Show have thrown");
812+
} catch (MongoExecutionTimeoutException e) {
813+
assertEquals(50, e.getCode());
814+
} finally {
815+
disableMaxTimeFailPoint();
816+
}
817+
}
818+
801819
private void insertData() {
802820
for (int i = 0; i < 10; i++) {
803821
collection.insert(new BasicDBObject("_id", i).append("x", i));
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/*
2+
* Copyright 2016 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+
*/
17+
18+
package com.mongodb;
19+
20+
import org.bson.BSONCallback;
21+
import org.bson.BSONObject;
22+
23+
import java.io.IOException;
24+
import java.io.InputStream;
25+
26+
class SubsitutingDBDecoderFactory implements DBDecoderFactory {
27+
private final DBObject substituted;
28+
29+
SubsitutingDBDecoderFactory(final DBObject substituted) {
30+
this.substituted = substituted;
31+
}
32+
33+
@Override
34+
public DBDecoder create() {
35+
final DBDecoder defaultDecoder = DefaultDBDecoder.FACTORY.create();
36+
return new DBDecoder() {
37+
@Override
38+
public DBCallback getDBCallback(final DBCollection collection) {
39+
return defaultDecoder.getDBCallback(collection);
40+
}
41+
42+
@Override
43+
public DBObject decode(final InputStream input, final DBCollection collection) throws IOException {
44+
defaultDecoder.decode(input, collection);
45+
return substituted;
46+
}
47+
48+
@Override
49+
public DBObject decode(final byte[] bytes, final DBCollection collection) {
50+
return substituted;
51+
}
52+
53+
@Override
54+
public BSONObject readObject(final byte[] bytes) {
55+
return substituted;
56+
}
57+
58+
@Override
59+
public BSONObject readObject(final InputStream in) throws IOException {
60+
defaultDecoder.readObject(in);
61+
return substituted;
62+
}
63+
64+
@Override
65+
public int decode(final byte[] bytes, final BSONCallback callback) {
66+
return defaultDecoder.decode(bytes, callback);
67+
}
68+
69+
@Override
70+
public int decode(final InputStream in, final BSONCallback callback) throws IOException {
71+
throw new UnsupportedOperationException();
72+
}
73+
};
74+
}
75+
}

0 commit comments

Comments
 (0)