Skip to content

Commit

Permalink
Mongodb file download fix (#333)
Browse files Browse the repository at this point in the history
  • Loading branch information
chf73 committed Jul 11, 2023
1 parent 64a6ccd commit 119d933
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 9 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
[![Components Lib javadoc](https://javadoc.io/badge2/org.eclipse.basyx/basyx.components.lib/javadoc.svg)](https://javadoc.io/doc/org.eclipse.basyx/basyx.components.lib) Components Lib


This repository contains BaSyx Java V1. If you're looking for BaSyx Java V2, see [here](https://github.com/eclipse-basyx/basyx-java-server-sdk).


The Eclipse BaSyx Java Components are part of the [Eclipse BaSyx middleware](https://www.eclipse.org/basyx/). The Components utilize the [BaSyx Java SDK](https://github.com/eclipse-basyx/basyx-java-sdk) to provide easy to use off-the-shelf components and have been created within the [BaSys](https://www.basys40.de/) project.

## Eclipse Wiki
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import java.io.OutputStream;
import java.util.Collection;
import java.util.Map;
import java.util.Objects;

import org.eclipse.basyx.aas.metamodel.map.descriptor.CustomId;
import org.eclipse.basyx.components.aas.mongodb.MongoDBSubmodelAPI;
Expand Down Expand Up @@ -91,7 +92,7 @@ public void fileSubmodelElementFileUpload() throws FileNotFoundException {

java.io.File value = submodelAPI.getSubmodelElementFile("fileSmeIdShort");

assertEquals("mySubmodelId-fileSmeIdShort.xml", value.getName());
assertEquals("#"+ Objects.hashCode(submodelAPI.getSubmodelId())+"#mySubmodelId-fileSmeIdShort.xml", value.getName());
assertEquals(expected.length(), value.length());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -172,11 +173,17 @@ public java.io.File getFile(String idShortPath, String parentKey, Map<String, Ob
GridFSBucket bucket = MongoDBFileHelper.getGridFSBucket(client, config);
String fileName = MongoDBFileHelper.constructFileName(parentKey, fileSubmodelElement, idShortPath);
java.io.File file = new java.io.File(fileName);
FileOutputStream fileOutputStream;
fileOutputStream = new FileOutputStream(file);
bucket.downloadToStream(fileName, fileOutputStream);
// check if file with this filename exist in MongoDB
// there might be older files constructed with old (=legacy) filenames, use this one instead
// the real file in file system still uses the new filename pattern!
if (!MongoDBFileHelper.fileExists(bucket, fileName)) {
fileName = MongoDBFileHelper.legacyFileName(parentKey, fileSubmodelElement, idShortPath);
}
try (FileOutputStream fileOutputStream = new FileOutputStream(file)) {
bucket.downloadToStream(fileName, fileOutputStream);
}
return file;
} catch (FileNotFoundException e) {
} catch (IOException e) {
throw new ResourceNotFoundException("The File Submodel Element does not contain a File");
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,10 @@
package org.eclipse.basyx.components.internal.mongodb;

import java.io.InputStream;
import java.util.Arrays;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

import org.apache.tika.mime.MimeType;
import org.apache.tika.mime.MimeTypeException;
Expand Down Expand Up @@ -57,7 +60,7 @@ public static String updateFileInDB(MongoClient client, BaSyxMongoDBConfiguratio
File file = File.createAsFacade((Map<String, Object>) 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;
}
Expand All @@ -69,22 +72,44 @@ 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) {
MongoDatabase database = client.getDatabase(config.getDatabase());
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 {
Expand Down

0 comments on commit 119d933

Please sign in to comment.