From c5906e75cb75bf0001e909d566d33e6535d58190 Mon Sep 17 00:00:00 2001 From: Christian Frank Date: Thu, 29 Jun 2023 13:41:01 +0200 Subject: [PATCH] merge with new structure: support old filenames for download, replace with new filename during updates --- .../mongodb/MongoDBBaSyxStorageAPI.java | 15 ++++++--- .../internal/mongodb/MongoDBFileHelper.java | 33 ++++++++++++++++--- 2 files changed, 40 insertions(+), 8 deletions(-) diff --git a/basyx.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/internal/mongodb/MongoDBBaSyxStorageAPI.java b/basyx.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/internal/mongodb/MongoDBBaSyxStorageAPI.java index 6fbf24d3..6cde1634 100644 --- a/basyx.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/internal/mongodb/MongoDBBaSyxStorageAPI.java +++ b/basyx.components/basyx.components.lib/src/main/java/org/eclipse/basyx/components/internal/mongodb/MongoDBBaSyxStorageAPI.java @@ -30,6 +30,7 @@ import java.io.FileNotFoundException; import java.io.FileOutputStream; +import java.io.IOException; import java.io.InputStream; import java.util.Collection; import java.util.Map; @@ -144,11 +145,17 @@ public java.io.File getFile(String idShortPath, String parentKey, Map) element); GridFSBucket bucket = getGridFSBucket(client, config); String fileName = constructFileName(submodelId, file, idShortPath); - deleteAllDuplicateFiles(bucket, fileName); + deleteAllDuplicateFiles(bucket, fileName, legacyFileName(submodelId, file, idShortPath)); bucket.uploadFromStream(fileName, newValue); return fileName; } @@ -69,7 +72,11 @@ public static void deleteAllFilesFromGridFsIfIsFileSubmodelElement(MongoClient c return; File file = File.createAsFacade(submodelElement); GridFSBucket bucket = MongoDBFileHelper.getGridFSBucket(client, config); - bucket.find(Filters.eq("filename", file.getValue())).forEach(gridFile -> bucket.delete(gridFile.getObjectId())); + deleteAllDuplicateFiles(bucket, constructFileName(sm.getIdentification().getId(), file, idShort), legacyFileName(sm.getIdentification().getId(), file, idShort)); + } + + protected static boolean fileExists(GridFSBucket bucket, String fileName) { + return bucket.find(Filters.eq("filename", fileName)).first() != null; } public static GridFSBucket getGridFSBucket(MongoClient client, BaSyxMongoDBConfiguration config) { @@ -77,14 +84,32 @@ public static GridFSBucket getGridFSBucket(MongoClient client, BaSyxMongoDBConfi return GridFSBuckets.create(database, config.getFileCollection()); } - private static void deleteAllDuplicateFiles(GridFSBucket bucket, String fileName) { - bucket.find(Filters.eq("filename", fileName)).forEach(gridFile -> bucket.delete(gridFile.getObjectId())); + private static void deleteAllDuplicateFiles(GridFSBucket bucket, String... fileNames) { + bucket.find(Filters.or( + Arrays.stream(fileNames) + .map(fileName -> Filters.eq("filename", fileName)) + .collect(Collectors.toList()))) + .forEach(gridFile -> bucket.delete(gridFile.getObjectId())); } public static String constructFileName(String submodelId, File file, String idShortPath) { + String fileName = submodelId + "-" + idShortPath.replaceAll("/", "-") + getFileExtension(file); + // replace those chars that are not permitted on filesystems + fileName = fileName.replaceAll("[^a-zA-Z0-9-_\\.]", "_"); + // ensure the filename is still unique to be used as key in MongoDB storage layer + return String.format("#%s#", Objects.hashCode(submodelId)).concat(fileName); + } + /** + * This method is kept for backwards compatibility to still find files from DB which where stored with old scheme. + * @param file the filename of this file is requested. + * @param idShortPath the shortId of the given file. + * @return the filename as it was constructed in older versions. + */ + public static String legacyFileName(String submodelId, File file, String idShortPath) { return submodelId + "-" + idShortPath.replaceAll("/", "-") + getFileExtension(file); } + private static String getFileExtension(File file) { MimeTypes allTypes = MimeTypes.getDefaultMimeTypes(); try {