# HG changeset patch # User Sebastien Jodogne # Date 1354224120 -3600 # Node ID 4eb0c7ce86c9784b738a1523c2a06efedaec4eb8 # Parent 6f0e4a8ebb0f1f2d2a3b9e48c565b95af2df7d4f refactoring for store diff -r 6f0e4a8ebb0f -r 4eb0c7ce86c9 CMakeLists.txt --- a/CMakeLists.txt Thu Nov 29 18:07:50 2012 +0100 +++ b/CMakeLists.txt Thu Nov 29 22:22:00 2012 +0100 @@ -146,6 +146,7 @@ OrthancServer/ServerIndex.cpp OrthancServer/ToDcmtkBridge.cpp OrthancServer/DatabaseWrapper.cpp + OrthancServer/ServerContext.cpp OrthancServer/ServerEnumerations.cpp OrthancServer/ServerToolbox.cpp ) diff -r 6f0e4a8ebb0f -r 4eb0c7ce86c9 OrthancServer/OrthancRestApi2.cpp --- a/OrthancServer/OrthancRestApi2.cpp Thu Nov 29 18:07:50 2012 +0100 +++ b/OrthancServer/OrthancRestApi2.cpp Thu Nov 29 22:22:00 2012 +0100 @@ -45,7 +45,7 @@ #define RETRIEVE_CONTEXT(call) \ - OrthancRestApi2& context = dynamic_cast(call.GetContext()) + ServerContext& context = dynamic_cast(call.GetContext()).GetContext() namespace Orthanc @@ -258,7 +258,7 @@ } catch (OrthancException& e) { - if (e.GetErrorCode() == ErrorCode_NotImplemented) + //if (e.GetErrorCode() == ErrorCode_NotImplemented) { std::string root = ""; for (size_t i = 1; i < call.GetFullUri().size(); i++) @@ -309,8 +309,8 @@ StoreStatus status = StoreStatus_Failure; if (postData.size() > 0) { - status = context.GetIndex().Store - (context.GetFileStorage(), reinterpret_cast(&postData[0]), + status = context.Store + (reinterpret_cast(&postData[0]), postData.size(), dicomSummary, dicomJson, ""); } @@ -331,13 +331,13 @@ static void ListModalities(RestApi::GetCall& call) { - RETRIEVE_CONTEXT(call); + const OrthancRestApi2::Modalities& m = + dynamic_cast(call.GetContext()).GetModalities(); Json::Value result = Json::arrayValue; for (OrthancRestApi2::Modalities::const_iterator - it = context.GetModalities().begin(); - it != context.GetModalities().end(); it++) + it = m.begin(); it != m.end(); it++) { result.append(*it); } @@ -349,10 +349,8 @@ // Registration of the various REST handlers -------------------------------- - OrthancRestApi2::OrthancRestApi2(ServerIndex& index, - const std::string& path) : - index_(index), - storage_(path) + OrthancRestApi2::OrthancRestApi2(ServerContext& context) : + context_(context) { GetListOfDicomModalities(modalities_); diff -r 6f0e4a8ebb0f -r 4eb0c7ce86c9 OrthancServer/OrthancRestApi2.h --- a/OrthancServer/OrthancRestApi2.h Thu Nov 29 18:07:50 2012 +0100 +++ b/OrthancServer/OrthancRestApi2.h Thu Nov 29 22:22:00 2012 +0100 @@ -32,7 +32,7 @@ #pragma once -#include "ServerIndex.h" +#include "ServerContext.h" #include "../Core/RestApi/RestApi.h" #include @@ -45,22 +45,15 @@ typedef std::set Modalities; private: - ServerIndex& index_; - FileStorage storage_; + ServerContext& context_; Modalities modalities_; public: - OrthancRestApi2(ServerIndex& index, - const std::string& path); + OrthancRestApi2(ServerContext& context); - ServerIndex& GetIndex() + ServerContext& GetContext() { - return index_; - } - - FileStorage& GetFileStorage() - { - return storage_; + return context_; } Modalities& GetModalities() diff -r 6f0e4a8ebb0f -r 4eb0c7ce86c9 OrthancServer/ServerContext.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/OrthancServer/ServerContext.cpp Thu Nov 29 22:22:00 2012 +0100 @@ -0,0 +1,78 @@ +/** + * Orthanc - A Lightweight, RESTful DICOM Store + * Copyright (C) 2012 Medical Physics Department, CHU 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 "ServerContext.h" + +#include + +namespace Orthanc +{ + ServerContext::ServerContext(const boost::filesystem::path& path) : + storage_(path.string()), + index_(storage_, path.string()) + { + } + + StoreStatus ServerContext::Store(const char* dicomFile, + size_t dicomSize, + const DicomMap& dicomSummary, + const Json::Value& dicomJson, + const std::string& remoteAet) + { + std::string fileUuid = storage_.Create(dicomFile, dicomSize); + std::string jsonUuid = storage_.Create(dicomJson.toStyledString()); + StoreStatus status = index_.Store(dicomSummary, fileUuid, dicomSize, jsonUuid, remoteAet); + + if (status != StoreStatus_Success) + { + storage_.Remove(fileUuid); + storage_.Remove(jsonUuid); + } + + switch (status) + { + case StoreStatus_Success: + LOG(INFO) << "New instance stored"; + break; + + case StoreStatus_AlreadyStored: + LOG(INFO) << "Already stored"; + break; + + case StoreStatus_Failure: + LOG(ERROR) << "Store failure"; + break; + } + + return status; + } +} diff -r 6f0e4a8ebb0f -r 4eb0c7ce86c9 OrthancServer/ServerContext.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/OrthancServer/ServerContext.h Thu Nov 29 22:22:00 2012 +0100 @@ -0,0 +1,65 @@ +/** + * Orthanc - A Lightweight, RESTful DICOM Store + * Copyright (C) 2012 Medical Physics Department, CHU 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 "ServerIndex.h" +#include "../Core/FileStorage.h" + +namespace Orthanc +{ + class ServerContext + { + private: + FileStorage storage_; + ServerIndex index_; + + public: + ServerContext(const boost::filesystem::path& path); + + ServerIndex& GetIndex() + { + return index_; + } + + FileStorage& GetFileStorage() + { + return storage_; + } + + StoreStatus Store(const char* dicomFile, + size_t dicomSize, + const DicomMap& dicomSummary, + const Json::Value& dicomJson, + const std::string& remoteAet); + }; +} diff -r 6f0e4a8ebb0f -r 4eb0c7ce86c9 OrthancServer/ServerIndex.cpp --- a/OrthancServer/ServerIndex.cpp Thu Nov 29 18:07:50 2012 +0100 +++ b/OrthancServer/ServerIndex.cpp Thu Nov 29 22:22:00 2012 +0100 @@ -350,41 +350,6 @@ } - StoreStatus ServerIndex::Store(FileStorage& storage, - const char* dicomFile, - size_t dicomSize, - const DicomMap& dicomSummary, - const Json::Value& dicomJson, - const std::string& remoteAet) - { - std::string fileUuid = storage.Create(dicomFile, dicomSize); - std::string jsonUuid = storage.Create(dicomJson.toStyledString()); - StoreStatus status = Store(dicomSummary, fileUuid, dicomSize, jsonUuid, remoteAet); - - if (status != StoreStatus_Success) - { - storage.Remove(fileUuid); - storage.Remove(jsonUuid); - } - - switch (status) - { - case StoreStatus_Success: - LOG(INFO) << "New instance stored"; - break; - - case StoreStatus_AlreadyStored: - LOG(INFO) << "Already stored"; - break; - - case StoreStatus_Failure: - LOG(ERROR) << "Store failure"; - break; - } - - return status; - } - uint64_t ServerIndex::GetTotalCompressedSize() { boost::mutex::scoped_lock lock(mutex_); diff -r 6f0e4a8ebb0f -r 4eb0c7ce86c9 OrthancServer/ServerIndex.h --- a/OrthancServer/ServerIndex.h Thu Nov 29 18:07:50 2012 +0100 +++ b/OrthancServer/ServerIndex.h Thu Nov 29 22:22:00 2012 +0100 @@ -77,13 +77,6 @@ const std::string& jsonUuid, const std::string& remoteAet); - StoreStatus Store(FileStorage& storage, - const char* dicomFile, - size_t dicomSize, - const DicomMap& dicomSummary, - const Json::Value& dicomJson, - const std::string& remoteAet); - uint64_t GetTotalCompressedSize(); uint64_t GetTotalUncompressedSize(); diff -r 6f0e4a8ebb0f -r 4eb0c7ce86c9 OrthancServer/main.cpp --- a/OrthancServer/main.cpp Thu Nov 29 18:07:50 2012 +0100 +++ b/OrthancServer/main.cpp Thu Nov 29 22:22:00 2012 +0100 @@ -42,22 +42,20 @@ #include "../Core/HttpServer/MongooseServer.h" #include "DicomProtocol/DicomServer.h" #include "OrthancInitialization.h" - +#include "ServerContext.h" using namespace Orthanc; + class MyDicomStore : public IStoreRequestHandler { private: - ServerIndex& index_; - FileStorage storage_; + ServerContext& context_; public: - MyDicomStore(ServerIndex& index, - const std::string& path) : - index_(index), - storage_(path) + MyDicomStore(ServerContext& context) : + context_(context) { } @@ -68,9 +66,8 @@ { if (dicomFile.size() > 0) { - index_.Store(storage_, - reinterpret_cast(&dicomFile[0]), dicomFile.size(), - dicomSummary, dicomJson, remoteAet); + context_.Store(reinterpret_cast(&dicomFile[0]), dicomFile.size(), + dicomSummary, dicomJson, remoteAet); } } }; @@ -79,20 +76,16 @@ class MyDicomStoreFactory : public IStoreRequestHandlerFactory { private: - ServerIndex& index_; - std::string path_; + ServerContext& context_; public: - MyDicomStoreFactory(ServerIndex& index, - const std::string& path) : - index_(index), - path_(path) + MyDicomStoreFactory(ServerContext& context) : context_(context) { } virtual IStoreRequestHandler* ConstructStoreRequestHandler() { - return new MyDicomStore(index_, path_); + return new MyDicomStore(context_); } void Done() @@ -219,9 +212,8 @@ } boost::filesystem::path storageDirectory = GetGlobalStringParameter("StorageDirectory", "OrthancStorage"); - FileStorage storage(storageDirectory.string()); - ServerIndex index(storage, storageDirectory.string()); - MyDicomStoreFactory storeScp(index, storageDirectory.string()); + ServerContext context(storageDirectory); + MyDicomStoreFactory storeScp(context); { // DICOM server @@ -259,8 +251,8 @@ httpServer.RegisterHandler(new FilesystemHttpHandler("/app", ORTHANC_PATH "/OrthancExplorer")); #endif - httpServer.RegisterHandler(new OrthancRestApi2(index, storageDirectory.string())); - httpServer.RegisterHandler(new OrthancRestApi(index, storageDirectory.string())); + httpServer.RegisterHandler(new OrthancRestApi2(context)); + httpServer.RegisterHandler(new OrthancRestApi(context.GetIndex(), storageDirectory.string())); // GO !!! httpServer.Start(); diff -r 6f0e4a8ebb0f -r 4eb0c7ce86c9 UnitTests/FileStorage.cpp --- a/UnitTests/FileStorage.cpp Thu Nov 29 18:07:50 2012 +0100 +++ b/UnitTests/FileStorage.cpp Thu Nov 29 22:22:00 2012 +0100 @@ -4,6 +4,7 @@ #include #include "../Core/FileStorage.h" +#include "../OrthancServer/ServerIndex.h" #include "../Core/Toolbox.h" #include "../Core/OrthancException.h" #include "../Core/Uuid.h" @@ -130,8 +131,100 @@ ASSERT_NE(compressedData, r); #if defined(__linux) - // This tests is too slow on Windows + // This test is too slow on Windows accessor.SetCompressionForNextOperations(CompressionType_Zlib); ASSERT_THROW(accessor.Read(r, uncompressedId), OrthancException); #endif } + + + +#if 0 +// TODO REMOVE THIS STUFF +namespace Orthanc +{ + class ServerStorageAccessor : public StorageAccessor + { + private: + CompressedFileStorageAccessor composite_; + ServerIndex& index_; + AttachedFileType contentType_; + + protected: + virtual std::string WriteInternal(const void* data, + size_t size) + { + switch (contentType_) + { + case AttachedFileType_Json: + composite_.SetCompressionForNextOperations(CompressionType_None); + break; + + case AttachedFileType_Dicom: + // TODO GLOBAL PARAMETER + composite_.SetCompressionForNextOperations(CompressionType_Zlib); + break; + + default: + throw OrthancException(ErrorCode_InternalError); + } + + std::string fileUuid = composite_.Write(data, size); + + + } + + public: + ServerStorageAccessor(FileStorage& storage, + ServerIndex& index) : + composite_(storage), + index_(index) + { + contentType_ = AttachedFileType_Dicom; + } + + void SetAttachmentType(AttachedFileType type) + { + contentType_ = type; + } + + AttachedFileType GetAttachmentType() const + { + return contentType_; + } + + virtual void Read(std::string& content, + const std::string& uuid) + { + std::string fileUuid; + CompressionType compression; + + if (index_.GetFile(fileUuid, compression, uuid, contentType_)) + { + composite_.SetCompressionForNextOperations(compression); + composite_.Read(content, fileUuid); + } + else + { + throw OrthancException(ErrorCode_InternalError); + } + } + + virtual HttpFileSender* ConstructHttpFileSender(const std::string& uuid) + { + std::string fileUuid; + CompressionType compression; + + if (index_.GetFile(fileUuid, compression, uuid, contentType_)) + { + composite_.SetCompressionForNextOperations(compression); + return composite_.ConstructHttpFileSender(fileUuid); + } + else + { + throw OrthancException(ErrorCode_InternalError); + } + } + }; +} +#endif