View Javadoc
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; // 1 MiB
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(fileoid, 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 }