# HG changeset patch # User Sebastien Jodogne # Date 1439801224 -7200 # Node ID e5e975e9b738f9ba0e6336875e990b36f5aac67d # Parent e9325f3ac496cf65e935436f60e99efaf55ff296 refactoring and simplification of StorageAccessor diff -r e9325f3ac496 -r e5e975e9b738 CMakeLists.txt --- a/CMakeLists.txt Fri Aug 14 11:52:03 2015 +0200 +++ b/CMakeLists.txt Mon Aug 17 10:47:04 2015 +0200 @@ -97,8 +97,6 @@ Core/Enumerations.cpp Core/FileStorage/FilesystemStorage.cpp Core/FileStorage/StorageAccessor.cpp - Core/FileStorage/CompressedFileStorageAccessor.cpp - Core/FileStorage/FileStorageAccessor.cpp Core/HttpClient.cpp Core/HttpServer/BufferHttpSender.cpp Core/HttpServer/EmbeddedResourceHttpHandler.cpp diff -r e9325f3ac496 -r e5e975e9b738 Core/FileStorage/CompressedFileStorageAccessor.cpp --- a/Core/FileStorage/CompressedFileStorageAccessor.cpp Fri Aug 14 11:52:03 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,180 +0,0 @@ -/** - * Orthanc - A Lightweight, RESTful DICOM Store - * Copyright (C) 2012-2015 Sebastien Jodogne, Medical Physics - * Department, University Hospital of Liege, Belgium - * - * This program is free software: you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * In addition, as a special exception, the copyright holders of this - * program give permission to link the code of its release with the - * OpenSSL project's "OpenSSL" library (or with modified versions of it - * that use the same license as the "OpenSSL" library), and distribute - * the linked executables. You must obey the GNU General Public License - * in all respects for all of the code used other than "OpenSSL". If you - * modify file(s) with this exception, you may extend this exception to - * your version of the file(s), but you are not obligated to do so. If - * you do not wish to do so, delete this exception statement from your - * version. If you delete this exception statement from all source files - * in the program, then also delete it here. - * - * 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 - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - **/ - - -#include "../PrecompiledHeaders.h" -#include "CompressedFileStorageAccessor.h" - -#include "../HttpServer/BufferHttpSender.h" -#include "../Logging.h" -#include "../OrthancException.h" -#include "../Uuid.h" -#include "FileStorageAccessor.h" - -#include - -namespace Orthanc -{ - FileInfo CompressedFileStorageAccessor::WriteInternal(const void* data, - size_t size, - FileContentType type) - { - std::string uuid = Toolbox::GenerateUuid(); - - std::string md5; - - if (storeMD5_) - { - Toolbox::ComputeMD5(md5, data, size); - } - - switch (compressionType_) - { - case CompressionType_None: - { - GetStorageArea().Create(uuid.c_str(), data, size, type); - return FileInfo(uuid, type, size, md5); - } - - case CompressionType_ZlibWithSize: - { - std::string compressed; - zlib_.Compress(compressed, data, size); - - std::string compressedMD5; - - if (storeMD5_) - { - Toolbox::ComputeMD5(compressedMD5, compressed); - } - - if (compressed.size() > 0) - { - GetStorageArea().Create(uuid.c_str(), &compressed[0], compressed.size(), type); - } - else - { - GetStorageArea().Create(uuid.c_str(), NULL, 0, type); - } - - return FileInfo(uuid, type, size, md5, - CompressionType_ZlibWithSize, compressed.size(), compressedMD5); - } - - default: - throw OrthancException(ErrorCode_NotImplemented); - } - } - - - CompressedFileStorageAccessor::CompressedFileStorageAccessor() : - storage_(NULL), - compressionType_(CompressionType_None) - { - } - - - CompressedFileStorageAccessor::CompressedFileStorageAccessor(IStorageArea& storage) : - storage_(&storage), - compressionType_(CompressionType_None) - { - } - - - IStorageArea& CompressedFileStorageAccessor::GetStorageArea() - { - if (storage_ == NULL) - { - LOG(ERROR) << "No storage area is currently available"; - throw OrthancException(ErrorCode_BadSequenceOfCalls); - } - - return *storage_; - } - - - void CompressedFileStorageAccessor::Read(std::string& content, - const std::string& uuid, - FileContentType type) - { - switch (compressionType_) - { - case CompressionType_None: - GetStorageArea().Read(content, uuid, type); - break; - - case CompressionType_ZlibWithSize: - { - std::string compressed; - GetStorageArea().Read(compressed, uuid, type); - IBufferCompressor::Uncompress(content, zlib_, compressed); - break; - } - - default: - throw OrthancException(ErrorCode_NotImplemented); - } - } - - HttpFileSender* CompressedFileStorageAccessor::ConstructHttpFileSender(const std::string& uuid, - FileContentType type) - { - switch (compressionType_) - { - case CompressionType_None: - { - FileStorageAccessor uncompressedAccessor(GetStorageArea()); - return uncompressedAccessor.ConstructHttpFileSender(uuid, type); - } - - case CompressionType_ZlibWithSize: - { - std::string compressed; - GetStorageArea().Read(compressed, uuid, type); - - std::auto_ptr sender(new BufferHttpSender); - IBufferCompressor::Uncompress(sender->GetBuffer(), zlib_, compressed); - - return sender.release(); - } - - default: - throw OrthancException(ErrorCode_NotImplemented); - } - } - - - void CompressedFileStorageAccessor::Remove(const std::string& uuid, - FileContentType type) - { - GetStorageArea().Remove(uuid, type); - } -} diff -r e9325f3ac496 -r e5e975e9b738 Core/FileStorage/CompressedFileStorageAccessor.h --- a/Core/FileStorage/CompressedFileStorageAccessor.h Fri Aug 14 11:52:03 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,90 +0,0 @@ -/** - * Orthanc - A Lightweight, RESTful DICOM Store - * Copyright (C) 2012-2015 Sebastien Jodogne, Medical Physics - * Department, University Hospital of Liege, Belgium - * - * This program is free software: you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * In addition, as a special exception, the copyright holders of this - * program give permission to link the code of its release with the - * OpenSSL project's "OpenSSL" library (or with modified versions of it - * that use the same license as the "OpenSSL" library), and distribute - * the linked executables. You must obey the GNU General Public License - * in all respects for all of the code used other than "OpenSSL". If you - * modify file(s) with this exception, you may extend this exception to - * your version of the file(s), but you are not obligated to do so. If - * you do not wish to do so, delete this exception statement from your - * version. If you delete this exception statement from all source files - * in the program, then also delete it here. - * - * 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 - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - **/ - - -#pragma once - -#include "IStorageArea.h" -#include "StorageAccessor.h" -#include "../Compression/ZlibCompressor.h" - -namespace Orthanc -{ - class CompressedFileStorageAccessor : public StorageAccessor - { - private: - IStorageArea* storage_; - ZlibCompressor zlib_; - CompressionType compressionType_; - - protected: - virtual FileInfo WriteInternal(const void* data, - size_t size, - FileContentType type); - - public: - CompressedFileStorageAccessor(); - - CompressedFileStorageAccessor(IStorageArea& storage); - - void SetStorageArea(IStorageArea& storage) - { - storage_ = &storage; - } - - bool HasStorageArea() const - { - return storage_ != NULL; - } - - IStorageArea& GetStorageArea(); - - void SetCompressionForNextOperations(CompressionType compression) - { - compressionType_ = compression; - } - - CompressionType GetCompressionForNextOperations() - { - return compressionType_; - } - - virtual void Read(std::string& content, - const std::string& uuid, - FileContentType type); - - virtual HttpFileSender* ConstructHttpFileSender(const std::string& uuid, - FileContentType type); - - virtual void Remove(const std::string& uuid, - FileContentType type); - }; -} diff -r e9325f3ac496 -r e5e975e9b738 Core/FileStorage/FileStorageAccessor.cpp --- a/Core/FileStorage/FileStorageAccessor.cpp Fri Aug 14 11:52:03 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,72 +0,0 @@ -/** - * Orthanc - A Lightweight, RESTful DICOM Store - * Copyright (C) 2012-2015 Sebastien Jodogne, Medical Physics - * Department, University Hospital of Liege, Belgium - * - * This program is free software: you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * In addition, as a special exception, the copyright holders of this - * program give permission to link the code of its release with the - * OpenSSL project's "OpenSSL" library (or with modified versions of it - * that use the same license as the "OpenSSL" library), and distribute - * the linked executables. You must obey the GNU General Public License - * in all respects for all of the code used other than "OpenSSL". If you - * modify file(s) with this exception, you may extend this exception to - * your version of the file(s), but you are not obligated to do so. If - * you do not wish to do so, delete this exception statement from your - * version. If you delete this exception statement from all source files - * in the program, then also delete it here. - * - * 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 - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - **/ - - -#include "../PrecompiledHeaders.h" -#include "FileStorageAccessor.h" - -#include "../HttpServer/BufferHttpSender.h" -#include "../Uuid.h" - -#include -#include - -namespace Orthanc -{ - FileInfo FileStorageAccessor::WriteInternal(const void* data, - size_t size, - FileContentType type) - { - std::string md5; - - if (storeMD5_) - { - Toolbox::ComputeMD5(md5, data, size); - } - - std::string uuid = Toolbox::GenerateUuid(); - storage_.Create(uuid.c_str(), data, size, type); - - return FileInfo(uuid, type, size, md5); - } - - - HttpFileSender* FileStorageAccessor::ConstructHttpFileSender(const std::string& uuid, - FileContentType type) - { - std::auto_ptr sender(new BufferHttpSender); - - storage_.Read(sender->GetBuffer(), uuid, type); - - return sender.release(); - } - -} diff -r e9325f3ac496 -r e5e975e9b738 Core/FileStorage/FileStorageAccessor.h --- a/Core/FileStorage/FileStorageAccessor.h Fri Aug 14 11:52:03 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,71 +0,0 @@ -/** - * Orthanc - A Lightweight, RESTful DICOM Store - * Copyright (C) 2012-2015 Sebastien Jodogne, Medical Physics - * Department, University Hospital of Liege, Belgium - * - * This program is free software: you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * In addition, as a special exception, the copyright holders of this - * program give permission to link the code of its release with the - * OpenSSL project's "OpenSSL" library (or with modified versions of it - * that use the same license as the "OpenSSL" library), and distribute - * the linked executables. You must obey the GNU General Public License - * in all respects for all of the code used other than "OpenSSL". If you - * modify file(s) with this exception, you may extend this exception to - * your version of the file(s), but you are not obligated to do so. If - * you do not wish to do so, delete this exception statement from your - * version. If you delete this exception statement from all source files - * in the program, then also delete it here. - * - * 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 - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - **/ - - -#pragma once - -#include "StorageAccessor.h" -#include "IStorageArea.h" - -namespace Orthanc -{ - class FileStorageAccessor : public StorageAccessor - { - private: - IStorageArea& storage_; - - protected: - virtual FileInfo WriteInternal(const void* data, - size_t size, - FileContentType type); - - public: - FileStorageAccessor(IStorageArea& storage) : storage_(storage) - { - } - - virtual void Read(std::string& content, - const std::string& uuid, - FileContentType type) - { - storage_.Read(content, uuid, type); - } - - virtual HttpFileSender* ConstructHttpFileSender(const std::string& uuid, - FileContentType type); - - virtual void Remove(const std::string& uuid, - FileContentType type) - { - storage_.Remove(uuid, type); - } - }; -} diff -r e9325f3ac496 -r e5e975e9b738 Core/FileStorage/StorageAccessor.cpp --- a/Core/FileStorage/StorageAccessor.cpp Fri Aug 14 11:52:03 2015 +0200 +++ b/Core/FileStorage/StorageAccessor.cpp Mon Aug 17 10:47:04 2015 +0200 @@ -33,31 +33,126 @@ #include "../PrecompiledHeaders.h" #include "StorageAccessor.h" +#include "../Compression/ZlibCompressor.h" +#include "../OrthancException.h" +#include "../HttpServer/HttpStreamTranscoder.h" + namespace Orthanc { - FileInfo StorageAccessor::Write(const std::vector& content, - FileContentType type) + FileInfo StorageAccessor::Write(const void* data, + size_t size, + FileContentType type, + CompressionType compression, + bool storeMd5) { - if (content.size() == 0) + std::string uuid = Toolbox::GenerateUuid(); + + std::string md5; + + if (storeMd5) + { + Toolbox::ComputeMD5(md5, data, size); + } + + switch (compression) { - return WriteInternal(NULL, 0, type); - } - else - { - return WriteInternal(&content[0], content.size(), type); + case CompressionType_None: + { + area_.Create(uuid, data, size, type); + return FileInfo(uuid, type, size, md5); + } + + case CompressionType_ZlibWithSize: + { + ZlibCompressor zlib; + + std::string compressed; + zlib.Compress(compressed, data, size); + + std::string compressedMD5; + + if (storeMd5) + { + Toolbox::ComputeMD5(compressedMD5, compressed); + } + + if (compressed.size() > 0) + { + area_.Create(uuid, &compressed[0], compressed.size(), type); + } + else + { + area_.Create(uuid, NULL, 0, type); + } + + return FileInfo(uuid, type, size, md5, + CompressionType_ZlibWithSize, compressed.size(), compressedMD5); + } + + default: + throw OrthancException(ErrorCode_NotImplemented); } } - FileInfo StorageAccessor::Write(const std::string& content, - FileContentType type) + + void StorageAccessor::Read(std::string& content, + const FileInfo& info) { - if (content.size() == 0) + switch (info.GetCompressionType()) { - return WriteInternal(NULL, 0, type); + case CompressionType_None: + { + area_.Read(content, info.GetUuid(), info.GetContentType()); + break; + } + + case CompressionType_ZlibWithSize: + { + ZlibCompressor zlib; + + std::string compressed; + area_.Read(compressed, info.GetUuid(), info.GetContentType()); + IBufferCompressor::Uncompress(content, zlib, compressed); + break; + } + + default: + { + throw OrthancException(ErrorCode_NotImplemented); + } } - else - { - return WriteInternal(&content[0], content.size(), type); - } + + // TODO Check the validity of the uncompressed MD5? + } + + + void StorageAccessor::SetupSender(BufferHttpSender& sender, + const FileInfo& info) + { + Read(sender.GetBuffer(), info); + sender.SetContentType(GetMimeType(info.GetContentType())); + sender.SetContentFilename(info.GetUuid() + std::string(GetFileExtension(info.GetContentType()))); + } + + + void StorageAccessor::AnswerFile(HttpOutput& output, + const FileInfo& info) + { + BufferHttpSender sender; + SetupSender(sender, info); + + HttpStreamTranscoder transcoder(sender, info.GetCompressionType()); + output.Answer(transcoder); + } + + + void StorageAccessor::AnswerFile(RestApiOutput& output, + const FileInfo& info) + { + BufferHttpSender sender; + SetupSender(sender, info); + + HttpStreamTranscoder transcoder(sender, info.GetCompressionType()); + output.AnswerStream(transcoder); } } diff -r e9325f3ac496 -r e5e975e9b738 Core/FileStorage/StorageAccessor.h --- a/Core/FileStorage/StorageAccessor.h Fri Aug 14 11:52:03 2015 +0200 +++ b/Core/FileStorage/StorageAccessor.h Mon Aug 17 10:47:04 2015 +0200 @@ -32,8 +32,10 @@ #pragma once +#include "IStorageArea.h" #include "FileInfo.h" -#include "../HttpServer/HttpFileSender.h" +#include "../HttpServer/BufferHttpSender.h" +#include "../RestApi/RestApiOutput.h" #include #include @@ -44,54 +46,44 @@ { class StorageAccessor : boost::noncopyable { - protected: - bool storeMD5_; + private: + IStorageArea& area_; - virtual FileInfo WriteInternal(const void* data, - size_t size, - FileContentType type) = 0; + void SetupSender(BufferHttpSender& sender, + const FileInfo& info); public: - StorageAccessor() - { - storeMD5_ = true; - } - - virtual ~StorageAccessor() + StorageAccessor(IStorageArea& area) : area_(area) { } - void SetStoreMD5(bool storeMD5) - { - storeMD5_ = storeMD5; - } - - bool IsStoreMD5() const - { - return storeMD5_; - } - FileInfo Write(const void* data, size_t size, - FileContentType type) + FileContentType type, + CompressionType compression, + bool storeMd5); + + FileInfo Write(const std::string& data, + FileContentType type, + CompressionType compression, + bool storeMd5) { - return WriteInternal(data, size, type); + return Write((data.size() == 0 ? NULL : data.c_str()), + data.size(), type, compression, storeMd5); } - FileInfo Write(const std::vector& content, - FileContentType type); - - FileInfo Write(const std::string& content, - FileContentType type); + void Read(std::string& content, + const FileInfo& info); - virtual void Read(std::string& content, - const std::string& uuid, - FileContentType type) = 0; + void Remove(const FileInfo& info) + { + area_.Remove(info.GetUuid(), info.GetContentType()); + } - virtual void Remove(const std::string& uuid, - FileContentType type) = 0; + void AnswerFile(HttpOutput& output, + const FileInfo& info); - virtual HttpFileSender* ConstructHttpFileSender(const std::string& uuid, - FileContentType type) = 0; + void AnswerFile(RestApiOutput& output, + const FileInfo& info); }; } diff -r e9325f3ac496 -r e5e975e9b738 OrthancServer/ServerContext.cpp --- a/OrthancServer/ServerContext.cpp Fri Aug 14 11:52:03 2015 +0200 +++ b/OrthancServer/ServerContext.cpp Mon Aug 17 10:47:04 2015 +0200 @@ -33,6 +33,7 @@ #include "PrecompiledHeadersServer.h" #include "ServerContext.h" +#include "../Core/FileStorage/StorageAccessor.h" #include "../Core/HttpServer/FilesystemHttpSender.h" #include "../Core/HttpServer/HttpStreamTranscoder.h" #include "../Core/Logging.h" @@ -97,9 +98,12 @@ } - ServerContext::ServerContext(IDatabaseWrapper& database) : + ServerContext::ServerContext(IDatabaseWrapper& database, + IStorageArea& area) : index_(*this, database), + area_(area), compressionEnabled_(false), + storeMD5_(true), provider_(*this), dicomCache_(provider_, DICOM_CACHE_SIZE), scheduler_(Configuration::GetGlobalIntegerParameter("LimitJobs", 10)), @@ -164,10 +168,11 @@ compressionEnabled_ = enabled; } + void ServerContext::RemoveFile(const std::string& fileUuid, FileContentType type) { - accessor_.Remove(fileUuid, type); + area_.Remove(fileUuid, type); } @@ -176,6 +181,8 @@ { try { + StorageAccessor accessor(area_); + DicomInstanceHasher hasher(dicom.GetSummary()); resultPublicId = hasher.HashInstance(); @@ -213,18 +220,13 @@ return StoreStatus_FilteredOut; } - if (compressionEnabled_) - { - // TODO Should we use "gzip" instead? - accessor_.SetCompressionForNextOperations(CompressionType_ZlibWithSize); - } - else - { - accessor_.SetCompressionForNextOperations(CompressionType_None); - } + // TODO Should we use "gzip" instead? + CompressionType compression = (compressionEnabled_ ? CompressionType_ZlibWithSize : CompressionType_None); - FileInfo dicomInfo = accessor_.Write(dicom.GetBufferData(), dicom.GetBufferSize(), FileContentType_Dicom); - FileInfo jsonInfo = accessor_.Write(dicom.GetJson().toStyledString(), FileContentType_DicomAsJson); + FileInfo dicomInfo = accessor.Write(dicom.GetBufferData(), dicom.GetBufferSize(), + FileContentType_Dicom, compression, storeMD5_); + FileInfo jsonInfo = accessor.Write(dicom.GetJson().toStyledString(), + FileContentType_DicomAsJson, compression, storeMD5_); ServerIndex::Attachments attachments; attachments.push_back(dicomInfo); @@ -247,8 +249,8 @@ if (status != StoreStatus_Success) { - accessor_.Remove(dicomInfo.GetUuid(), FileContentType_Dicom); - accessor_.Remove(jsonInfo.GetUuid(), FileContentType_DicomAsJson); + accessor.Remove(dicomInfo); + accessor.Remove(jsonInfo); } switch (status) @@ -314,15 +316,8 @@ throw OrthancException(ErrorCode_InternalError); } - IStorageArea& area = accessor_.GetStorageArea(); - - BufferHttpSender sender; - area.Read(sender.GetBuffer(), attachment.GetUuid(), content); - sender.SetContentType(GetMimeType(content)); - sender.SetContentFilename(attachment.GetUuid() + std::string(GetFileExtension(content))); - - HttpStreamTranscoder transcoder(sender, attachment.GetCompressionType()); - output.AnswerStream(transcoder); + StorageAccessor accessor(area_); + accessor.AnswerFile(output, attachment); } @@ -350,17 +345,9 @@ { throw OrthancException(ErrorCode_InternalError); } - - if (uncompressIfNeeded) - { - accessor_.SetCompressionForNextOperations(attachment.GetCompressionType()); - } - else - { - accessor_.SetCompressionForNextOperations(CompressionType_None); - } - - accessor_.Read(result, attachment.GetUuid(), attachment.GetContentType()); + + StorageAccessor accessor(area_); + accessor.Read(result, attachment); } @@ -395,7 +382,7 @@ void ServerContext::SetStoreMD5ForAttachments(bool storeMD5) { LOG(INFO) << "Storing MD5 for attachments: " << (storeMD5 ? "yes" : "no"); - accessor_.SetStoreMD5(storeMD5); + storeMD5_ = storeMD5; } @@ -406,22 +393,16 @@ { LOG(INFO) << "Adding attachment " << EnumerationToString(attachmentType) << " to resource " << resourceId; - if (compressionEnabled_) - { - // TODO Should we use "gzip" instead? - accessor_.SetCompressionForNextOperations(CompressionType_ZlibWithSize); - } - else - { - accessor_.SetCompressionForNextOperations(CompressionType_None); - } + // TODO Should we use "gzip" instead? + CompressionType compression = (compressionEnabled_ ? CompressionType_ZlibWithSize : CompressionType_None); - FileInfo info = accessor_.Write(data, size, attachmentType); - StoreStatus status = index_.AddAttachment(info, resourceId); + StorageAccessor accessor(area_); + FileInfo attachment = accessor.Write(data, size, attachmentType, compression, storeMD5_); + StoreStatus status = index_.AddAttachment(attachment, resourceId); if (status != StoreStatus_Success) { - accessor_.Remove(info.GetUuid(), info.GetContentType()); + accessor.Remove(attachment); return false; } else diff -r e9325f3ac496 -r e5e975e9b738 OrthancServer/ServerContext.h --- a/OrthancServer/ServerContext.h Fri Aug 14 11:52:03 2015 +0200 +++ b/OrthancServer/ServerContext.h Mon Aug 17 10:47:04 2015 +0200 @@ -35,7 +35,6 @@ #include "../Core/MultiThreading/SharedMessageQueue.h" #include "../Core/Cache/MemoryCache.h" #include "../Core/Cache/SharedArchive.h" -#include "../Core/FileStorage/CompressedFileStorageAccessor.h" #include "../Core/FileStorage/IStorageArea.h" #include "../Core/Lua/LuaContext.h" #include "../Core/RestApi/RestApiOutput.h" @@ -108,8 +107,10 @@ ServerIndex index_; - CompressedFileStorageAccessor accessor_; + IStorageArea& area_; + bool compressionEnabled_; + bool storeMD5_; DicomCacheProvider provider_; boost::mutex dicomCacheMutex_; @@ -150,15 +151,11 @@ } }; - ServerContext(IDatabaseWrapper& database); + ServerContext(IDatabaseWrapper& database, + IStorageArea& area); ~ServerContext(); - void SetStorageArea(IStorageArea& storage) - { - accessor_.SetStorageArea(storage); - } - ServerIndex& GetIndex() { return index_; @@ -199,7 +196,7 @@ bool IsStoreMD5ForAttachments() const { - return accessor_.IsStoreMD5(); + return storeMD5_; } ReusableDicomUserConnection& GetReusableDicomUserConnection() diff -r e9325f3ac496 -r e5e975e9b738 OrthancServer/main.cpp --- a/OrthancServer/main.cpp Fri Aug 14 11:52:03 2015 +0200 +++ b/OrthancServer/main.cpp Mon Aug 17 10:47:04 2015 +0200 @@ -521,8 +521,7 @@ IStorageArea& storageArea, OrthancPlugins *plugins) { - ServerContext context(database); - context.SetStorageArea(storageArea); + ServerContext context(database, storageArea); context.SetCompressionEnabled(Configuration::GetGlobalBoolParameter("StorageCompression", false)); context.SetStoreMD5ForAttachments(Configuration::GetGlobalBoolParameter("StoreMD5ForAttachments", true)); diff -r e9325f3ac496 -r e5e975e9b738 UnitTestsSources/FileStorageTests.cpp --- a/UnitTestsSources/FileStorageTests.cpp Fri Aug 14 11:52:03 2015 +0200 +++ b/UnitTestsSources/FileStorageTests.cpp Mon Aug 17 10:47:04 2015 +0200 @@ -36,15 +36,14 @@ #include #include "../Core/FileStorage/FilesystemStorage.h" -#include "../OrthancServer/ServerIndex.h" +#include "../Core/FileStorage/StorageAccessor.h" +#include "../Core/HttpServer/BufferHttpSender.h" +#include "../Core/HttpServer/FilesystemHttpSender.h" #include "../Core/Logging.h" +#include "../Core/OrthancException.h" #include "../Core/Toolbox.h" -#include "../Core/OrthancException.h" #include "../Core/Uuid.h" -#include "../Core/HttpServer/FilesystemHttpSender.h" -#include "../Core/HttpServer/BufferHttpSender.h" -#include "../Core/FileStorage/FileStorageAccessor.h" -#include "../Core/FileStorage/CompressedFileStorageAccessor.h" +#include "../OrthancServer/ServerIndex.h" using namespace Orthanc; @@ -123,106 +122,64 @@ } -TEST(FileStorageAccessor, Simple) +TEST(StorageAccessor, NoCompression) { FilesystemStorage s("UnitTestsStorage"); - FileStorageAccessor accessor(s); + StorageAccessor accessor(s); std::string data = "Hello world"; - FileInfo info = accessor.Write(data, FileContentType_Dicom); + FileInfo info = accessor.Write(data, FileContentType_Dicom, CompressionType_None, true); std::string r; - accessor.Read(r, info.GetUuid(), FileContentType_Unknown); - - ASSERT_EQ(data, r); - ASSERT_EQ(CompressionType_None, info.GetCompressionType()); - ASSERT_EQ(11u, info.GetUncompressedSize()); - ASSERT_EQ(11u, info.GetCompressedSize()); - ASSERT_EQ(FileContentType_Dicom, info.GetContentType()); -} - - -TEST(FileStorageAccessor, NoCompression) -{ - FilesystemStorage s("UnitTestsStorage"); - CompressedFileStorageAccessor accessor(s); - - accessor.SetCompressionForNextOperations(CompressionType_None); - std::string data = "Hello world"; - FileInfo info = accessor.Write(data, FileContentType_Dicom); - - std::string r; - accessor.Read(r, info.GetUuid(), FileContentType_Unknown); + accessor.Read(r, info); ASSERT_EQ(data, r); ASSERT_EQ(CompressionType_None, info.GetCompressionType()); ASSERT_EQ(11u, info.GetUncompressedSize()); ASSERT_EQ(11u, info.GetCompressedSize()); ASSERT_EQ(FileContentType_Dicom, info.GetContentType()); + ASSERT_EQ("3e25960a79dbc69b674cd4ec67a72c62", info.GetUncompressedMD5()); + ASSERT_EQ(info.GetUncompressedMD5(), info.GetCompressedMD5()); } -TEST(FileStorageAccessor, NoCompression2) +TEST(StorageAccessor, Compression) { FilesystemStorage s("UnitTestsStorage"); - CompressedFileStorageAccessor accessor(s); + StorageAccessor accessor(s); - accessor.SetCompressionForNextOperations(CompressionType_None); - std::vector data; - StringToVector(data, "Hello world"); - FileInfo info = accessor.Write(data, FileContentType_Dicom); + std::string data = "Hello world"; + FileInfo info = accessor.Write(data, FileContentType_DicomAsJson, CompressionType_ZlibWithSize, true); std::string r; - accessor.Read(r, info.GetUuid(), FileContentType_Unknown); - - ASSERT_EQ(0, memcmp(&r[0], &data[0], data.size())); - ASSERT_EQ(CompressionType_None, info.GetCompressionType()); - ASSERT_EQ(11u, info.GetUncompressedSize()); - ASSERT_EQ(11u, info.GetCompressedSize()); - ASSERT_EQ(FileContentType_Dicom, info.GetContentType()); -} - - -TEST(FileStorageAccessor, Compression) -{ - FilesystemStorage s("UnitTestsStorage"); - CompressedFileStorageAccessor accessor(s); - - accessor.SetCompressionForNextOperations(CompressionType_ZlibWithSize); - std::string data = "Hello world"; - FileInfo info = accessor.Write(data, FileContentType_Dicom); - - std::string r; - accessor.Read(r, info.GetUuid(), FileContentType_Unknown); + accessor.Read(r, info); ASSERT_EQ(data, r); ASSERT_EQ(CompressionType_ZlibWithSize, info.GetCompressionType()); ASSERT_EQ(11u, info.GetUncompressedSize()); - ASSERT_EQ(FileContentType_Dicom, info.GetContentType()); + ASSERT_EQ(FileContentType_DicomAsJson, info.GetContentType()); + ASSERT_EQ("3e25960a79dbc69b674cd4ec67a72c62", info.GetUncompressedMD5()); + ASSERT_NE(info.GetUncompressedMD5(), info.GetCompressedMD5()); } -TEST(FileStorageAccessor, Mix) +TEST(StorageAccessor, Mix) { FilesystemStorage s("UnitTestsStorage"); - CompressedFileStorageAccessor accessor(s); + StorageAccessor accessor(s); std::string r; std::string compressedData = "Hello"; std::string uncompressedData = "HelloWorld"; - accessor.SetCompressionForNextOperations(CompressionType_ZlibWithSize); - FileInfo compressedInfo = accessor.Write(compressedData, FileContentType_Dicom); + FileInfo compressedInfo = accessor.Write(compressedData, FileContentType_Dicom, CompressionType_ZlibWithSize, false); + FileInfo uncompressedInfo = accessor.Write(uncompressedData, FileContentType_Dicom, CompressionType_None, false); - accessor.SetCompressionForNextOperations(CompressionType_None); - FileInfo uncompressedInfo = accessor.Write(uncompressedData, FileContentType_Dicom); - - accessor.SetCompressionForNextOperations(CompressionType_ZlibWithSize); - accessor.Read(r, compressedInfo.GetUuid(), FileContentType_Unknown); + accessor.Read(r, compressedInfo); ASSERT_EQ(compressedData, r); - accessor.SetCompressionForNextOperations(CompressionType_None); - accessor.Read(r, compressedInfo.GetUuid(), FileContentType_Unknown); + accessor.Read(r, uncompressedInfo); + ASSERT_EQ(uncompressedData, r); ASSERT_NE(compressedData, r); /* diff -r e9325f3ac496 -r e5e975e9b738 UnitTestsSources/ServerIndexTests.cpp --- a/UnitTestsSources/ServerIndexTests.cpp Fri Aug 14 11:52:03 2015 +0200 +++ b/UnitTestsSources/ServerIndexTests.cpp Mon Aug 17 10:47:04 2015 +0200 @@ -660,8 +660,7 @@ Toolbox::RemoveFile(path + "/index"); FilesystemStorage storage(path); DatabaseWrapper db; // The SQLite DB is in memory - ServerContext context(db); - context.SetStorageArea(storage); + ServerContext context(db, storage); ServerIndex& index = context.GetIndex(); ASSERT_EQ(1u, index.IncrementGlobalSequence(GlobalProperty_AnonymizationSequence)); @@ -729,8 +728,7 @@ Toolbox::RemoveFile(path + "/index"); FilesystemStorage storage(path); DatabaseWrapper db; // The SQLite DB is in memory - ServerContext context(db); - context.SetStorageArea(storage); + ServerContext context(db, storage); ServerIndex& index = context.GetIndex(); index.SetMaximumStorageSize(10);