From ef3c3822f065f8815c17d51d0598879e0807b210 Mon Sep 17 00:00:00 2001 From: Timm Fitschen <t.fitschen@indiscale.com> Date: Wed, 14 Dec 2022 22:10:49 +0100 Subject: [PATCH] WIP: file system: import --- .../java/org/caosdb/server/entity/Entity.java | 20 ++++++++++++++----- .../server/filesystem/FSODescriptor.java | 10 ++++++++++ .../filesystem/FileStorageInterface.java | 6 ++++-- .../caosdb/server/filesystem/FileSystem.java | 9 +++++++-- .../server/filesystem/LocalFileStorage.java | 17 +++++++++++++++- .../server/filesystem/SharedFileStorage.java | 2 +- .../VirtualFSODescriptorInterface.java | 2 ++ .../consistency/ConsistencyCheck.java | 2 +- .../java/org/caosdb/server/jobs/FilesJob.java | 17 +++++++++++++++- .../jobs/core/CheckTargetPathValid.java | 10 ++++++++++ .../caosdb/server/utils/ServerMessages.java | 6 ++++++ 11 files changed, 88 insertions(+), 13 deletions(-) diff --git a/src/main/java/org/caosdb/server/entity/Entity.java b/src/main/java/org/caosdb/server/entity/Entity.java index 04237c31..61a287e6 100644 --- a/src/main/java/org/caosdb/server/entity/Entity.java +++ b/src/main/java/org/caosdb/server/entity/Entity.java @@ -816,21 +816,31 @@ public abstract class Entity extends AbstractObservable implements EntityInterfa linkTarget = Integer.parseInt(element.getAttributeValue("linktarget")); } + // Parse IMPORT + boolean isImport = false; + if (element.getAttribute("import") != null + && element.getAttributeValue("import").equals("true")) { + isImport = true; + } + // Store PATH, HASH, SIZE, TMPIDENTIFYER if (tmpIdentifier != null || checksum != null || path != null || size != null) { // legacy clients (which use this api) always use sha512. Hash hash = Hash.create(checksum, 0, Hasher.Default); + FSODescriptor fso; if (getRole() == Role.Directory) { - setFSODescriptor(FSODescriptor.createDir(FileSystem.DEFAULT_BACKEND, new Path(path))); + fso = FSODescriptor.createDir(FileSystem.DEFAULT_BACKEND, new Path(path)); } else if (getRole() == Role.Link) { - setFSODescriptor( + fso = FSODescriptor.createLink( - FileSystem.DEFAULT_BACKEND, new Path(path), new EntityID(linkTarget))); + FileSystem.DEFAULT_BACKEND, new Path(path), new EntityID(linkTarget)); } else { - setFSODescriptor( + fso = new FSODescriptor( - FileSystem.DEFAULT_BACKEND, null, hash, new Path(path), size, tmpIdentifier)); + FileSystem.DEFAULT_BACKEND, null, hash, new Path(path), size, tmpIdentifier); } + fso.setImport(isImport); + setFSODescriptor(fso); } // Parse flags diff --git a/src/main/java/org/caosdb/server/filesystem/FSODescriptor.java b/src/main/java/org/caosdb/server/filesystem/FSODescriptor.java index 19b1c829..ee99d816 100644 --- a/src/main/java/org/caosdb/server/filesystem/FSODescriptor.java +++ b/src/main/java/org/caosdb/server/filesystem/FSODescriptor.java @@ -43,6 +43,7 @@ public class FSODescriptor implements VirtualFSODescriptorInterface { protected List<VirtualFSODescriptorInterface> children; private RealFSODescriptorInterface twin; private EntityID linkTarget = null; + private boolean isImport = false; public FSODescriptor( final String fileStorageId, @@ -283,4 +284,13 @@ public class FSODescriptor implements VirtualFSODescriptorInterface { result.type = ObjectType.LINK; return result; } + + @Override + public boolean isImport() { + return isImport; + } + + public void setImport(boolean isImport) { + this.isImport = isImport; + } } diff --git a/src/main/java/org/caosdb/server/filesystem/FileStorageInterface.java b/src/main/java/org/caosdb/server/filesystem/FileStorageInterface.java index e2bca5af..90f49e9a 100644 --- a/src/main/java/org/caosdb/server/filesystem/FileStorageInterface.java +++ b/src/main/java/org/caosdb/server/filesystem/FileStorageInterface.java @@ -48,8 +48,10 @@ public interface FileStorageInterface { public abstract Hash getHash(FSODescriptorInterface fso, String algorithm); - /** Return true iff an object with this key exists. */ - public abstract boolean exists(String key); + /** Return true if this object exists. */ + public abstract boolean exists(VirtualFSODescriptorInterface fso); public abstract Iterable<? extends RealFSODescriptorInterface> list(String prefix); + + public abstract RealFSODescriptorInterface resolve(VirtualFSODescriptorInterface fso); } diff --git a/src/main/java/org/caosdb/server/filesystem/FileSystem.java b/src/main/java/org/caosdb/server/filesystem/FileSystem.java index 800a003b..dcd685fd 100644 --- a/src/main/java/org/caosdb/server/filesystem/FileSystem.java +++ b/src/main/java/org/caosdb/server/filesystem/FileSystem.java @@ -84,10 +84,10 @@ public class FileSystem implements FileSystemInterface { // return false; // } - public static Boolean exists(FSODescriptorInterface fso) { + public static Boolean exists(VirtualFSODescriptorInterface fso) { FileStorageInterface fileStorage = getInstance().getFileStorage(fso); if (fileStorage.getCapabilities().existence) { - return fileStorage.exists(fso.getKey()); + return fileStorage.exists(fso); } return null; } @@ -98,6 +98,11 @@ public class FileSystem implements FileSystemInterface { return fileStorage.move(fso, target); } + public RealFSODescriptorInterface resolve(VirtualFSODescriptorInterface fso) { + FileStorageInterface fileStorage = getInstance().getFileStorage(fso); + return fileStorage.resolve(fso); + } + // public static boolean resolve(FSODescriptorInterface fso) { // FileStorageInterface fileStorage = getInstance().getFileStorage(fso); // return fileStorage.resolve(fso); diff --git a/src/main/java/org/caosdb/server/filesystem/LocalFileStorage.java b/src/main/java/org/caosdb/server/filesystem/LocalFileStorage.java index 40836edb..bfc8fe12 100644 --- a/src/main/java/org/caosdb/server/filesystem/LocalFileStorage.java +++ b/src/main/java/org/caosdb/server/filesystem/LocalFileStorage.java @@ -284,6 +284,16 @@ public abstract class LocalFileStorage implements FileStorageInterface { return new LocalFSODescriptor(this, key); } + @Override + public RealFSODescriptorInterface resolve(VirtualFSODescriptorInterface fso) { + String key = fso.getKey(); + if (key == null) { + key = fso.getPath().toString(); + fso.setKey(key); + } + return resolve(key); + } + @Override public Undoable move(final RealFSODescriptorInterface file, VirtualFSODescriptorInterface target) throws Message { @@ -698,7 +708,12 @@ public abstract class LocalFileStorage implements FileStorageInterface { } @Override - public boolean exists(String key) { + public boolean exists(VirtualFSODescriptorInterface fso) { + String key = fso.getKey(); + if (key == null) { + key = fso.getPath().toString(); + fso.setKey(key); + } return !isFree(key); } diff --git a/src/main/java/org/caosdb/server/filesystem/SharedFileStorage.java b/src/main/java/org/caosdb/server/filesystem/SharedFileStorage.java index e66bf2b9..ac47dbd8 100644 --- a/src/main/java/org/caosdb/server/filesystem/SharedFileStorage.java +++ b/src/main/java/org/caosdb/server/filesystem/SharedFileStorage.java @@ -64,7 +64,7 @@ public class SharedFileStorage extends LocalFileStorage { } // known to this fs? - if (!exists(path)) { + if (!exists(getFile(path))) { return null; } diff --git a/src/main/java/org/caosdb/server/filesystem/VirtualFSODescriptorInterface.java b/src/main/java/org/caosdb/server/filesystem/VirtualFSODescriptorInterface.java index f76c997a..4e65b45b 100644 --- a/src/main/java/org/caosdb/server/filesystem/VirtualFSODescriptorInterface.java +++ b/src/main/java/org/caosdb/server/filesystem/VirtualFSODescriptorInterface.java @@ -126,4 +126,6 @@ public interface VirtualFSODescriptorInterface extends FSODescriptorInterface { public abstract Path getLinkTargetPath(); public abstract void setLinkTargetPath(Path target); + + public abstract boolean isImport(); } diff --git a/src/main/java/org/caosdb/server/filesystem/consistency/ConsistencyCheck.java b/src/main/java/org/caosdb/server/filesystem/consistency/ConsistencyCheck.java index b5dd679f..71e1a2cd 100644 --- a/src/main/java/org/caosdb/server/filesystem/consistency/ConsistencyCheck.java +++ b/src/main/java/org/caosdb/server/filesystem/consistency/ConsistencyCheck.java @@ -244,7 +244,7 @@ class RunThroughInternalFileSystem extends ConsistencyCheckStrategy { return null; } - private RealFSODescriptorInterface resolve(FSODescriptorInterface fso) { + private RealFSODescriptorInterface resolve(VirtualFSODescriptorInterface fso) { RealFSODescriptorInterface result = null; result = FileSystem.getInstance().resolve(fso.getFileStorageId(), fso.getKey()); Boolean exists = FileSystem.exists(fso); diff --git a/src/main/java/org/caosdb/server/jobs/FilesJob.java b/src/main/java/org/caosdb/server/jobs/FilesJob.java index f769481c..70b099ea 100644 --- a/src/main/java/org/caosdb/server/jobs/FilesJob.java +++ b/src/main/java/org/caosdb/server/jobs/FilesJob.java @@ -22,8 +22,11 @@ */ package org.caosdb.server.jobs; +import org.caosdb.server.entity.Message; +import org.caosdb.server.filesystem.FileSystem; import org.caosdb.server.filesystem.RealFSODescriptorInterface; import org.caosdb.server.filesystem.VirtualFSODescriptorInterface; +import org.caosdb.server.utils.ServerMessages; public abstract class FilesJob extends EntityJob { @@ -32,11 +35,23 @@ public abstract class FilesJob extends EntityJob { * * @param tmpFileId * @return + * @throws Message */ - protected RealFSODescriptorInterface getRealFSODescriptor(VirtualFSODescriptorInterface fso) { + protected RealFSODescriptorInterface getRealFSODescriptor(VirtualFSODescriptorInterface fso) + throws Message { if (fso.getTwin() != null) { return fso.getTwin(); } + if (fso.isImport()) { + if (FileSystem.exists(getEntity().getFSODescriptor())) { + RealFSODescriptorInterface twin = + FileSystem.getInstance().resolve(getEntity().getFSODescriptor()); + getEntity().getFSODescriptor().setTwin(twin); + return twin; + } else if (getEntity().getFSODescriptor().isImport()) { + throw ServerMessages.FILE_IMPORT_FAILED_FILE_DOES_NOT_EXIST; + } + } return getContainer().getFiles().get(fso.getTmpIdentifier()); } } diff --git a/src/main/java/org/caosdb/server/jobs/core/CheckTargetPathValid.java b/src/main/java/org/caosdb/server/jobs/core/CheckTargetPathValid.java index 6d381553..60e5ddd5 100644 --- a/src/main/java/org/caosdb/server/jobs/core/CheckTargetPathValid.java +++ b/src/main/java/org/caosdb/server/jobs/core/CheckTargetPathValid.java @@ -23,6 +23,7 @@ package org.caosdb.server.jobs.core; import org.caosdb.server.database.backend.transaction.CheckTargetPath; +import org.caosdb.server.filesystem.FileSystem; import org.caosdb.server.filesystem.VirtualFSODescriptorInterface; import org.caosdb.server.jobs.FilesJob; import org.caosdb.server.utils.EntityStatus; @@ -51,6 +52,15 @@ public class CheckTargetPathValid extends FilesJob { // check that target path is not owned by another entity. final CheckTargetPath t = new CheckTargetPath(getEntity(), getContainer()); execute(t); + + // check if the fso exists in the file storage + if (FileSystem.exists(getEntity().getFSODescriptor())) { + if (getEntity().getFSODescriptor().isImport()) { + // ok? + } else { + // is update? + } + } } } } diff --git a/src/main/java/org/caosdb/server/utils/ServerMessages.java b/src/main/java/org/caosdb/server/utils/ServerMessages.java index ed048f3c..25d52bc0 100644 --- a/src/main/java/org/caosdb/server/utils/ServerMessages.java +++ b/src/main/java/org/caosdb/server/utils/ServerMessages.java @@ -168,6 +168,12 @@ public class ServerMessages { MessageCode.MESSAGE_CODE_FILE_HAS_NOT_BEEN_UPLOAED, "File has not been uploaded."); + public static final Message FILE_IMPORT_FAILED_FILE_DOES_NOT_EXIST = + new Message( + MessageType.Error, + MessageCode.MESSAGE_CODE_UNKNOWN, + "This file does not exist. It cannot be imported."); + public static final Message CANNOT_MOVE_FILE_TO_TARGET_PATH = new Message( MessageType.Error, -- GitLab