# HG changeset patch # User Sebastien Jodogne # Date 1598177607 -7200 # Node ID a4664f169cd73eea725cdfb8c623f8907b6058a6 # Parent 36257d6f348f1145c3bf1da63497934434dd3a70 "/peers/{id}/store": New option "Compress" to compress DICOM data using gzip diff -r 36257d6f348f -r a4664f169cd7 NEWS --- a/NEWS Wed Aug 19 15:22:03 2020 +0200 +++ b/NEWS Sun Aug 23 12:13:27 2020 +0200 @@ -1,6 +1,12 @@ Pending changes in the mainline =============================== +REST API +-------- + +* "/peers/{id}/store": New option "Compress" to compress DICOM data using gzip +* "OrthancPeerStore" jobs now report the transmitted size in their public content + Plugins ------- diff -r 36257d6f348f -r a4664f169cd7 OrthancServer/Sources/OrthancRestApi/OrthancRestModalities.cpp --- a/OrthancServer/Sources/OrthancRestApi/OrthancRestModalities.cpp Wed Aug 19 15:22:03 2020 +0200 +++ b/OrthancServer/Sources/OrthancRestApi/OrthancRestModalities.cpp Sun Aug 23 12:13:27 2020 +0200 @@ -1143,6 +1143,13 @@ { job->SetTranscode(SerializationToolbox::ReadString(request, TRANSCODE)); } + + static const char* COMPRESS = "Compress"; + if (request.type() == Json::objectValue && + request.isMember(COMPRESS)) + { + job->SetCompress(SerializationToolbox::ReadBoolean(request, COMPRESS)); + } { OrthancConfiguration::ReaderLock lock; diff -r 36257d6f348f -r a4664f169cd7 OrthancServer/Sources/ServerJobs/OrthancPeerStoreJob.cpp --- 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(transcoded.GetBufferData()), - transcoded.GetBufferSize()); + body.assign(reinterpret_cast(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(size_); + value["SizeMB"] = static_cast(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(SerializationToolbox::ReadString(serialized, SIZE)); + } + else + { + size_ = 0; } } @@ -238,6 +299,9 @@ { target[TRANSCODE] = GetTransferSyntaxUid(transferSyntax_); } + + target[COMPRESS] = compress_; + target[SIZE] = boost::lexical_cast(size_); return true; } diff -r 36257d6f348f -r a4664f169cd7 OrthancServer/Sources/ServerJobs/OrthancPeerStoreJob.h --- a/OrthancServer/Sources/ServerJobs/OrthancPeerStoreJob.h Wed Aug 19 15:22:03 2020 +0200 +++ b/OrthancServer/Sources/ServerJobs/OrthancPeerStoreJob.h Sun Aug 23 12:13:27 2020 +0200 @@ -50,6 +50,8 @@ std::unique_ptr client_; bool transcode_; DicomTransferSyntax transferSyntax_; + bool compress_; + uint64_t size_; protected: virtual bool HandleInstance(const std::string& instance); @@ -59,7 +61,10 @@ public: OrthancPeerStoreJob(ServerContext& context) : context_(context), - transcode_(false) + transcode_(false), + transferSyntax_(DicomTransferSyntax_LittleEndianExplicit), // Dummy value + compress_(false), + size_(0) { } @@ -78,6 +83,11 @@ return transcode_; } + bool IsCompress() const + { + return compress_; + } + DicomTransferSyntax GetTransferSyntax() const; void SetTranscode(DicomTransferSyntax syntax); @@ -86,6 +96,8 @@ void ClearTranscode(); + void SetCompress(bool compress); + virtual void Stop(JobStopReason reason); // For pausing jobs virtual void GetJobType(std::string& target)