diff OrthancServer/Sources/ServerJobs/OrthancPeerStoreJob.cpp @ 4153:a4664f169cd7

"/peers/{id}/store": New option "Compress" to compress DICOM data using gzip
author Sebastien Jodogne <s.jodogne@gmail.com>
date Sun, 23 Aug 2020 12:13:27 +0200
parents 05b8fd21089c
children 6e7c842679ec
line wrap: on
line diff
--- a/OrthancServer/Sources/ServerJobs/OrthancPeerStoreJob.cpp	Wed Aug 19 15:22:03 2020 +0200
+++ b/OrthancServer/Sources/ServerJobs/OrthancPeerStoreJob.cpp	Sun Aug 23 12:13:27 2020 +0200
@@ -34,6 +34,7 @@
 #include "../PrecompiledHeadersServer.h"
 #include "OrthancPeerStoreJob.h"
 
+#include "../../../OrthancFramework/Sources/Compression/GzipCompressor.h"
 #include "../../../OrthancFramework/Sources/Logging.h"
 #include "../../../OrthancFramework/Sources/SerializationToolbox.h"
 #include "../ServerContext.h"
@@ -51,11 +52,19 @@
     {
       client_.reset(new HttpClient(peer_, "instances"));
       client_->SetMethod(HttpMethod_Post);
+
+      if (compress_)
+      {
+        client_->AddHeader("Expect", "");
+        client_->AddHeader("Content-Encoding", "gzip");
+      }
     }
       
     LOG(INFO) << "Sending instance " << instance << " to peer \"" 
               << peer_.GetUrl() << "\"";
 
+    std::string body;
+
     try
     {
       if (transcode_)
@@ -71,17 +80,17 @@
 
         if (context_.Transcode(transcoded, source, syntaxes, true))
         {
-          client_->GetBody().assign(reinterpret_cast<const char*>(transcoded.GetBufferData()),
-                                    transcoded.GetBufferSize());
+          body.assign(reinterpret_cast<const char*>(transcoded.GetBufferData()),
+                      transcoded.GetBufferSize());
         }
         else
         {
-          client_->GetBody().swap(dicom);
+          body.swap(dicom);
         }
       }
       else
       {
-        context_.ReadDicom(client_->GetBody(), instance);
+        context_.ReadDicom(body, instance);
       }
     }
     catch (OrthancException& e)
@@ -90,6 +99,19 @@
       return false;
     }
 
+    if (compress_)
+    {
+      GzipCompressor compressor;
+      compressor.SetCompressionLevel(9);  // Max compression level
+      IBufferCompressor::Compress(client_->GetBody(), compressor, body);
+    }
+    else
+    {
+      client_->GetBody().swap(body);
+    }
+
+    size_ += client_->GetBody().size();
+
     std::string answer;
     if (client_->Apply(answer))
     {
@@ -176,6 +198,19 @@
   }
 
 
+  void OrthancPeerStoreJob::SetCompress(bool compress)
+  {
+    if (IsStarted())
+    {
+      throw OrthancException(ErrorCode_BadSequenceOfCalls);
+    }
+    else
+    {
+      compress_ = compress;
+    }    
+  }
+
+
   void OrthancPeerStoreJob::Stop(JobStopReason reason)   // For pausing jobs
   {
     client_.reset(NULL);
@@ -191,16 +226,23 @@
                     false /* allow simple format if possible */,
                     false /* don't include passwords */);
     value["Peer"] = v;
+    value["Compress"] = compress_;
     
     if (transcode_)
     {
       value["Transcode"] = GetTransferSyntaxUid(transferSyntax_);
     }
+
+    static const uint64_t MEGA_BYTES = 1024 * 1024;
+    value["Size"] = boost::lexical_cast<std::string>(size_);
+    value["SizeMB"] = static_cast<unsigned int>(size_ / MEGA_BYTES);
   }
 
 
   static const char* PEER = "Peer";
   static const char* TRANSCODE = "Transcode";
+  static const char* COMPRESS = "Compress";
+  static const char* SIZE = "Size";
 
   OrthancPeerStoreJob::OrthancPeerStoreJob(ServerContext& context,
                                            const Json::Value& serialized) :
@@ -217,6 +259,25 @@
     else
     {
       transcode_ = false;
+      transferSyntax_ = DicomTransferSyntax_LittleEndianExplicit;  // Dummy value
+    }
+
+    if (serialized.isMember(COMPRESS))
+    {
+      SetCompress(SerializationToolbox::ReadBoolean(serialized, COMPRESS));
+    }
+    else
+    {
+      compress_ = false;
+    }
+
+    if (serialized.isMember(SIZE))
+    {
+      size_ = boost::lexical_cast<uint64_t>(SerializationToolbox::ReadString(serialized, SIZE));
+    }
+    else
+    {
+      size_ = 0;
     }
   }
 
@@ -238,6 +299,9 @@
       {
         target[TRANSCODE] = GetTransferSyntaxUid(transferSyntax_);
       }
+
+      target[COMPRESS] = compress_;
+      target[SIZE] = boost::lexical_cast<std::string>(size_);
       
       return true;
     }