Mercurial > hg > orthanc
comparison 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 |
comparison
equal
deleted
inserted
replaced
4152:36257d6f348f | 4153:a4664f169cd7 |
---|---|
32 | 32 |
33 | 33 |
34 #include "../PrecompiledHeadersServer.h" | 34 #include "../PrecompiledHeadersServer.h" |
35 #include "OrthancPeerStoreJob.h" | 35 #include "OrthancPeerStoreJob.h" |
36 | 36 |
37 #include "../../../OrthancFramework/Sources/Compression/GzipCompressor.h" | |
37 #include "../../../OrthancFramework/Sources/Logging.h" | 38 #include "../../../OrthancFramework/Sources/Logging.h" |
38 #include "../../../OrthancFramework/Sources/SerializationToolbox.h" | 39 #include "../../../OrthancFramework/Sources/SerializationToolbox.h" |
39 #include "../ServerContext.h" | 40 #include "../ServerContext.h" |
40 | 41 |
41 #include <dcmtk/dcmdata/dcfilefo.h> | 42 #include <dcmtk/dcmdata/dcfilefo.h> |
49 | 50 |
50 if (client_.get() == NULL) | 51 if (client_.get() == NULL) |
51 { | 52 { |
52 client_.reset(new HttpClient(peer_, "instances")); | 53 client_.reset(new HttpClient(peer_, "instances")); |
53 client_->SetMethod(HttpMethod_Post); | 54 client_->SetMethod(HttpMethod_Post); |
55 | |
56 if (compress_) | |
57 { | |
58 client_->AddHeader("Expect", ""); | |
59 client_->AddHeader("Content-Encoding", "gzip"); | |
60 } | |
54 } | 61 } |
55 | 62 |
56 LOG(INFO) << "Sending instance " << instance << " to peer \"" | 63 LOG(INFO) << "Sending instance " << instance << " to peer \"" |
57 << peer_.GetUrl() << "\""; | 64 << peer_.GetUrl() << "\""; |
65 | |
66 std::string body; | |
58 | 67 |
59 try | 68 try |
60 { | 69 { |
61 if (transcode_) | 70 if (transcode_) |
62 { | 71 { |
69 IDicomTranscoder::DicomImage source, transcoded; | 78 IDicomTranscoder::DicomImage source, transcoded; |
70 source.SetExternalBuffer(dicom); | 79 source.SetExternalBuffer(dicom); |
71 | 80 |
72 if (context_.Transcode(transcoded, source, syntaxes, true)) | 81 if (context_.Transcode(transcoded, source, syntaxes, true)) |
73 { | 82 { |
74 client_->GetBody().assign(reinterpret_cast<const char*>(transcoded.GetBufferData()), | 83 body.assign(reinterpret_cast<const char*>(transcoded.GetBufferData()), |
75 transcoded.GetBufferSize()); | 84 transcoded.GetBufferSize()); |
76 } | 85 } |
77 else | 86 else |
78 { | 87 { |
79 client_->GetBody().swap(dicom); | 88 body.swap(dicom); |
80 } | 89 } |
81 } | 90 } |
82 else | 91 else |
83 { | 92 { |
84 context_.ReadDicom(client_->GetBody(), instance); | 93 context_.ReadDicom(body, instance); |
85 } | 94 } |
86 } | 95 } |
87 catch (OrthancException& e) | 96 catch (OrthancException& e) |
88 { | 97 { |
89 LOG(WARNING) << "An instance was removed after the job was issued: " << instance; | 98 LOG(WARNING) << "An instance was removed after the job was issued: " << instance; |
90 return false; | 99 return false; |
91 } | 100 } |
101 | |
102 if (compress_) | |
103 { | |
104 GzipCompressor compressor; | |
105 compressor.SetCompressionLevel(9); // Max compression level | |
106 IBufferCompressor::Compress(client_->GetBody(), compressor, body); | |
107 } | |
108 else | |
109 { | |
110 client_->GetBody().swap(body); | |
111 } | |
112 | |
113 size_ += client_->GetBody().size(); | |
92 | 114 |
93 std::string answer; | 115 std::string answer; |
94 if (client_->Apply(answer)) | 116 if (client_->Apply(answer)) |
95 { | 117 { |
96 return true; | 118 return true; |
171 } | 193 } |
172 else | 194 else |
173 { | 195 { |
174 transcode_ = false; | 196 transcode_ = false; |
175 } | 197 } |
198 } | |
199 | |
200 | |
201 void OrthancPeerStoreJob::SetCompress(bool compress) | |
202 { | |
203 if (IsStarted()) | |
204 { | |
205 throw OrthancException(ErrorCode_BadSequenceOfCalls); | |
206 } | |
207 else | |
208 { | |
209 compress_ = compress; | |
210 } | |
176 } | 211 } |
177 | 212 |
178 | 213 |
179 void OrthancPeerStoreJob::Stop(JobStopReason reason) // For pausing jobs | 214 void OrthancPeerStoreJob::Stop(JobStopReason reason) // For pausing jobs |
180 { | 215 { |
189 Json::Value v; | 224 Json::Value v; |
190 peer_.Serialize(v, | 225 peer_.Serialize(v, |
191 false /* allow simple format if possible */, | 226 false /* allow simple format if possible */, |
192 false /* don't include passwords */); | 227 false /* don't include passwords */); |
193 value["Peer"] = v; | 228 value["Peer"] = v; |
229 value["Compress"] = compress_; | |
194 | 230 |
195 if (transcode_) | 231 if (transcode_) |
196 { | 232 { |
197 value["Transcode"] = GetTransferSyntaxUid(transferSyntax_); | 233 value["Transcode"] = GetTransferSyntaxUid(transferSyntax_); |
198 } | 234 } |
235 | |
236 static const uint64_t MEGA_BYTES = 1024 * 1024; | |
237 value["Size"] = boost::lexical_cast<std::string>(size_); | |
238 value["SizeMB"] = static_cast<unsigned int>(size_ / MEGA_BYTES); | |
199 } | 239 } |
200 | 240 |
201 | 241 |
202 static const char* PEER = "Peer"; | 242 static const char* PEER = "Peer"; |
203 static const char* TRANSCODE = "Transcode"; | 243 static const char* TRANSCODE = "Transcode"; |
244 static const char* COMPRESS = "Compress"; | |
245 static const char* SIZE = "Size"; | |
204 | 246 |
205 OrthancPeerStoreJob::OrthancPeerStoreJob(ServerContext& context, | 247 OrthancPeerStoreJob::OrthancPeerStoreJob(ServerContext& context, |
206 const Json::Value& serialized) : | 248 const Json::Value& serialized) : |
207 SetOfInstancesJob(serialized), | 249 SetOfInstancesJob(serialized), |
208 context_(context) | 250 context_(context) |
215 SetTranscode(SerializationToolbox::ReadString(serialized, TRANSCODE)); | 257 SetTranscode(SerializationToolbox::ReadString(serialized, TRANSCODE)); |
216 } | 258 } |
217 else | 259 else |
218 { | 260 { |
219 transcode_ = false; | 261 transcode_ = false; |
262 transferSyntax_ = DicomTransferSyntax_LittleEndianExplicit; // Dummy value | |
263 } | |
264 | |
265 if (serialized.isMember(COMPRESS)) | |
266 { | |
267 SetCompress(SerializationToolbox::ReadBoolean(serialized, COMPRESS)); | |
268 } | |
269 else | |
270 { | |
271 compress_ = false; | |
272 } | |
273 | |
274 if (serialized.isMember(SIZE)) | |
275 { | |
276 size_ = boost::lexical_cast<uint64_t>(SerializationToolbox::ReadString(serialized, SIZE)); | |
277 } | |
278 else | |
279 { | |
280 size_ = 0; | |
220 } | 281 } |
221 } | 282 } |
222 | 283 |
223 | 284 |
224 bool OrthancPeerStoreJob::Serialize(Json::Value& target) | 285 bool OrthancPeerStoreJob::Serialize(Json::Value& target) |
236 | 297 |
237 if (transcode_) | 298 if (transcode_) |
238 { | 299 { |
239 target[TRANSCODE] = GetTransferSyntaxUid(transferSyntax_); | 300 target[TRANSCODE] = GetTransferSyntaxUid(transferSyntax_); |
240 } | 301 } |
302 | |
303 target[COMPRESS] = compress_; | |
304 target[SIZE] = boost::lexical_cast<std::string>(size_); | |
241 | 305 |
242 return true; | 306 return true; |
243 } | 307 } |
244 } | 308 } |
245 } | 309 } |