Mercurial > hg > orthanc-object-storage
changeset 78:d7295e8678d7
renames
author | Alain Mazy <am@osimis.io> |
---|---|
date | Fri, 14 Oct 2022 11:00:18 +0200 |
parents | 80792bb9600e |
children | 16514270d9ca |
files | Aws/AwsS3StoragePlugin.cpp Aws/AwsS3StoragePlugin.h Aws/CMakeLists.txt Azure/AzureBlobStoragePlugin.cpp Azure/AzureBlobStoragePlugin.h Azure/CMakeLists.txt Common/BaseStorage.cpp Common/BaseStorage.h Common/BaseStoragePlugin.cpp Common/BaseStoragePlugin.h Common/FileSystemStorage.cpp Common/FileSystemStorage.h Common/FileSystemStoragePlugin.cpp Common/FileSystemStoragePlugin.h Common/IStorage.h Common/IStoragePlugin.h Common/StoragePlugin.cpp Google/CMakeLists.txt Google/GoogleStoragePlugin.cpp Google/GoogleStoragePlugin.h |
diffstat | 20 files changed, 531 insertions(+), 576 deletions(-) [+] |
line wrap: on
line diff
--- a/Aws/AwsS3StoragePlugin.cpp Fri Oct 14 10:36:02 2022 +0200 +++ b/Aws/AwsS3StoragePlugin.cpp Fri Oct 14 11:00:18 2022 +0200 @@ -35,7 +35,7 @@ const char* ALLOCATION_TAG = "OrthancS3"; -class AwsS3StoragePlugin : public BaseStoragePlugin +class AwsS3StoragePlugin : public BaseStorage { public: @@ -55,7 +55,7 @@ }; -class Writer : public IStoragePlugin::IWriter +class Writer : public IStorage::IWriter { std::string path_; Aws::S3::S3Client client_; @@ -99,7 +99,7 @@ }; -class Reader : public IStoragePlugin::IReader +class Reader : public IStorage::IReader { Aws::S3::S3Client client_; std::string bucketName_; @@ -258,7 +258,7 @@ static std::unique_ptr<Aws::SDKOptions> sdkOptions_; -IStoragePlugin* AwsS3StoragePluginFactory::CreateStoragePlugin(const std::string& nameForLogs, const OrthancPlugins::OrthancConfiguration& orthancConfig) +IStorage* AwsS3StoragePluginFactory::CreateStorage(const std::string& nameForLogs, const OrthancPlugins::OrthancConfiguration& orthancConfig) { if (sdkOptions_.get() != NULL) { @@ -285,7 +285,7 @@ OrthancPlugins::OrthancConfiguration pluginSection; orthancConfig.GetSection(pluginSection, GetConfigurationSectionName()); - if (!BaseStoragePlugin::ReadCommonConfiguration(enableLegacyStorageStructure, storageContainsUnknownFiles, pluginSection)) + if (!BaseStorage::ReadCommonConfiguration(enableLegacyStorageStructure, storageContainsUnknownFiles, pluginSection)) { return nullptr; } @@ -376,19 +376,19 @@ AwsS3StoragePlugin::AwsS3StoragePlugin(const std::string& nameForLogs, const Aws::S3::S3Client& client, const std::string& bucketName, bool enableLegacyStorageStructure, bool storageContainsUnknownFiles) - : BaseStoragePlugin(nameForLogs, enableLegacyStorageStructure), + : BaseStorage(nameForLogs, enableLegacyStorageStructure), client_(client), bucketName_(bucketName), storageContainsUnknownFiles_(storageContainsUnknownFiles) { } -IStoragePlugin::IWriter* AwsS3StoragePlugin::GetWriterForObject(const char* uuid, OrthancPluginContentType type, bool encryptionEnabled) +IStorage::IWriter* AwsS3StoragePlugin::GetWriterForObject(const char* uuid, OrthancPluginContentType type, bool encryptionEnabled) { return new Writer(client_, bucketName_, GetPath(uuid, type, encryptionEnabled)); } -IStoragePlugin::IReader* AwsS3StoragePlugin::GetReaderForObject(const char* uuid, OrthancPluginContentType type, bool encryptionEnabled) +IStorage::IReader* AwsS3StoragePlugin::GetReaderForObject(const char* uuid, OrthancPluginContentType type, bool encryptionEnabled) { std::list<std::string> paths; paths.push_back(GetPath(uuid, type, encryptionEnabled, false));
--- a/Aws/AwsS3StoragePlugin.h Fri Oct 14 10:36:02 2022 +0200 +++ b/Aws/AwsS3StoragePlugin.h Fri Oct 14 11:00:18 2022 +0200 @@ -18,13 +18,13 @@ #pragma once -#include "../Common/BaseStoragePlugin.h" +#include "../Common/BaseStorage.h" class AwsS3StoragePluginFactory { public: static const char* GetStoragePluginName(); - static IStoragePlugin* CreateStoragePlugin(const std::string& nameForLogs, const OrthancPlugins::OrthancConfiguration& orthancConfig); + static IStorage* CreateStorage(const std::string& nameForLogs, const OrthancPlugins::OrthancConfiguration& orthancConfig); static const char* GetConfigurationSectionName() {return "AwsS3Storage";} };
--- a/Aws/CMakeLists.txt Fri Oct 14 10:36:02 2022 +0200 +++ b/Aws/CMakeLists.txt Fri Oct 14 11:00:18 2022 +0200 @@ -122,15 +122,15 @@ set(COMMON_SOURCES - ${CMAKE_SOURCE_DIR}/../Common/IStoragePlugin.h - ${CMAKE_SOURCE_DIR}/../Common/BaseStoragePlugin.h - ${CMAKE_SOURCE_DIR}/../Common/BaseStoragePlugin.cpp + ${CMAKE_SOURCE_DIR}/../Common/IStorage.h + ${CMAKE_SOURCE_DIR}/../Common/BaseStorage.h + ${CMAKE_SOURCE_DIR}/../Common/BaseStorage.cpp ${CMAKE_SOURCE_DIR}/../Common/EncryptionHelpers.cpp ${CMAKE_SOURCE_DIR}/../Common/EncryptionHelpers.h ${CMAKE_SOURCE_DIR}/../Common/EncryptionConfigurator.cpp ${CMAKE_SOURCE_DIR}/../Common/EncryptionConfigurator.h - ${CMAKE_SOURCE_DIR}/../Common/FileSystemStoragePlugin.h - ${CMAKE_SOURCE_DIR}/../Common/FileSystemStoragePlugin.cpp + ${CMAKE_SOURCE_DIR}/../Common/FileSystemStorage.h + ${CMAKE_SOURCE_DIR}/../Common/FileSystemStorage.cpp ${CMAKE_SOURCE_DIR}/../Common/Resources/Orthanc/Plugins/OrthancPluginCppWrapper.cpp ${AWS_SOURCES}
--- a/Azure/AzureBlobStoragePlugin.cpp Fri Oct 14 10:36:02 2022 +0200 +++ b/Azure/AzureBlobStoragePlugin.cpp Fri Oct 14 11:00:18 2022 +0200 @@ -31,7 +31,7 @@ namespace as = azure::storage; static const char* const PLUGIN_SECTION = "AzureBlobStorage"; -class AzureBlobStoragePlugin : public BaseStoragePlugin +class AzureBlobStoragePlugin : public BaseStorage { public: @@ -54,7 +54,7 @@ }; -class Writer : public IStoragePlugin::IWriter +class Writer : public IStorage::IWriter { std::string path_; as::cloud_blob_client client_; @@ -89,7 +89,7 @@ }; -class Reader : public IStoragePlugin::IReader +class Reader : public IStorage::IReader { std::string path_; as::cloud_blob_client client_; @@ -196,7 +196,7 @@ return false; } -IStoragePlugin* AzureBlobStoragePluginFactory::CreateStoragePlugin(const OrthancPlugins::OrthancConfiguration& orthancConfig) +IStorage* AzureBlobStoragePluginFactory::CreateStorage(const OrthancPlugins::OrthancConfiguration& orthancConfig) { std::string connectionString; std::string containerName; @@ -209,7 +209,7 @@ OrthancPlugins::OrthancConfiguration pluginSection; orthancConfig.GetSection(pluginSection, PLUGIN_SECTION); - if (!BaseStoragePlugin::ReadCommonConfiguration(enableLegacyStorageStructure, storageContainsUnknownFiles, pluginSection)) + if (!BaseStorage::ReadCommonConfiguration(enableLegacyStorageStructure, storageContainsUnknownFiles, pluginSection)) { return nullptr; } @@ -314,7 +314,7 @@ } AzureBlobStoragePlugin::AzureBlobStoragePlugin(const as::cloud_blob_client& blobClient, const as::cloud_blob_container& blobContainer, bool enableLegacyStorageStructure, bool storageContainsUnknownFiles) - : BaseStoragePlugin(enableLegacyStorageStructure), + : BaseStorage(enableLegacyStorageStructure), blobClient_(blobClient), blobContainer_(blobContainer), storageContainsUnknownFiles_(storageContainsUnknownFiles) @@ -322,12 +322,12 @@ } -IStoragePlugin::IWriter* AzureBlobStoragePlugin::GetWriterForObject(const char* uuid, OrthancPluginContentType type, bool encryptionEnabled) +IStorage::IWriter* AzureBlobStoragePlugin::GetWriterForObject(const char* uuid, OrthancPluginContentType type, bool encryptionEnabled) { return new Writer(blobContainer_, GetPath(uuid, type, encryptionEnabled), blobClient_); } -IStoragePlugin::IReader* AzureBlobStoragePlugin::GetReaderForObject(const char* uuid, OrthancPluginContentType type, bool encryptionEnabled) +IStorage::IReader* AzureBlobStoragePlugin::GetReaderForObject(const char* uuid, OrthancPluginContentType type, bool encryptionEnabled) { std::list<std::string> paths; paths.push_back(GetPath(uuid, type, encryptionEnabled, false));
--- a/Azure/AzureBlobStoragePlugin.h Fri Oct 14 10:36:02 2022 +0200 +++ b/Azure/AzureBlobStoragePlugin.h Fri Oct 14 11:00:18 2022 +0200 @@ -19,11 +19,11 @@ #pragma once -#include "../Common/BaseStoragePlugin.h" +#include "../Common/BaseStorage.h" class AzureBlobStoragePluginFactory { public: static const char* GetStoragePluginName(); - static IStoragePlugin* CreateStoragePlugin(const OrthancPlugins::OrthancConfiguration& orthancConfig); + static IStorage* CreateStorage(const OrthancPlugins::OrthancConfiguration& orthancConfig); };
--- a/Azure/CMakeLists.txt Fri Oct 14 10:36:02 2022 +0200 +++ b/Azure/CMakeLists.txt Fri Oct 14 11:00:18 2022 +0200 @@ -86,15 +86,15 @@ endif() set(COMMON_SOURCES - ${CMAKE_SOURCE_DIR}/../Common/IStoragePlugin.h - ${CMAKE_SOURCE_DIR}/../Common/BaseStoragePlugin.h - ${CMAKE_SOURCE_DIR}/../Common/BaseStoragePlugin.cpp + ${CMAKE_SOURCE_DIR}/../Common/IStorage.h + ${CMAKE_SOURCE_DIR}/../Common/BaseStorage.h + ${CMAKE_SOURCE_DIR}/../Common/BaseStorage.cpp ${CMAKE_SOURCE_DIR}/../Common/EncryptionHelpers.cpp ${CMAKE_SOURCE_DIR}/../Common/EncryptionHelpers.h ${CMAKE_SOURCE_DIR}/../Common/EncryptionConfigurator.cpp ${CMAKE_SOURCE_DIR}/../Common/EncryptionConfigurator.h - ${CMAKE_SOURCE_DIR}/../Common/FileSystemStoragePlugin.h - ${CMAKE_SOURCE_DIR}/../Common/FileSystemStoragePlugin.cpp + ${CMAKE_SOURCE_DIR}/../Common/FileSystemStorage.h + ${CMAKE_SOURCE_DIR}/../Common/FileSystemStorage.cpp ${ORTHANC_FRAMEWORK_ROOT}/../../OrthancServer/Plugins/Samples/Common/OrthancPluginCppWrapper.cpp ${ORTHANC_CORE_SOURCES}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Common/BaseStorage.cpp Fri Oct 14 11:00:18 2022 +0200 @@ -0,0 +1,95 @@ +/** + * Cloud storage plugins for Orthanc + * Copyright (C) 2020-2021 Osimis S.A., Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + **/ + + +#include "BaseStorage.h" +#include <boost/filesystem/fstream.hpp> + +boost::filesystem::path BaseStorage::GetOrthancFileSystemPath(const std::string& uuid, const std::string& fileSystemRootPath) +{ + boost::filesystem::path path = fileSystemRootPath; + + path /= std::string(&uuid[0], &uuid[2]); + path /= std::string(&uuid[2], &uuid[4]); + path /= uuid; + + path.make_preferred(); + + return path; +} + + +std::string BaseStorage::GetPath(const char* uuid, OrthancPluginContentType type, bool encryptionEnabled, bool useAlternateExtension) +{ + if (enableLegacyStorageStructure_) + { + return GetOrthancFileSystemPath(uuid, rootPath_).string(); + } + else + { + boost::filesystem::path path = rootPath_; + std::string filename = std::string(uuid); + + if (type == OrthancPluginContentType_Dicom) + { + filename += ".dcm"; + } + else if (type == OrthancPluginContentType_DicomAsJson) + { + filename += ".json"; + } + else if (type == OrthancPluginContentType_DicomUntilPixelData && !useAlternateExtension) // for some time, header files were saved with .unk (happened with S3 storage plugin between version 1.2.0 and 1.3.0 - 21.5.1 and 21.6.2) + { + filename += ".dcm.head"; + } + else + { + filename += ".unk"; + } + + if (encryptionEnabled) + { + filename += ".enc"; + } + path /= filename; + + return path.string(); + } +} + +bool BaseStorage::ReadCommonConfiguration(bool& enableLegacyStorageStructure, bool& storageContainsUnknownFiles, const OrthancPlugins::OrthancConfiguration& pluginSection) +{ + std::string storageStructure = pluginSection.GetStringValue("StorageStructure", "flat"); + if (storageStructure == "flat") + { + enableLegacyStorageStructure = false; + } + else + { + enableLegacyStorageStructure = true; + if (storageStructure != "legacy") + { + OrthancPlugins::LogError("ObjectStorage/StorageStructure configuration invalid value: " + storageStructure + ", allowed values are 'flat' and 'legacy'"); + return false; + } + } + + storageContainsUnknownFiles = pluginSection.GetBooleanValue("EnableLegacyUnknownFiles", false); + + return true; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Common/BaseStorage.h Fri Oct 14 11:00:18 2022 +0200 @@ -0,0 +1,51 @@ +/** + * Cloud storage plugins for Orthanc + * Copyright (C) 2020-2021 Osimis S.A., Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + **/ + + +#pragma once + +#include "IStorage.h" +#include <boost/filesystem.hpp> + +namespace fs = boost::filesystem; + +class BaseStorage : public IStorage +{ + bool enableLegacyStorageStructure_; + std::string rootPath_; + +protected: + + BaseStorage(const std::string& nameForLogs, bool enableLegacyStorageStructure): + IStorage(nameForLogs), + enableLegacyStorageStructure_(enableLegacyStorageStructure) + {} + + std::string GetPath(const char* uuid, OrthancPluginContentType type, bool encryptionEnabled, bool useAlternateExtension = false); + +public: + virtual void SetRootPath(const std::string& rootPath) + { + rootPath_ = rootPath; + } + + static std::string GetPath(const char* uuid, OrthancPluginContentType type, bool encryptionEnabled, bool legacyFileStructure, const std::string& rootFolder); + static fs::path GetOrthancFileSystemPath(const std::string& uuid, const std::string& fileSystemRootPath); + + static bool ReadCommonConfiguration(bool& enableLegacyStorageStructure, bool& storageContainsUnknownFiles, const OrthancPlugins::OrthancConfiguration& pluginSection); +};
--- a/Common/BaseStoragePlugin.cpp Fri Oct 14 10:36:02 2022 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,95 +0,0 @@ -/** - * Cloud storage plugins for Orthanc - * Copyright (C) 2020-2021 Osimis S.A., Belgium - * - * This program is free software: you can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License - * as published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - **/ - - -#include "BaseStoragePlugin.h" -#include <boost/filesystem/fstream.hpp> - -boost::filesystem::path BaseStoragePlugin::GetOrthancFileSystemPath(const std::string& uuid, const std::string& fileSystemRootPath) -{ - boost::filesystem::path path = fileSystemRootPath; - - path /= std::string(&uuid[0], &uuid[2]); - path /= std::string(&uuid[2], &uuid[4]); - path /= uuid; - - path.make_preferred(); - - return path; -} - - -std::string BaseStoragePlugin::GetPath(const char* uuid, OrthancPluginContentType type, bool encryptionEnabled, bool useAlternateExtension) -{ - if (enableLegacyStorageStructure_) - { - return GetOrthancFileSystemPath(uuid, rootPath_).string(); - } - else - { - boost::filesystem::path path = rootPath_; - std::string filename = std::string(uuid); - - if (type == OrthancPluginContentType_Dicom) - { - filename += ".dcm"; - } - else if (type == OrthancPluginContentType_DicomAsJson) - { - filename += ".json"; - } - else if (type == OrthancPluginContentType_DicomUntilPixelData && !useAlternateExtension) // for some time, header files were saved with .unk (happened with S3 storage plugin between version 1.2.0 and 1.3.0 - 21.5.1 and 21.6.2) - { - filename += ".dcm.head"; - } - else - { - filename += ".unk"; - } - - if (encryptionEnabled) - { - filename += ".enc"; - } - path /= filename; - - return path.string(); - } -} - -bool BaseStoragePlugin::ReadCommonConfiguration(bool& enableLegacyStorageStructure, bool& storageContainsUnknownFiles, const OrthancPlugins::OrthancConfiguration& pluginSection) -{ - std::string storageStructure = pluginSection.GetStringValue("StorageStructure", "flat"); - if (storageStructure == "flat") - { - enableLegacyStorageStructure = false; - } - else - { - enableLegacyStorageStructure = true; - if (storageStructure != "legacy") - { - OrthancPlugins::LogError("ObjectStorage/StorageStructure configuration invalid value: " + storageStructure + ", allowed values are 'flat' and 'legacy'"); - return false; - } - } - - storageContainsUnknownFiles = pluginSection.GetBooleanValue("EnableLegacyUnknownFiles", false); - - return true; -}
--- a/Common/BaseStoragePlugin.h Fri Oct 14 10:36:02 2022 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,51 +0,0 @@ -/** - * Cloud storage plugins for Orthanc - * Copyright (C) 2020-2021 Osimis S.A., Belgium - * - * This program is free software: you can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License - * as published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - **/ - - -#pragma once - -#include "IStoragePlugin.h" -#include <boost/filesystem.hpp> - -namespace fs = boost::filesystem; - -class BaseStoragePlugin : public IStoragePlugin -{ - bool enableLegacyStorageStructure_; - std::string rootPath_; - -protected: - - BaseStoragePlugin(const std::string& nameForLogs, bool enableLegacyStorageStructure): - IStoragePlugin(nameForLogs), - enableLegacyStorageStructure_(enableLegacyStorageStructure) - {} - - std::string GetPath(const char* uuid, OrthancPluginContentType type, bool encryptionEnabled, bool useAlternateExtension = false); - -public: - virtual void SetRootPath(const std::string& rootPath) - { - rootPath_ = rootPath; - } - - static std::string GetPath(const char* uuid, OrthancPluginContentType type, bool encryptionEnabled, bool legacyFileStructure, const std::string& rootFolder); - static fs::path GetOrthancFileSystemPath(const std::string& uuid, const std::string& fileSystemRootPath); - - static bool ReadCommonConfiguration(bool& enableLegacyStorageStructure, bool& storageContainsUnknownFiles, const OrthancPlugins::OrthancConfiguration& pluginSection); -};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Common/FileSystemStorage.cpp Fri Oct 14 11:00:18 2022 +0200 @@ -0,0 +1,149 @@ +/** + * Cloud storage plugins for Orthanc + * Copyright (C) 2020-2021 Osimis S.A., Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + **/ + +#include "FileSystemStorage.h" +#include "BaseStorage.h" + +#include <SystemToolbox.h> +#include <boost/filesystem.hpp> +#include <boost/filesystem/fstream.hpp> + +namespace fs = boost::filesystem; + +void FileSystemStoragePlugin::FileSystemWriter::Write(const char* data, size_t size) +{ + Orthanc::SystemToolbox::MakeDirectory(path_.parent_path().string()); + + Orthanc::SystemToolbox::WriteFile(reinterpret_cast<const void*>(data), size, path_.string(), fsync_); +} + +size_t FileSystemStoragePlugin::FileSystemReader::GetSize() +{ + if (!Orthanc::SystemToolbox::IsRegularFile(path_.string())) + { + throw StoragePluginException(std::string("The path does not point to a regular file: ") + path_.string()); + } + + try + { + fs::ifstream f; + f.open(path_.string(), std::ifstream::in | std::ifstream::binary); + if (!f.good()) + { + throw StoragePluginException(std::string("The path does not point to a regular file: ") + path_.string()); + } + + f.seekg(0, std::ios::end); + std::streamsize fileSize = f.tellg(); + f.seekg(0, std::ios::beg); + + f.close(); + + return fileSize; + } + catch (...) + { + throw StoragePluginException(std::string("Unexpected error while reading: ") + path_.string()); + } + +} + +void FileSystemStoragePlugin::FileSystemReader::ReadWhole(char* data, size_t size) +{ + ReadRange(data, size, 0); +} + +void FileSystemStoragePlugin::FileSystemReader::ReadRange(char* data, size_t size, size_t fromOffset) +{ + if (!Orthanc::SystemToolbox::IsRegularFile(path_.string())) + { + throw StoragePluginException(std::string("The path does not point to a regular file: ") + path_.string()); + } + + try + { + fs::ifstream f; + f.open(path_.string(), std::ifstream::in | std::ifstream::binary); + if (!f.good()) + { + throw StoragePluginException(std::string("The path does not point to a regular file: ") + path_.string()); + } + + f.seekg(fromOffset, std::ios::beg); + + f.read(reinterpret_cast<char*>(data), size); + + f.close(); + } + catch (...) + { + throw StoragePluginException(std::string("Unexpected error while reading: ") + path_.string()); + } +} + + + +IStorage::IWriter* FileSystemStoragePlugin::GetWriterForObject(const char* uuid, OrthancPluginContentType type, bool encryptionEnabled) +{ + return new FileSystemWriter(BaseStorage::GetOrthancFileSystemPath(uuid, fileSystemRootPath_), fsync_); +} + +IStorage::IReader* FileSystemStoragePlugin::GetReaderForObject(const char* uuid, OrthancPluginContentType type, bool encryptionEnabled) +{ + return new FileSystemReader(BaseStorage::GetOrthancFileSystemPath(uuid, fileSystemRootPath_)); +} + +void FileSystemStoragePlugin::DeleteObject(const char* uuid, OrthancPluginContentType type, bool encryptionEnabled) +{ + try + { + namespace fs = boost::filesystem; + + fs::path path = BaseStorage::GetOrthancFileSystemPath(uuid, fileSystemRootPath_); + + try + { + fs::remove(path.string()); + } + catch (...) + { + // Ignore the error + } + + // Remove the two parent directories, ignoring the error code if + // these directories are not empty + + try + { + boost::system::error_code err; + fs::remove(path.parent_path().string(), err); + fs::remove(path.parent_path().parent_path().string(), err); + } + catch (...) + { + // Ignore the error + } + } + catch(Orthanc::OrthancException& e) + { + OrthancPlugins::LogError(GetNameForLogs() + ": error while deleting object " + std::string(uuid) + ": " + std::string(e.What())); + } + +} + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Common/FileSystemStorage.h Fri Oct 14 11:00:18 2022 +0200 @@ -0,0 +1,73 @@ +/** + * Cloud storage plugins for Orthanc + * Copyright (C) 2020-2021 Osimis S.A., Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + **/ + + +#pragma once + +#include "IStorage.h" +#include <boost/filesystem.hpp> + +namespace fs = boost::filesystem; + + +class FileSystemStoragePlugin: public IStorage +{ +public: + class FileSystemWriter: public IStorage::IWriter + { + const fs::path path_; + bool fsync_; + public: + FileSystemWriter(const fs::path& path, bool fsync) + : path_(path), + fsync_(fsync) + {} + + virtual ~FileSystemWriter() {} + virtual void Write(const char* data, size_t size); + }; + + class FileSystemReader: public IStorage::IReader + { + const fs::path path_; + public: + FileSystemReader(const fs::path& path) + : path_(path) + {} + + virtual ~FileSystemReader() {} + virtual size_t GetSize(); + virtual void ReadWhole(char* data, size_t size); + virtual void ReadRange(char* data, size_t size, size_t fromOffset); + }; + + std::string fileSystemRootPath_; + bool fsync_; +public: + FileSystemStoragePlugin(const std::string& nameForLogs, const std::string& fileSystemRootPath, bool fsync) + : IStorage(nameForLogs), + fileSystemRootPath_(fileSystemRootPath), + fsync_(fsync) + {} + + virtual void SetRootPath(const std::string& rootPath) {} + + virtual IStorage::IWriter* GetWriterForObject(const char* uuid, OrthancPluginContentType type, bool encryptionEnabled); + virtual IStorage::IReader* GetReaderForObject(const char* uuid, OrthancPluginContentType type, bool encryptionEnabled); + virtual void DeleteObject(const char* uuid, OrthancPluginContentType type, bool encryptionEnabled); +}; \ No newline at end of file
--- a/Common/FileSystemStoragePlugin.cpp Fri Oct 14 10:36:02 2022 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,149 +0,0 @@ -/** - * Cloud storage plugins for Orthanc - * Copyright (C) 2020-2021 Osimis S.A., Belgium - * - * This program is free software: you can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License - * as published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - **/ - -#include "FileSystemStoragePlugin.h" -#include "BaseStoragePlugin.h" - -#include <SystemToolbox.h> -#include <boost/filesystem.hpp> -#include <boost/filesystem/fstream.hpp> - -namespace fs = boost::filesystem; - -void FileSystemStoragePlugin::FileSystemWriter::Write(const char* data, size_t size) -{ - Orthanc::SystemToolbox::MakeDirectory(path_.parent_path().string()); - - Orthanc::SystemToolbox::WriteFile(reinterpret_cast<const void*>(data), size, path_.string(), fsync_); -} - -size_t FileSystemStoragePlugin::FileSystemReader::GetSize() -{ - if (!Orthanc::SystemToolbox::IsRegularFile(path_.string())) - { - throw StoragePluginException(std::string("The path does not point to a regular file: ") + path_.string()); - } - - try - { - fs::ifstream f; - f.open(path_.string(), std::ifstream::in | std::ifstream::binary); - if (!f.good()) - { - throw StoragePluginException(std::string("The path does not point to a regular file: ") + path_.string()); - } - - f.seekg(0, std::ios::end); - std::streamsize fileSize = f.tellg(); - f.seekg(0, std::ios::beg); - - f.close(); - - return fileSize; - } - catch (...) - { - throw StoragePluginException(std::string("Unexpected error while reading: ") + path_.string()); - } - -} - -void FileSystemStoragePlugin::FileSystemReader::ReadWhole(char* data, size_t size) -{ - ReadRange(data, size, 0); -} - -void FileSystemStoragePlugin::FileSystemReader::ReadRange(char* data, size_t size, size_t fromOffset) -{ - if (!Orthanc::SystemToolbox::IsRegularFile(path_.string())) - { - throw StoragePluginException(std::string("The path does not point to a regular file: ") + path_.string()); - } - - try - { - fs::ifstream f; - f.open(path_.string(), std::ifstream::in | std::ifstream::binary); - if (!f.good()) - { - throw StoragePluginException(std::string("The path does not point to a regular file: ") + path_.string()); - } - - f.seekg(fromOffset, std::ios::beg); - - f.read(reinterpret_cast<char*>(data), size); - - f.close(); - } - catch (...) - { - throw StoragePluginException(std::string("Unexpected error while reading: ") + path_.string()); - } -} - - - -IStoragePlugin::IWriter* FileSystemStoragePlugin::GetWriterForObject(const char* uuid, OrthancPluginContentType type, bool encryptionEnabled) -{ - return new FileSystemWriter(BaseStoragePlugin::GetOrthancFileSystemPath(uuid, fileSystemRootPath_), fsync_); -} - -IStoragePlugin::IReader* FileSystemStoragePlugin::GetReaderForObject(const char* uuid, OrthancPluginContentType type, bool encryptionEnabled) -{ - return new FileSystemReader(BaseStoragePlugin::GetOrthancFileSystemPath(uuid, fileSystemRootPath_)); -} - -void FileSystemStoragePlugin::DeleteObject(const char* uuid, OrthancPluginContentType type, bool encryptionEnabled) -{ - try - { - namespace fs = boost::filesystem; - - fs::path path = BaseStoragePlugin::GetOrthancFileSystemPath(uuid, fileSystemRootPath_); - - try - { - fs::remove(path.string()); - } - catch (...) - { - // Ignore the error - } - - // Remove the two parent directories, ignoring the error code if - // these directories are not empty - - try - { - boost::system::error_code err; - fs::remove(path.parent_path().string(), err); - fs::remove(path.parent_path().parent_path().string(), err); - } - catch (...) - { - // Ignore the error - } - } - catch(Orthanc::OrthancException& e) - { - OrthancPlugins::LogError(GetNameForLogs() + ": error while deleting object " + std::string(uuid) + ": " + std::string(e.What())); - } - -} - -
--- a/Common/FileSystemStoragePlugin.h Fri Oct 14 10:36:02 2022 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,73 +0,0 @@ -/** - * Cloud storage plugins for Orthanc - * Copyright (C) 2020-2021 Osimis S.A., Belgium - * - * This program is free software: you can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License - * as published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - **/ - - -#pragma once - -#include "IStoragePlugin.h" -#include <boost/filesystem.hpp> - -namespace fs = boost::filesystem; - - -class FileSystemStoragePlugin: public IStoragePlugin -{ -public: - class FileSystemWriter: public IStoragePlugin::IWriter - { - const fs::path path_; - bool fsync_; - public: - FileSystemWriter(const fs::path& path, bool fsync) - : path_(path), - fsync_(fsync) - {} - - virtual ~FileSystemWriter() {} - virtual void Write(const char* data, size_t size); - }; - - class FileSystemReader: public IStoragePlugin::IReader - { - const fs::path path_; - public: - FileSystemReader(const fs::path& path) - : path_(path) - {} - - virtual ~FileSystemReader() {} - virtual size_t GetSize(); - virtual void ReadWhole(char* data, size_t size); - virtual void ReadRange(char* data, size_t size, size_t fromOffset); - }; - - std::string fileSystemRootPath_; - bool fsync_; -public: - FileSystemStoragePlugin(const std::string& nameForLogs, const std::string& fileSystemRootPath, bool fsync) - : IStoragePlugin(nameForLogs), - fileSystemRootPath_(fileSystemRootPath), - fsync_(fsync) - {} - - virtual void SetRootPath(const std::string& rootPath) {} - - virtual IStoragePlugin::IWriter* GetWriterForObject(const char* uuid, OrthancPluginContentType type, bool encryptionEnabled); - virtual IStoragePlugin::IReader* GetReaderForObject(const char* uuid, OrthancPluginContentType type, bool encryptionEnabled); - virtual void DeleteObject(const char* uuid, OrthancPluginContentType type, bool encryptionEnabled); -}; \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Common/IStorage.h Fri Oct 14 11:00:18 2022 +0200 @@ -0,0 +1,83 @@ +/** + * Cloud storage plugins for Orthanc + * Copyright (C) 2020-2021 Osimis S.A., Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + **/ + + +#pragma once + +#include <orthanc/OrthancCPlugin.h> +#include <OrthancPluginCppWrapper.h> + +class StoragePluginException : public std::runtime_error +{ +public: + StoragePluginException(const std::string& what) + : std::runtime_error(what) + { + } +}; + + + + +// each "plugin" must also provide these global methods +//class XXXStoragePluginFactory +//{ +//public: +// const char* GetStoragePluginName(); +// IStorage* CreateStorage(const OrthancPlugins::OrthancConfiguration& orthancConfig); +//}; + +class IStorage +{ +public: + class IWriter + { + public: + IWriter() + {} + + virtual ~IWriter() {} + virtual void Write(const char* data, size_t size) = 0; + }; + + class IReader + { + public: + IReader() + {} + + virtual ~IReader() {} + virtual size_t GetSize() = 0; + virtual void ReadWhole(char* data, size_t size) = 0; + virtual void ReadRange(char* data, size_t size, size_t fromOffset) = 0; + }; + + std::string nameForLogs_; +public: + IStorage(const std::string& nameForLogs): + nameForLogs_(nameForLogs) + {} + + virtual void SetRootPath(const std::string& rootPath) = 0; + + virtual IWriter* GetWriterForObject(const char* uuid, OrthancPluginContentType type, bool encryptionEnabled) = 0; + virtual IReader* GetReaderForObject(const char* uuid, OrthancPluginContentType type, bool encryptionEnabled) = 0; + virtual void DeleteObject(const char* uuid, OrthancPluginContentType type, bool encryptionEnabled) = 0; // returns true only if 100% sure that the file has been deleted, false otherwise + + const std::string& GetNameForLogs() {return nameForLogs_;} +};
--- a/Common/IStoragePlugin.h Fri Oct 14 10:36:02 2022 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,83 +0,0 @@ -/** - * Cloud storage plugins for Orthanc - * Copyright (C) 2020-2021 Osimis S.A., Belgium - * - * This program is free software: you can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License - * as published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - **/ - - -#pragma once - -#include <orthanc/OrthancCPlugin.h> -#include <OrthancPluginCppWrapper.h> - -class StoragePluginException : public std::runtime_error -{ -public: - StoragePluginException(const std::string& what) - : std::runtime_error(what) - { - } -}; - - - - -// each "plugin" must also provide these global methods -//class XXXStoragePluginFactory -//{ -//public: -// const char* GetStoragePluginName(); -// IStoragePlugin* CreateStoragePlugin(const OrthancPlugins::OrthancConfiguration& orthancConfig); -//}; - -class IStoragePlugin -{ -public: - class IWriter - { - public: - IWriter() - {} - - virtual ~IWriter() {} - virtual void Write(const char* data, size_t size) = 0; - }; - - class IReader - { - public: - IReader() - {} - - virtual ~IReader() {} - virtual size_t GetSize() = 0; - virtual void ReadWhole(char* data, size_t size) = 0; - virtual void ReadRange(char* data, size_t size, size_t fromOffset) = 0; - }; - - std::string nameForLogs_; -public: - IStoragePlugin(const std::string& nameForLogs): - nameForLogs_(nameForLogs) - {} - - virtual void SetRootPath(const std::string& rootPath) = 0; - - virtual IWriter* GetWriterForObject(const char* uuid, OrthancPluginContentType type, bool encryptionEnabled) = 0; - virtual IReader* GetReaderForObject(const char* uuid, OrthancPluginContentType type, bool encryptionEnabled) = 0; - virtual void DeleteObject(const char* uuid, OrthancPluginContentType type, bool encryptionEnabled) = 0; // returns true only if 100% sure that the file has been deleted, false otherwise - - const std::string& GetNameForLogs() {return nameForLogs_;} -};
--- a/Common/StoragePlugin.cpp Fri Oct 14 10:36:02 2022 +0200 +++ b/Common/StoragePlugin.cpp Fri Oct 14 11:00:18 2022 +0200 @@ -40,13 +40,13 @@ #include "../Common/EncryptionHelpers.h" #include "../Common/EncryptionConfigurator.h" -#include "../Common/FileSystemStoragePlugin.h" +#include "../Common/FileSystemStorage.h" #include <Logging.h> #include <SystemToolbox.h> -static std::unique_ptr<IStoragePlugin> primaryPlugin; -static std::unique_ptr<IStoragePlugin> secondaryPlugin; +static std::unique_ptr<IStorage> primaryStorage; +static std::unique_ptr<IStorage> secondaryStorage; static std::unique_ptr<EncryptionHelpers> crypto; static bool cryptoEnabled = false; @@ -84,8 +84,8 @@ { try { - OrthancPlugins::LogInfo(primaryPlugin->GetNameForLogs() + ": creating attachment " + std::string(uuid) + " of type " + boost::lexical_cast<std::string>(type)); - std::unique_ptr<IStoragePlugin::IWriter> writer(primaryPlugin->GetWriterForObject(uuid, type, cryptoEnabled)); + OrthancPlugins::LogInfo(primaryStorage->GetNameForLogs() + ": creating attachment " + std::string(uuid) + " of type " + boost::lexical_cast<std::string>(type)); + std::unique_ptr<IStorage::IWriter> writer(primaryStorage->GetWriterForObject(uuid, type, cryptoEnabled)); if (cryptoEnabled) { @@ -97,7 +97,7 @@ } catch (EncryptionException& ex) { - OrthancPlugins::LogError(primaryPlugin->GetNameForLogs() + ": error while encrypting object " + std::string(uuid) + ": " + ex.what()); + OrthancPlugins::LogError(primaryStorage->GetNameForLogs() + ": error while encrypting object " + std::string(uuid) + ": " + ex.what()); return OrthancPluginErrorCode_StorageAreaPlugin; } @@ -110,7 +110,7 @@ } catch (StoragePluginException& ex) { - OrthancPlugins::LogError(primaryPlugin->GetNameForLogs() + ": error while creating object " + std::string(uuid) + ": " + ex.what()); + OrthancPlugins::LogError(primaryStorage->GetNameForLogs() + ": error while creating object " + std::string(uuid) + ": " + ex.what()); return OrthancPluginErrorCode_StorageAreaPlugin; } @@ -118,7 +118,7 @@ } -static OrthancPluginErrorCode StorageReadRange(IStoragePlugin* plugin, +static OrthancPluginErrorCode StorageReadRange(IStorage* storage, LogErrorFunction logErrorFunction, OrthancPluginMemoryBuffer64* target, // Memory buffer where to store the content of the range. The memory buffer is allocated and freed by Orthanc. The length of the range of interest corresponds to the size of this buffer. const char* uuid, @@ -129,9 +129,9 @@ try { - OrthancPlugins::LogInfo(plugin->GetNameForLogs() + ": reading range of attachment " + std::string(uuid) + " of type " + boost::lexical_cast<std::string>(type)); + OrthancPlugins::LogInfo(storage->GetNameForLogs() + ": reading range of attachment " + std::string(uuid) + " of type " + boost::lexical_cast<std::string>(type)); - std::unique_ptr<IStoragePlugin::IReader> reader(plugin->GetReaderForObject(uuid, type, cryptoEnabled)); + std::unique_ptr<IStorage::IReader> reader(storage->GetReaderForObject(uuid, type, cryptoEnabled)); reader->ReadRange(reinterpret_cast<char*>(target->data), target->size, rangeStart); return OrthancPluginErrorCode_Success; @@ -148,7 +148,7 @@ OrthancPluginContentType type, uint64_t rangeStart) { - OrthancPluginErrorCode res = StorageReadRange(primaryPlugin.get(), + OrthancPluginErrorCode res = StorageReadRange(primaryStorage.get(), (IsHybridModeEnabled() ? OrthancPlugins::LogWarning : OrthancPlugins::LogError), // log errors as warning on first try target, uuid, @@ -157,7 +157,7 @@ if (res != OrthancPluginErrorCode_Success && IsHybridModeEnabled()) { - res = StorageReadRange(secondaryPlugin.get(), + res = StorageReadRange(secondaryStorage.get(), OrthancPlugins::LogError, // log errors as errors on second try target, uuid, @@ -169,7 +169,7 @@ -static OrthancPluginErrorCode StorageReadWhole(IStoragePlugin* plugin, +static OrthancPluginErrorCode StorageReadWhole(IStorage* storage, LogErrorFunction logErrorFunction, OrthancPluginMemoryBuffer64* target, // Memory buffer where to store the content of the file. It must be allocated by the plugin using OrthancPluginCreateMemoryBuffer64(). The core of Orthanc will free it. const char* uuid, @@ -177,8 +177,8 @@ { try { - OrthancPlugins::LogInfo(plugin->GetNameForLogs() + ": reading whole attachment " + std::string(uuid) + " of type " + boost::lexical_cast<std::string>(type)); - std::unique_ptr<IStoragePlugin::IReader> reader(plugin->GetReaderForObject(uuid, type, cryptoEnabled)); + OrthancPlugins::LogInfo(storage->GetNameForLogs() + ": reading whole attachment " + std::string(uuid) + " of type " + boost::lexical_cast<std::string>(type)); + std::unique_ptr<IStorage::IReader> reader(storage->GetReaderForObject(uuid, type, cryptoEnabled)); size_t fileSize = reader->GetSize(); size_t size; @@ -194,13 +194,13 @@ if (size <= 0) { - logErrorFunction(plugin->GetNameForLogs() + ": error while reading object " + std::string(uuid) + ", size of file is too small: " + boost::lexical_cast<std::string>(fileSize) + " bytes"); + logErrorFunction(storage->GetNameForLogs() + ": error while reading object " + std::string(uuid) + ", size of file is too small: " + boost::lexical_cast<std::string>(fileSize) + " bytes"); return OrthancPluginErrorCode_StorageAreaPlugin; } if (OrthancPluginCreateMemoryBuffer64(OrthancPlugins::GetGlobalContext(), target, size) != OrthancPluginErrorCode_Success) { - logErrorFunction(plugin->GetNameForLogs() + ": error while reading object " + std::string(uuid) + ", cannot allocate memory of size " + boost::lexical_cast<std::string>(size) + " bytes"); + logErrorFunction(storage->GetNameForLogs() + ": error while reading object " + std::string(uuid) + ", cannot allocate memory of size " + boost::lexical_cast<std::string>(size) + " bytes"); return OrthancPluginErrorCode_StorageAreaPlugin; } @@ -215,7 +215,7 @@ } catch (EncryptionException& ex) { - logErrorFunction(plugin->GetNameForLogs() + ": error while decrypting object " + std::string(uuid) + ": " + ex.what()); + logErrorFunction(storage->GetNameForLogs() + ": error while decrypting object " + std::string(uuid) + ": " + ex.what()); return OrthancPluginErrorCode_StorageAreaPlugin; } } @@ -226,7 +226,7 @@ } catch (StoragePluginException& ex) { - logErrorFunction(plugin->GetNameForLogs() + ": error while decrypting object " + std::string(uuid) + ": " + ex.what()); + logErrorFunction(storage->GetNameForLogs() + ": error while decrypting object " + std::string(uuid) + ": " + ex.what()); return OrthancPluginErrorCode_StorageAreaPlugin; } @@ -237,7 +237,7 @@ const char* uuid, OrthancPluginContentType type) { - OrthancPluginErrorCode res = StorageReadWhole(primaryPlugin.get(), + OrthancPluginErrorCode res = StorageReadWhole(primaryStorage.get(), (IsHybridModeEnabled() ? OrthancPlugins::LogWarning : OrthancPlugins::LogError), // log errors as warning on first try target, uuid, @@ -245,7 +245,7 @@ if (res != OrthancPluginErrorCode_Success && IsHybridModeEnabled()) { - res = StorageReadWhole(secondaryPlugin.get(), + res = StorageReadWhole(secondaryStorage.get(), OrthancPlugins::LogError, // log errors as errors on second try target, uuid, @@ -272,61 +272,16 @@ } -// static bool StorageRemoveFromDisk(const char* uuid, -// OrthancPluginContentType type) -// { -// try -// { -// namespace fs = boost::filesystem; -// bool fileExisted = false; -// fs::path path = BaseStoragePlugin::GetOrthancFileSystemPath(uuid, fileSystemRootPath); - -// try -// { -// fs::remove(path); -// fileExisted = true; -// } -// catch (...) -// { -// // Ignore the error -// fileExisted = false; -// } - -// // Remove the two parent directories, ignoring the error code if -// // these directories are not empty - -// try -// { -// boost::system::error_code err; -// fs::remove(path.parent_path(), err); -// fs::remove(path.parent_path().parent_path(), err); -// } -// catch (...) -// { -// // Ignore the error -// } - -// return fileExisted; -// } -// catch(Orthanc::OrthancException& e) -// { -// OrthancPlugins::LogError(std::string(StoragePluginFactory::GetStoragePluginName()) + ": error while deleting object " + std::string(uuid) + ": " + std::string(e.What())); -// return false; -// } - -// } - - -static OrthancPluginErrorCode StorageRemove(IStoragePlugin* plugin, +static OrthancPluginErrorCode StorageRemove(IStorage* storage, LogErrorFunction logErrorFunction, const char* uuid, OrthancPluginContentType type) { try { - OrthancPlugins::LogInfo(plugin->GetNameForLogs() + ": deleting attachment " + std::string(uuid) + " of type " + boost::lexical_cast<std::string>(type)); - plugin->DeleteObject(uuid, type, cryptoEnabled); - if ((plugin == primaryPlugin.get()) && IsHybridModeEnabled()) + OrthancPlugins::LogInfo(storage->GetNameForLogs() + ": deleting attachment " + std::string(uuid) + " of type " + boost::lexical_cast<std::string>(type)); + storage->DeleteObject(uuid, type, cryptoEnabled); + if ((storage == primaryStorage.get()) && IsHybridModeEnabled()) { // not 100% sure the file has been deleted, try the secondary plugin return OrthancPluginErrorCode_StorageAreaPlugin; @@ -344,14 +299,14 @@ static OrthancPluginErrorCode StorageRemove(const char* uuid, OrthancPluginContentType type) { - OrthancPluginErrorCode res = StorageRemove(primaryPlugin.get(), + OrthancPluginErrorCode res = StorageRemove(primaryStorage.get(), (IsHybridModeEnabled() ? OrthancPlugins::LogWarning : OrthancPlugins::LogError), // log errors as warning on first try uuid, type); if (res != OrthancPluginErrorCode_Success && IsHybridModeEnabled()) { - res = StorageRemove(secondaryPlugin.get(), + res = StorageRemove(secondaryStorage.get(), OrthancPlugins::LogError, // log errors as errors on second try uuid, type); @@ -443,7 +398,7 @@ objecstStoragePluginName += " (Primary: object-storage)"; } - std::unique_ptr<IStoragePlugin> objectStoragePlugin(StoragePluginFactory::CreateStoragePlugin(objecstStoragePluginName, orthancConfig)); + std::unique_ptr<IStorage> objectStoragePlugin(StoragePluginFactory::CreateStorage(objecstStoragePluginName, orthancConfig)); if (objectStoragePlugin.get() == nullptr) { @@ -452,7 +407,7 @@ objectStoragePlugin->SetRootPath(objectsRootPath); - std::unique_ptr<IStoragePlugin> fileSystemStoragePlugin; + std::unique_ptr<IStorage> fileSystemStoragePlugin; if (IsHybridModeEnabled()) { bool fsync = orthancConfig.GetBooleanValue("SyncStorageArea", true); @@ -472,17 +427,17 @@ if (hybridMode == HybridMode_Disabled || hybridMode == HybridMode_WriteToObjectStorage) { - primaryPlugin.reset(objectStoragePlugin.release()); + primaryStorage.reset(objectStoragePlugin.release()); if (hybridMode == HybridMode_WriteToObjectStorage) { - secondaryPlugin.reset(fileSystemStoragePlugin.release()); + secondaryStorage.reset(fileSystemStoragePlugin.release()); } } else if (hybridMode == HybridMode_WriteToFileSystem) { - primaryPlugin.reset(fileSystemStoragePlugin.release()); - secondaryPlugin.reset(objectStoragePlugin.release()); + primaryStorage.reset(fileSystemStoragePlugin.release()); + secondaryStorage.reset(objectStoragePlugin.release()); } if (pluginSection.IsSection(ENCRYPTION_SECTION)) @@ -529,8 +484,8 @@ ORTHANC_PLUGINS_API void OrthancPluginFinalize() { OrthancPlugins::LogWarning(std::string(StoragePluginFactory::GetStoragePluginName()) + " plugin is finalizing"); - primaryPlugin.reset(); - secondaryPlugin.reset(); + primaryStorage.reset(); + secondaryStorage.reset(); Orthanc::FinalizeFramework(); }
--- a/Google/CMakeLists.txt Fri Oct 14 10:36:02 2022 +0200 +++ b/Google/CMakeLists.txt Fri Oct 14 11:00:18 2022 +0200 @@ -60,15 +60,15 @@ find_package(cryptopp CONFIG REQUIRED) set(COMMON_SOURCES - ${CMAKE_SOURCE_DIR}/../Common/IStoragePlugin.h - ${CMAKE_SOURCE_DIR}/../Common/BaseStoragePlugin.h - ${CMAKE_SOURCE_DIR}/../Common/BaseStoragePlugin.cpp + ${CMAKE_SOURCE_DIR}/../Common/IStorage.h + ${CMAKE_SOURCE_DIR}/../Common/BaseStorage.h + ${CMAKE_SOURCE_DIR}/../Common/BaseStorage.cpp ${CMAKE_SOURCE_DIR}/../Common/EncryptionHelpers.cpp ${CMAKE_SOURCE_DIR}/../Common/EncryptionHelpers.h ${CMAKE_SOURCE_DIR}/../Common/EncryptionConfigurator.cpp ${CMAKE_SOURCE_DIR}/../Common/EncryptionConfigurator.h - ${CMAKE_SOURCE_DIR}/../Common/FileSystemStoragePlugin.h - ${CMAKE_SOURCE_DIR}/../Common/FileSystemStoragePlugin.cpp + ${CMAKE_SOURCE_DIR}/../Common/FileSystemStorage.h + ${CMAKE_SOURCE_DIR}/../Common/FileSystemStorage.cpp ${ORTHANC_FRAMEWORK_ROOT}/../../OrthancServer/Plugins/Samples/Common/OrthancPluginCppWrapper.cpp ${ORTHANC_CORE_SOURCES}
--- a/Google/GoogleStoragePlugin.cpp Fri Oct 14 10:36:02 2022 +0200 +++ b/Google/GoogleStoragePlugin.cpp Fri Oct 14 11:00:18 2022 +0200 @@ -26,7 +26,7 @@ static const char* const PLUGIN_SECTION = "GoogleCloudStorage"; -class GoogleStoragePlugin : public BaseStoragePlugin +class GoogleStoragePlugin : public BaseStorage { public: @@ -49,7 +49,7 @@ }; -class Writer : public IStoragePlugin::IWriter +class Writer : public IStorage::IWriter { std::string path_; gcs::Client client_; @@ -89,7 +89,7 @@ }; -class Reader : public IStoragePlugin::IReader +class Reader : public IStorage::IReader { std::list<std::string> paths_; gcs::Client client_; @@ -234,7 +234,7 @@ return "Google Cloud Storage"; } -IStoragePlugin* GoogleStoragePluginFactory::CreateStoragePlugin(const OrthancPlugins::OrthancConfiguration& orthancConfig) +IStorage* GoogleStoragePluginFactory::CreateStorage(const OrthancPlugins::OrthancConfiguration& orthancConfig) { bool enableLegacyStorageStructure; bool storageContainsUnknownFiles; @@ -248,7 +248,7 @@ OrthancPlugins::OrthancConfiguration pluginSection; orthancConfig.GetSection(pluginSection, PLUGIN_SECTION); - if (!BaseStoragePlugin::ReadCommonConfiguration(enableLegacyStorageStructure, storageContainsUnknownFiles, pluginSection)) + if (!BaseStorage::ReadCommonConfiguration(enableLegacyStorageStructure, storageContainsUnknownFiles, pluginSection)) { return nullptr; } @@ -289,7 +289,7 @@ } GoogleStoragePlugin::GoogleStoragePlugin(const std::string &bucketName, google::cloud::storage::Client& mainClient, bool enableLegacyStorageStructure, bool storageContainsUnknownFiles) - : BaseStoragePlugin(enableLegacyStorageStructure), + : BaseStorage(enableLegacyStorageStructure), bucketName_(bucketName), mainClient_(mainClient), storageContainsUnknownFiles_(storageContainsUnknownFiles) @@ -297,12 +297,12 @@ } -IStoragePlugin::IWriter* GoogleStoragePlugin::GetWriterForObject(const char* uuid, OrthancPluginContentType type, bool encryptionEnabled) +IStorage::IWriter* GoogleStoragePlugin::GetWriterForObject(const char* uuid, OrthancPluginContentType type, bool encryptionEnabled) { return new Writer(bucketName_, GetPath(uuid, type, encryptionEnabled), mainClient_); } -IStoragePlugin::IReader* GoogleStoragePlugin::GetReaderForObject(const char* uuid, OrthancPluginContentType type, bool encryptionEnabled) +IStorage::IReader* GoogleStoragePlugin::GetReaderForObject(const char* uuid, OrthancPluginContentType type, bool encryptionEnabled) { std::list<std::string> paths; paths.push_back(GetPath(uuid, type, encryptionEnabled, false));
--- a/Google/GoogleStoragePlugin.h Fri Oct 14 10:36:02 2022 +0200 +++ b/Google/GoogleStoragePlugin.h Fri Oct 14 11:00:18 2022 +0200 @@ -19,7 +19,7 @@ #pragma once -#include "../Common/BaseStoragePlugin.h" +#include "../Common/BaseStorage.h" #include "google/cloud/storage/client.h" @@ -27,5 +27,5 @@ { public: static const char* GetStoragePluginName(); - static IStoragePlugin* CreateStoragePlugin(const OrthancPlugins::OrthancConfiguration& orthancConfig); + static IStorage* CreateStorage(const OrthancPlugins::OrthancConfiguration& orthancConfig); };