Skip to content

Commit b135b9e

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

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.TestOperationExecutor
2627
import com.mongodb.client.gridfs.model.GridFSFile
@@ -150,8 +151,8 @@ class GridFSFindIterableSpecification extends Specification {
150151
firstResult.getId() == new BsonInt32(expectedResult.getInteger('_id'));
151152
}
152153
firstResult.getFilename() == expectedResult.getString('filename')
153-
firstResult.getLength() == expectedResult.getLong('length')
154-
firstResult.getChunkSize() == expectedResult.getInteger('chunkSize')
154+
firstResult.getLength() == expectedResult.get('length')
155+
firstResult.getChunkSize() == expectedResult.get('chunkSize')
155156
firstResult.getMD5() == expectedResult.getString('md5')
156157
firstResult.getUploadDate() == expectedResult.getDate('uploadDate')
157158

@@ -208,6 +209,66 @@ class GridFSFindIterableSpecification extends Specification {
208209
cannedResults << [toSpecCannedResults, legacyCannedResults]
209210
}
210211

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

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

0 commit comments

Comments
 (0)