changeset 224:4eb0c7ce86c9

refactoring for store
author Sebastien Jodogne <s.jodogne@gmail.com>
date Thu, 29 Nov 2012 22:22:00 +0100
parents 6f0e4a8ebb0f
children 03aa59ecf6d8
files CMakeLists.txt OrthancServer/OrthancRestApi2.cpp OrthancServer/OrthancRestApi2.h OrthancServer/ServerContext.cpp OrthancServer/ServerContext.h OrthancServer/ServerIndex.cpp OrthancServer/ServerIndex.h OrthancServer/main.cpp UnitTests/FileStorage.cpp
diffstat 9 files changed, 266 insertions(+), 88 deletions(-) [+]
line wrap: on
line diff
--- 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
   )
--- 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<OrthancRestApi2&>(call.GetContext())
+  ServerContext& context = dynamic_cast<OrthancRestApi2&>(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<const char*>(&postData[0]),
+      status = context.Store
+        (reinterpret_cast<const char*>(&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<OrthancRestApi2&>(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_);
 
--- 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 <set>
@@ -45,22 +45,15 @@
     typedef std::set<std::string> 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()
--- /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 <http://www.gnu.org/licenses/>.
+ **/
+
+
+#include "ServerContext.h"
+
+#include <glog/logging.h>
+
+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;
+  }
+}
--- /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 <http://www.gnu.org/licenses/>.
+ **/
+
+
+#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);
+  };
+}
--- 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_);
--- 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();
--- 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<const char*>(&dicomFile[0]), dicomFile.size(),
-                   dicomSummary, dicomJson, remoteAet);
+      context_.Store(reinterpret_cast<const char*>(&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();
--- 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 <glog/logging.h>
 
 #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