comparison OrthancServer/ServerContext.cpp @ 1549:e5e975e9b738

refactoring and simplification of StorageAccessor
author Sebastien Jodogne <s.jodogne@gmail.com>
date Mon, 17 Aug 2015 10:47:04 +0200
parents e9325f3ac496
children 2c7d5eb588e6
comparison
equal deleted inserted replaced
1548:e9325f3ac496 1549:e5e975e9b738
31 31
32 32
33 #include "PrecompiledHeadersServer.h" 33 #include "PrecompiledHeadersServer.h"
34 #include "ServerContext.h" 34 #include "ServerContext.h"
35 35
36 #include "../Core/FileStorage/StorageAccessor.h"
36 #include "../Core/HttpServer/FilesystemHttpSender.h" 37 #include "../Core/HttpServer/FilesystemHttpSender.h"
37 #include "../Core/HttpServer/HttpStreamTranscoder.h" 38 #include "../Core/HttpServer/HttpStreamTranscoder.h"
38 #include "../Core/Logging.h" 39 #include "../Core/Logging.h"
39 #include "FromDcmtkBridge.h" 40 #include "FromDcmtkBridge.h"
40 #include "ServerToolbox.h" 41 #include "ServerToolbox.h"
95 } 96 }
96 } 97 }
97 } 98 }
98 99
99 100
100 ServerContext::ServerContext(IDatabaseWrapper& database) : 101 ServerContext::ServerContext(IDatabaseWrapper& database,
102 IStorageArea& area) :
101 index_(*this, database), 103 index_(*this, database),
104 area_(area),
102 compressionEnabled_(false), 105 compressionEnabled_(false),
106 storeMD5_(true),
103 provider_(*this), 107 provider_(*this),
104 dicomCache_(provider_, DICOM_CACHE_SIZE), 108 dicomCache_(provider_, DICOM_CACHE_SIZE),
105 scheduler_(Configuration::GetGlobalIntegerParameter("LimitJobs", 10)), 109 scheduler_(Configuration::GetGlobalIntegerParameter("LimitJobs", 10)),
106 lua_(*this), 110 lua_(*this),
107 plugins_(NULL), 111 plugins_(NULL),
162 LOG(WARNING) << "Disk compression is disabled"; 166 LOG(WARNING) << "Disk compression is disabled";
163 167
164 compressionEnabled_ = enabled; 168 compressionEnabled_ = enabled;
165 } 169 }
166 170
171
167 void ServerContext::RemoveFile(const std::string& fileUuid, 172 void ServerContext::RemoveFile(const std::string& fileUuid,
168 FileContentType type) 173 FileContentType type)
169 { 174 {
170 accessor_.Remove(fileUuid, type); 175 area_.Remove(fileUuid, type);
171 } 176 }
172 177
173 178
174 StoreStatus ServerContext::Store(std::string& resultPublicId, 179 StoreStatus ServerContext::Store(std::string& resultPublicId,
175 DicomInstanceToStore& dicom) 180 DicomInstanceToStore& dicom)
176 { 181 {
177 try 182 try
178 { 183 {
184 StorageAccessor accessor(area_);
185
179 DicomInstanceHasher hasher(dicom.GetSummary()); 186 DicomInstanceHasher hasher(dicom.GetSummary());
180 resultPublicId = hasher.HashInstance(); 187 resultPublicId = hasher.HashInstance();
181 188
182 Json::Value simplified; 189 Json::Value simplified;
183 SimplifyTags(simplified, dicom.GetJson()); 190 SimplifyTags(simplified, dicom.GetJson());
211 { 218 {
212 LOG(INFO) << "An incoming instance has been discarded by the filter"; 219 LOG(INFO) << "An incoming instance has been discarded by the filter";
213 return StoreStatus_FilteredOut; 220 return StoreStatus_FilteredOut;
214 } 221 }
215 222
216 if (compressionEnabled_) 223 // TODO Should we use "gzip" instead?
217 { 224 CompressionType compression = (compressionEnabled_ ? CompressionType_ZlibWithSize : CompressionType_None);
218 // TODO Should we use "gzip" instead? 225
219 accessor_.SetCompressionForNextOperations(CompressionType_ZlibWithSize); 226 FileInfo dicomInfo = accessor.Write(dicom.GetBufferData(), dicom.GetBufferSize(),
220 } 227 FileContentType_Dicom, compression, storeMD5_);
221 else 228 FileInfo jsonInfo = accessor.Write(dicom.GetJson().toStyledString(),
222 { 229 FileContentType_DicomAsJson, compression, storeMD5_);
223 accessor_.SetCompressionForNextOperations(CompressionType_None);
224 }
225
226 FileInfo dicomInfo = accessor_.Write(dicom.GetBufferData(), dicom.GetBufferSize(), FileContentType_Dicom);
227 FileInfo jsonInfo = accessor_.Write(dicom.GetJson().toStyledString(), FileContentType_DicomAsJson);
228 230
229 ServerIndex::Attachments attachments; 231 ServerIndex::Attachments attachments;
230 attachments.push_back(dicomInfo); 232 attachments.push_back(dicomInfo);
231 attachments.push_back(jsonInfo); 233 attachments.push_back(jsonInfo);
232 234
245 it->second)); 247 it->second));
246 } 248 }
247 249
248 if (status != StoreStatus_Success) 250 if (status != StoreStatus_Success)
249 { 251 {
250 accessor_.Remove(dicomInfo.GetUuid(), FileContentType_Dicom); 252 accessor.Remove(dicomInfo);
251 accessor_.Remove(jsonInfo.GetUuid(), FileContentType_DicomAsJson); 253 accessor.Remove(jsonInfo);
252 } 254 }
253 255
254 switch (status) 256 switch (status)
255 { 257 {
256 case StoreStatus_Success: 258 case StoreStatus_Success:
312 if (!index_.LookupAttachment(attachment, instancePublicId, content)) 314 if (!index_.LookupAttachment(attachment, instancePublicId, content))
313 { 315 {
314 throw OrthancException(ErrorCode_InternalError); 316 throw OrthancException(ErrorCode_InternalError);
315 } 317 }
316 318
317 IStorageArea& area = accessor_.GetStorageArea(); 319 StorageAccessor accessor(area_);
318 320 accessor.AnswerFile(output, attachment);
319 BufferHttpSender sender;
320 area.Read(sender.GetBuffer(), attachment.GetUuid(), content);
321 sender.SetContentType(GetMimeType(content));
322 sender.SetContentFilename(attachment.GetUuid() + std::string(GetFileExtension(content)));
323
324 HttpStreamTranscoder transcoder(sender, attachment.GetCompressionType());
325 output.AnswerStream(transcoder);
326 } 321 }
327 322
328 323
329 void ServerContext::ReadJson(Json::Value& result, 324 void ServerContext::ReadJson(Json::Value& result,
330 const std::string& instancePublicId) 325 const std::string& instancePublicId)
348 FileInfo attachment; 343 FileInfo attachment;
349 if (!index_.LookupAttachment(attachment, instancePublicId, content)) 344 if (!index_.LookupAttachment(attachment, instancePublicId, content))
350 { 345 {
351 throw OrthancException(ErrorCode_InternalError); 346 throw OrthancException(ErrorCode_InternalError);
352 } 347 }
353 348
354 if (uncompressIfNeeded) 349 StorageAccessor accessor(area_);
355 { 350 accessor.Read(result, attachment);
356 accessor_.SetCompressionForNextOperations(attachment.GetCompressionType());
357 }
358 else
359 {
360 accessor_.SetCompressionForNextOperations(CompressionType_None);
361 }
362
363 accessor_.Read(result, attachment.GetUuid(), attachment.GetContentType());
364 } 351 }
365 352
366 353
367 IDynamicObject* ServerContext::DicomCacheProvider::Provide(const std::string& instancePublicId) 354 IDynamicObject* ServerContext::DicomCacheProvider::Provide(const std::string& instancePublicId)
368 { 355 {
393 380
394 381
395 void ServerContext::SetStoreMD5ForAttachments(bool storeMD5) 382 void ServerContext::SetStoreMD5ForAttachments(bool storeMD5)
396 { 383 {
397 LOG(INFO) << "Storing MD5 for attachments: " << (storeMD5 ? "yes" : "no"); 384 LOG(INFO) << "Storing MD5 for attachments: " << (storeMD5 ? "yes" : "no");
398 accessor_.SetStoreMD5(storeMD5); 385 storeMD5_ = storeMD5;
399 } 386 }
400 387
401 388
402 bool ServerContext::AddAttachment(const std::string& resourceId, 389 bool ServerContext::AddAttachment(const std::string& resourceId,
403 FileContentType attachmentType, 390 FileContentType attachmentType,
404 const void* data, 391 const void* data,
405 size_t size) 392 size_t size)
406 { 393 {
407 LOG(INFO) << "Adding attachment " << EnumerationToString(attachmentType) << " to resource " << resourceId; 394 LOG(INFO) << "Adding attachment " << EnumerationToString(attachmentType) << " to resource " << resourceId;
408 395
409 if (compressionEnabled_) 396 // TODO Should we use "gzip" instead?
410 { 397 CompressionType compression = (compressionEnabled_ ? CompressionType_ZlibWithSize : CompressionType_None);
411 // TODO Should we use "gzip" instead? 398
412 accessor_.SetCompressionForNextOperations(CompressionType_ZlibWithSize); 399 StorageAccessor accessor(area_);
413 } 400 FileInfo attachment = accessor.Write(data, size, attachmentType, compression, storeMD5_);
414 else 401
415 { 402 StoreStatus status = index_.AddAttachment(attachment, resourceId);
416 accessor_.SetCompressionForNextOperations(CompressionType_None);
417 }
418
419 FileInfo info = accessor_.Write(data, size, attachmentType);
420 StoreStatus status = index_.AddAttachment(info, resourceId);
421
422 if (status != StoreStatus_Success) 403 if (status != StoreStatus_Success)
423 { 404 {
424 accessor_.Remove(info.GetUuid(), info.GetContentType()); 405 accessor.Remove(attachment);
425 return false; 406 return false;
426 } 407 }
427 else 408 else
428 { 409 {
429 return true; 410 return true;