io.vertx.ext.mongo.impl.MongoGridFsClientImpl Maven / Gradle / Ivy
package io.vertx.ext.mongo.impl;
import com.mongodb.client.gridfs.model.GridFSDownloadOptions;
import com.mongodb.client.gridfs.model.GridFSUploadOptions;
import com.mongodb.reactivestreams.client.gridfs.GridFSBucket;
import com.mongodb.reactivestreams.client.gridfs.GridFSDownloadPublisher;
import io.vertx.core.AsyncResult;
import io.vertx.core.Future;
import io.vertx.core.Handler;
import io.vertx.core.Promise;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.file.OpenOptions;
import io.vertx.core.impl.VertxInternal;
import io.vertx.core.json.JsonObject;
import io.vertx.core.streams.ReadStream;
import io.vertx.core.streams.WriteStream;
import io.vertx.ext.mongo.*;
import org.bson.Document;
import org.bson.conversions.Bson;
import org.bson.types.ObjectId;
import java.nio.ByteBuffer;
import java.util.List;
import java.util.function.Function;
import static io.netty.buffer.Unpooled.copiedBuffer;
import static io.vertx.ext.mongo.impl.Utils.setHandler;
import static java.util.Objects.requireNonNull;
/**
* The implementation of the {@link MongoGridFsClient}. This implementation is based on the async driver
* provided by Mongo.
*
* @author David Bush
*/
public class MongoGridFsClientImpl implements MongoGridFsClient {
private final GridFSBucket bucket;
private final MongoClientImpl clientImpl;
private final VertxInternal vertx;
public MongoGridFsClientImpl(VertxInternal vertx, MongoClientImpl mongoClient, GridFSBucket gridFSBucket) {
this.vertx = vertx;
this.clientImpl = mongoClient;
this.bucket = gridFSBucket;
}
@Override
public MongoGridFsClient uploadByFileName(ReadStream stream, String fileName, Handler> resultHandler) {
Future future = uploadByFileName(stream, fileName);
setHandler(future, resultHandler);
return this;
}
@Override
public Future uploadByFileName(ReadStream stream, String fileName) {
GridFSReadStreamPublisher publisher = new GridFSReadStreamPublisher(stream);
Promise promise = vertx.promise();
bucket.uploadFromPublisher(fileName, publisher).subscribe(new SingleResultSubscriber<>(promise));
return promise.future().map(ObjectId::toHexString);
}
@Override
public MongoGridFsClient uploadByFileNameWithOptions(ReadStream stream, String fileName, GridFsUploadOptions options, Handler> resultHandler) {
Future future = uploadByFileNameWithOptions(stream, fileName, options);
setHandler(future, resultHandler);
return this;
}
@Override
public Future uploadByFileNameWithOptions(ReadStream stream, String fileName, GridFsUploadOptions options) {
GridFSUploadOptions uploadOptions = new GridFSUploadOptions();
uploadOptions.chunkSizeBytes(options.getChunkSizeBytes());
if (options.getMetadata() != null) uploadOptions.metadata(new Document(options.getMetadata().getMap()));
GridFSReadStreamPublisher publisher = new GridFSReadStreamPublisher(stream);
Promise promise = vertx.promise();
bucket.uploadFromPublisher(fileName, publisher, uploadOptions).subscribe(new SingleResultSubscriber<>(promise));
return promise.future().map(ObjectId::toHexString);
}
@Override
public MongoGridFsClient uploadFile(String fileName, Handler> resultHandler) {
Future future = uploadFile(fileName);
setHandler(future, resultHandler);
return this;
}
@Override
public Future uploadFile(String fileName) {
requireNonNull(fileName, "fileName cannot be null");
return uploadFileWithOptions(fileName, null);
}
@Override
public MongoGridFsClient uploadFileWithOptions(String fileName, GridFsUploadOptions options, Handler> resultHandler) {
Future future = uploadFileWithOptions(fileName, options);
setHandler(future, resultHandler);
return this;
}
@Override
public Future uploadFileWithOptions(String fileName, GridFsUploadOptions options) {
requireNonNull(fileName, "fileName cannot be null");
OpenOptions openOptions = new OpenOptions().setRead(true);
return vertx.fileSystem().open(fileName, openOptions)
.flatMap(file -> {
GridFSReadStreamPublisher publisher = new GridFSReadStreamPublisher(file);
Promise promise = vertx.promise();
if (options == null) {
bucket.uploadFromPublisher(fileName, publisher).subscribe(new SingleResultSubscriber<>(promise));
} else {
GridFSUploadOptions uploadOptions = new GridFSUploadOptions();
uploadOptions.chunkSizeBytes(options.getChunkSizeBytes());
if (options.getMetadata() != null) {
uploadOptions.metadata(new Document(options.getMetadata().getMap()));
}
bucket.uploadFromPublisher(fileName, publisher, uploadOptions).subscribe(new SingleResultSubscriber<>(promise));
}
return promise.future().map(ObjectId::toHexString);
});
}
@Override
public void close() {
}
@Override
public MongoGridFsClient delete(String id, Handler> resultHandler) {
Future future = delete(id);
setHandler(future, resultHandler);
return this;
}
@Override
public Future delete(String id) {
requireNonNull(id, "id cannot be null");
ObjectId objectId = new ObjectId(id);
Promise promise = vertx.promise();
bucket.delete(objectId).subscribe(new CompletionSubscriber<>(promise));
return promise.future();
}
@Override
public ReadStream readByFileName(String fileName) {
GridFSDownloadPublisher publisher = bucket.downloadToPublisher(fileName);
return handleRead(publisher);
}
@Override
public ReadStream readByFileNameWithOptions(String fileName, GridFsDownloadOptions options) {
GridFSDownloadOptions downloadOptions = new GridFSDownloadOptions();
GridFSDownloadPublisher publisher = bucket.downloadToPublisher(fileName, downloadOptions);
return handleRead(publisher);
}
@Override
public ReadStream readById(String id) {
ObjectId objectId = new ObjectId(id);
GridFSDownloadPublisher publisher = bucket.downloadToPublisher(objectId);
return handleRead(publisher);
}
@Override
public MongoGridFsClient downloadByFileName(WriteStream stream, String fileName, Handler> resultHandler) {
Future future = downloadByFileName(stream, fileName);
setHandler(future, resultHandler);
return this;
}
@Override
public Future downloadByFileName(WriteStream stream, String fileName) {
GridFSDownloadPublisher publisher = bucket.downloadToPublisher(fileName);
return handleDownload(publisher, stream);
}
@Override
public MongoGridFsClient downloadByFileNameWithOptions(WriteStream stream, String fileName, GridFsDownloadOptions options, Handler> resultHandler) {
Future future = downloadByFileNameWithOptions(stream, fileName, options);
setHandler(future, resultHandler);
return this;
}
@Override
public Future downloadByFileNameWithOptions(WriteStream stream, String fileName, GridFsDownloadOptions options) {
GridFSDownloadOptions downloadOptions = new GridFSDownloadOptions();
GridFSDownloadPublisher publisher = bucket.downloadToPublisher(fileName, downloadOptions);
return handleDownload(publisher, stream);
}
@Override
public MongoGridFsClient downloadById(WriteStream stream, String id, Handler> resultHandler) {
Future future = downloadById(stream, id);
setHandler(future, resultHandler);
return this;
}
@Override
public Future downloadById(WriteStream stream, String id) {
ObjectId objectId = new ObjectId(id);
GridFSDownloadPublisher publisher = bucket.downloadToPublisher(objectId);
return handleDownload(publisher, stream);
}
@Override
public MongoGridFsClient downloadFile(String fileName, Handler> resultHandler) {
Future future = downloadFile(fileName);
setHandler(future, resultHandler);
return this;
}
@Override
public Future downloadFile(String fileName) {
requireNonNull(fileName, "fileName cannot be null");
return downloadFileAs(fileName, fileName);
}
@Override
public MongoGridFsClient downloadFileAs(String fileName, String newFileName, Handler> resultHandler) {
Future future = downloadFileAs(fileName, newFileName);
setHandler(future, resultHandler);
return this;
}
@Override
public Future downloadFileAs(String fileName, String newFileName) {
requireNonNull(fileName, "fileName cannot be null");
requireNonNull(newFileName, "newFileName cannot be null");
OpenOptions options = new OpenOptions().setWrite(true);
return vertx.fileSystem().open(newFileName, options)
.flatMap(file -> {
GridFSDownloadPublisher publisher = bucket.downloadToPublisher(fileName);
return handleDownload(publisher, file);
});
}
@Override
public MongoGridFsClient downloadFileByID(String id, String fileName, Handler> resultHandler) {
Future future = downloadFileByID(id, fileName);
setHandler(future, resultHandler);
return this;
}
@Override
public Future downloadFileByID(String id, String fileName) {
requireNonNull(fileName, "fileName cannot be null");
OpenOptions options = new OpenOptions().setWrite(true);
return vertx.fileSystem().open(fileName, options)
.flatMap(file -> {
ObjectId objectId = new ObjectId(id);
GridFSDownloadPublisher publisher = bucket.downloadToPublisher(objectId);
return handleDownload(publisher, file);
});
}
@Override
public MongoGridFsClient drop(Handler> resultHandler) {
Future future = drop();
setHandler(future, resultHandler);
return this;
}
@Override
public Future drop() {
Promise promise = vertx.promise();
bucket.drop().subscribe(new CompletionSubscriber<>(promise));
return promise.future();
}
@Override
public MongoGridFsClient findAllIds(Handler>> resultHandler) {
Future> future = findAllIds();
setHandler(future, resultHandler);
return this;
}
@Override
public Future> findAllIds() {
Promise> promise = vertx.promise();
bucket.find().subscribe(new MappingAndBufferingSubscriber<>(gridFSFile -> gridFSFile.getObjectId().toHexString(), promise));
return promise.future();
}
@Override
public MongoGridFsClient findIds(JsonObject query, Handler>> resultHandler) {
Future> future = findIds(query);
setHandler(future, resultHandler);
return this;
}
@Override
public Future> findIds(JsonObject query) {
requireNonNull(query, "query cannot be null");
JsonObject encodedQuery = clientImpl.encodeKeyWhenUseObjectId(query);
Bson bquery = clientImpl.wrap(encodedQuery);
Promise> promise = vertx.promise();
bucket.find(bquery).subscribe(new MappingAndBufferingSubscriber<>(gridFSFile -> gridFSFile.getObjectId().toHexString(), promise));
return promise.future();
}
private Future handleDownload(GridFSDownloadPublisher publisher, WriteStream stream) {
ReadStream adapter = new PublisherAdapter<>(vertx.getOrCreateContext(), publisher, 16);
MapAndCountBuffer mapper = new MapAndCountBuffer();
MappingStream rs = new MappingStream<>(adapter, mapper);
return rs.pipeTo(stream).map(v -> mapper.count);
}
private ReadStream handleRead(GridFSDownloadPublisher publisher) {
ReadStream adapter = new PublisherAdapter<>(vertx.getOrCreateContext(), publisher, 16);
MapBuffer mapper = new MapBuffer();
return new MappingStream<>(adapter, mapper);
}
private static class MapAndCountBuffer implements Function {
private long count = 0;
@Override
public Buffer apply(ByteBuffer bb) {
Buffer buffer = Buffer.buffer(copiedBuffer(bb));
count += buffer.length();
return buffer;
}
}
private static class MapBuffer implements Function {
@Override
public Buffer apply(ByteBuffer bb) {
Buffer buffer = Buffer.buffer(copiedBuffer(bb));
return buffer;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy