Skip to content

Commit b67650f

Browse files
committed
GridFS handle alternative numbers for the files metadata
JAVA-2023
1 parent a13ffa3 commit b67650f

File tree

2 files changed

+94
-5
lines changed

2 files changed

+94
-5
lines changed

driver/src/main/com/mongodb/client/gridfs/GridFSFindIterableImpl.java

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import com.mongodb.Block;
2020
import com.mongodb.Function;
2121
import com.mongodb.MongoClient;
22+
import com.mongodb.MongoGridFSException;
2223
import com.mongodb.client.FindIterable;
2324
import com.mongodb.client.MongoCursor;
2425
import com.mongodb.client.MongoIterable;
@@ -39,6 +40,7 @@
3940
import java.util.concurrent.TimeUnit;
4041

4142
import static java.util.Arrays.asList;
43+
import static java.lang.String.format;
4244

4345
class GridFSFindIterableImpl implements GridFSFindIterable {
4446
private static final CodecRegistry DEFAULT_CODEC_REGISTRY = MongoClient.getDefaultCodecRegistry();
@@ -122,11 +124,11 @@ private MongoIterable<GridFSFile> toGridFSFileIterable() {
122124
public GridFSFile apply(final Document document) {
123125
BsonValue id = getId(document);
124126
String filename = document.getString("filename");
125-
long length = document.getLong("length");
126-
int chunkSize = document.getInteger("chunkSize");
127+
long length = getAndValidateNumber("length", document).longValue();
128+
int chunkSize = getAndValidateNumber("chunkSize", document).intValue();
127129
Date uploadDate = document.getDate("uploadDate");
128-
String md5 = document.getString("md5");
129130

131+
String md5 = document.getString("md5");
130132
Document metadata = document.get("metadata", Document.class);
131133
Set<String> extraElementKeys = new HashSet<String>(document.keySet());
132134
extraElementKeys.removeAll(VALID_FIELDS);
@@ -144,6 +146,14 @@ public GridFSFile apply(final Document document) {
144146
});
145147
}
146148

149+
private Number getAndValidateNumber(final String fieldName, final Document document) {
150+
Number value = document.get(fieldName, Number.class);
151+
if ((value.floatValue() % 1) != 0){
152+
throw new MongoGridFSException(format("Invalid number format for %s", fieldName));
153+
}
154+
return value;
155+
}
156+
147157
private BsonValue getId(final Document document) {
148158
Object rawId = document.get("_id");
149159
if (rawId instanceof ObjectId) {

driver/src/test/unit/com/mongodb/client/gridfs/GridFSFindIterableSpecification.groovy

Lines changed: 81 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import com.mongodb.CursorType
2121
import com.mongodb.FindIterableImpl
2222
import com.mongodb.Function
2323
import com.mongodb.MongoClient
24+
import com.mongodb.MongoGridFSException
2425
import com.mongodb.MongoNamespace
2526
import com.mongodb.ReadConcern
2627
import com.mongodb.TestOperationExecutor
@@ -152,8 +153,8 @@ class GridFSFindIterableSpecification extends Specification {
152153
firstResult.getId() == new BsonInt32(expectedResult.getInteger('_id'));
153154
}
154155
firstResult.getFilename() == expectedResult.getString('filename')
155-
firstResult.getLength() == expectedResult.getLong('length')
156-
firstResult.getChunkSize() == expectedResult.getInteger('chunkSize')
156+
firstResult.getLength() == expectedResult.get('length')
157+
firstResult.getChunkSize() == expectedResult.get('chunkSize')
157158
firstResult.getMD5() == expectedResult.getString('md5')
158159
firstResult.getUploadDate() == expectedResult.getDate('uploadDate')
159160

@@ -210,6 +211,66 @@ class GridFSFindIterableSpecification extends Specification {
210211
cannedResults << [toSpecCannedResults, legacyCannedResults]
211212
}
212213

214+
def 'should handle alternative data for the GridFS file'() {
215+
given:
216+
def expectedLength = 123
217+
def expectedChunkSize = 255
218+
219+
def cursor = {
220+
Stub(BatchCursor) {
221+
def count = 0
222+
def getResult = {
223+
count++
224+
count == 1 ? [cannedResults] : null
225+
}
226+
next() >> { getResult() }
227+
hasNext() >> { count == 0 }
228+
}
229+
}
230+
def executor = new TestOperationExecutor([cursor()]);
231+
def underlying = new FindIterableImpl(namespace, Document, Document, codecRegistry, readPreference, readConcern, executor,
232+
new Document(), new FindOptions())
233+
def mongoIterable = new GridFSFindIterableImpl(underlying)
234+
235+
when:
236+
def results = mongoIterable.first()
237+
238+
then:
239+
results.getLength() == expectedLength
240+
results.getChunkSize() == expectedChunkSize
241+
242+
where:
243+
cannedResults << alternativeImplCannedResults
244+
}
245+
246+
def 'should throw if has a value with a decimal'() {
247+
given:
248+
def cursor = {
249+
Stub(BatchCursor) {
250+
def count = 0
251+
def getResult = {
252+
count++
253+
count == 1 ? [cannedResults] : null
254+
}
255+
next() >> { getResult() }
256+
hasNext() >> { count == 0 }
257+
}
258+
}
259+
def executor = new TestOperationExecutor([cursor()]);
260+
def underlying = new FindIterableImpl(namespace, Document, Document, codecRegistry, readPreference, readConcern, executor,
261+
new Document(), new FindOptions())
262+
def mongoIterable = new GridFSFindIterableImpl(underlying)
263+
264+
when:
265+
mongoIterable.first()
266+
267+
then:
268+
thrown(MongoGridFSException)
269+
270+
where:
271+
cannedResults << invalidFloatCannedResults
272+
}
273+
213274
@Shared
214275
def toSpecCannedResults = [
215276
Document.parse('''{ '_id' : { '$oid' : '000000000000000000000001' }, 'filename' : 'File 1',
@@ -236,6 +297,24 @@ class GridFSFindIterableSpecification extends Specification {
236297
'md5' : 'd41d8cd98f00b204e9800998ecf8427e', 'aliases' : ['File Three', 'Third File'] }''')
237298
]
238299

300+
@Shared
301+
def alternativeImplCannedResults = [
302+
Document.parse('''{ '_id' : 1, 'filename' : 'File 1', 'length' : 123, 'chunkSize' : { '$numberLong' : '255' },
303+
'uploadDate' : { '$date' : 1438679434041 }, 'md5' : 'd41d8cd98f00b204e9800998ecf8427e' }'''),
304+
Document.parse('''{ '_id' : { '$oid' : '000000000000000000000001' }, 'filename' : 'File 2', 'length' : 123.0,
305+
'chunkSize' : 255.0, 'uploadDate' : { '$date' : 1438679434050 },
306+
'md5' : 'd41d8cd98f00b204e9800998ecf8427e'}''')
307+
]
308+
309+
@Shared
310+
def invalidFloatCannedResults = [
311+
Document.parse('''{ '_id' : 1, 'filename' : 'File 1', 'length' : 123.4, 'chunkSize' : 255,
312+
'uploadDate' : { '$date' : 1438679434041 }, 'md5' : 'd41d8cd98f00b204e9800998ecf8427e' }'''),
313+
Document.parse('''{ '_id' : { '$oid' : '000000000000000000000001' }, 'filename' : 'File 2', 'length' : 123,
314+
'chunkSize' : 255.5, 'uploadDate' : { '$date' : 1438679434050 },
315+
'md5' : 'd41d8cd98f00b204e9800998ecf8427e'}''')
316+
]
317+
239318
@Shared
240319
mixedResults = [toSpecCannedResults[0], legacyCannedResults[1], legacyCannedResults[2]]
241320
}

0 commit comments

Comments
 (0)