1 package de.dlr.shepard.mongoDB;
2
3 import static com.mongodb.client.model.Filters.eq;
4
5 import java.io.InputStream;
6 import java.security.DigestInputStream;
7 import java.security.MessageDigest;
8 import java.security.NoSuchAlgorithmException;
9
10 import org.bson.Document;
11 import org.bson.types.ObjectId;
12
13 import com.mongodb.client.MongoCollection;
14 import com.mongodb.client.gridfs.GridFSBucket;
15
16 import de.dlr.shepard.util.DateHelper;
17 import de.dlr.shepard.util.UUIDHelper;
18 import jakarta.xml.bind.DatatypeConverter;
19 import lombok.extern.slf4j.Slf4j;
20
21 @Slf4j
22 public class FileService {
23
24 private static final int CHUNK_SIZE_BYTES = 1024 * 1024;
25 private static final String ID_ATTR = "_id";
26 private static final String FILENAME_ATTR = "name";
27 private static final String FILEID_ATTR = "FileMongoId";
28 private static final String CREATEDAT_ATTR = "createdAt";
29 private static final String MD5_ATTR = "md5";
30
31 private MongoDBConnector mongoDBConnector = MongoDBConnector.getInstance();
32 private UUIDHelper uuidHelper = new UUIDHelper();
33 private DateHelper dateHelper = new DateHelper();
34
35 public String createFileContainer() {
36 String oid = "FileContainer" + uuidHelper.getUUID().toString();
37 mongoDBConnector.createCollection(oid);
38 return oid;
39 }
40
41 public ShepardFile createFile(String mongoid, String fileName, InputStream inputStream) {
42 MongoCollection<Document> collection;
43 try {
44 collection = mongoDBConnector.getDatabase().getCollection(mongoid);
45 } catch (IllegalArgumentException e) {
46 log.error("Could not find container with mongoid: {}", mongoid);
47 return null;
48 }
49
50 MessageDigest md;
51 try {
52 md = MessageDigest.getInstance("MD5");
53 } catch (NoSuchAlgorithmException e) {
54 log.error("No Such Algorithm while uploading file");
55 return null;
56 }
57 DigestInputStream dis = new DigestInputStream(inputStream, md);
58 String fileMongoId = mongoDBConnector.createBucket().withChunkSizeBytes(CHUNK_SIZE_BYTES)
59 .uploadFromStream(fileName, dis).toHexString();
60 var file = new ShepardFile(dateHelper.getDate(), fileName, DatatypeConverter.printHexBinary(md.digest()));
61 var doc = toDocument(file).append(FILEID_ATTR, fileMongoId);
62 collection.insertOne(doc);
63 file.setOid(doc.getObjectId(ID_ATTR).toHexString());
64 return file;
65 }
66
67 public NamedInputStream getPayload(String containerId, String fileoid) {
68 MongoCollection<Document> collection;
69 try {
70 collection = mongoDBConnector.getDatabase().getCollection(containerId);
71 } catch (IllegalArgumentException e) {
72 log.error("Could not find container with mongoid: {}", containerId);
73 return null;
74 }
75 var oid = new ObjectId(fileoid);
76 var payloadDocument = collection.find(eq(ID_ATTR, oid)).first();
77 if (payloadDocument == null) {
78 log.error("Could not find document with oid: {}", fileoid);
79 return null;
80 }
81 var fileId = new ObjectId(payloadDocument.getString(FILEID_ATTR));
82 var filename = payloadDocument.getString(FILENAME_ATTR);
83 var gridBucket = mongoDBConnector.createBucket();
84 var gridFsFile = gridBucket.find(eq(ID_ATTR, fileId)).first();
85 var inputStream = gridBucket.openDownloadStream(fileId);
86
87 return new NamedInputStream(inputStream, filename, gridFsFile.getLength());
88 }
89
90 public ShepardFile getFile(String containerId, String fileoid) {
91 MongoCollection<Document> collection;
92 try {
93 collection = mongoDBConnector.getDatabase().getCollection(containerId);
94 } catch (IllegalArgumentException e) {
95 log.error("Could not find container with mongoid: {}", containerId);
96 return null;
97 }
98 var doc = collection.find(eq(ID_ATTR, new ObjectId(fileoid))).first();
99 if (doc == null) {
100 log.error("Could not find file with oid: {}", fileoid);
101 return null;
102 }
103 return toShepardFile(doc);
104 }
105
106 public boolean deleteFileContainer(String mongoid) {
107 MongoCollection<Document> toDelete;
108 try {
109 toDelete = mongoDBConnector.getDatabase().getCollection(mongoid);
110 } catch (IllegalArgumentException e) {
111 log.error("Could not delete container with mongoid: {}", mongoid);
112 return false;
113 }
114 GridFSBucket gridBucket = mongoDBConnector.createBucket();
115 for (Document doc : toDelete.find()) {
116 gridBucket.delete(new ObjectId(doc.getString(FILEID_ATTR)));
117 }
118 toDelete.drop();
119 return true;
120 }
121
122 public boolean deleteFile(String mongoId, String fileoid) {
123 MongoCollection<Document> collection;
124 try {
125 collection = mongoDBConnector.getDatabase().getCollection(mongoId);
126 } catch (IllegalArgumentException e) {
127 log.error("Could not find container with mongoid: {}", mongoId);
128 return false;
129 }
130 var doc = collection.findOneAndDelete(eq(ID_ATTR, new ObjectId(fileoid)));
131 if (doc == null) {
132 log.warn("Could not find and delete file with oid: {}", fileoid);
133 return true;
134 }
135 var gridBucket = mongoDBConnector.createBucket();
136 gridBucket.delete(new ObjectId(doc.getString(FILEID_ATTR)));
137 return true;
138 }
139
140 private static ShepardFile toShepardFile(Document doc) {
141 var file = new ShepardFile(doc.getObjectId(ID_ATTR).toHexString(), doc.getDate(CREATEDAT_ATTR),
142 doc.getString(FILENAME_ATTR), doc.getString(MD5_ATTR));
143 return file;
144 }
145
146 private static Document toDocument(ShepardFile file) {
147 var doc = new Document().append(CREATEDAT_ATTR, file.getCreatedAt()).append(FILENAME_ATTR, file.getFilename())
148 .append(MD5_ATTR, file.getMd5());
149 if (file.getOid() != null)
150 doc.append(ID_ATTR, new ObjectId(file.getOid()));
151 return doc;
152 }
153
154 }