comparison OrthancServer/Sources/ServerContext.cpp @ 5080:d7274e43ea7c attach-custom-data

allow plugins to store a customData in the Attachments table to e.g. store custom paths without requiring an external DB
author Alain Mazy <am@osimis.io>
date Thu, 08 Sep 2022 17:42:08 +0200
parents e69a3ff39bc5
children 8279eaab0d1d
comparison
equal deleted inserted replaced
5079:4366b4c41441 5080:d7274e43ea7c
484 compressionEnabled_ = enabled; 484 compressionEnabled_ = enabled;
485 } 485 }
486 486
487 487
488 void ServerContext::RemoveFile(const std::string& fileUuid, 488 void ServerContext::RemoveFile(const std::string& fileUuid,
489 FileContentType type) 489 FileContentType type,
490 const std::string& customData)
490 { 491 {
491 StorageAccessor accessor(area_, &storageCache_, GetMetricsRegistry()); 492 StorageAccessor accessor(area_, &storageCache_, GetMetricsRegistry());
492 accessor.Remove(fileUuid, type); 493 accessor.Remove(fileUuid, type, customData);
493 } 494 }
494 495
495 496
496 ServerContext::StoreResult ServerContext::StoreAfterTranscoding(std::string& resultPublicId, 497 ServerContext::StoreResult ServerContext::StoreAfterTranscoding(std::string& resultPublicId,
497 DicomInstanceToStore& dicom, 498 DicomInstanceToStore& dicom,
597 PublishDicomCacheMetrics(); 598 PublishDicomCacheMetrics();
598 599
599 // TODO Should we use "gzip" instead? 600 // TODO Should we use "gzip" instead?
600 CompressionType compression = (compressionEnabled_ ? CompressionType_ZlibWithSize : CompressionType_None); 601 CompressionType compression = (compressionEnabled_ ? CompressionType_ZlibWithSize : CompressionType_None);
601 602
602 FileInfo dicomInfo = accessor.Write(dicom.GetBufferData(), dicom.GetBufferSize(), 603 std::string dicomCustomData;
603 FileContentType_Dicom, compression, storeMD5_); 604 std::string dicomUuid = Toolbox::GenerateUuid();
605
606 FileInfo dicomInfo = accessor.WriteInstance(dicomCustomData, dicom, dicom.GetBufferData(), dicom.GetBufferSize(),
607 FileContentType_Dicom, compression, storeMD5_, dicomUuid);
604 608
605 ServerIndex::Attachments attachments; 609 ServerIndex::Attachments attachments;
606 attachments.push_back(dicomInfo); 610 attachments.push_back(dicomInfo);
607 611
608 FileInfo dicomUntilPixelData; 612 FileInfo dicomUntilPixelData;
609 if (hasPixelDataOffset && 613 if (hasPixelDataOffset &&
610 (!area_.HasReadRange() || 614 (!area_.HasReadRange() ||
611 compressionEnabled_)) 615 compressionEnabled_))
612 { 616 {
613 dicomUntilPixelData = accessor.Write(dicom.GetBufferData(), pixelDataOffset, 617 std::string dicomHeaderCustomData;
614 FileContentType_DicomUntilPixelData, compression, storeMD5_); 618 std::string dicomHeaderUuid = Toolbox::GenerateUuid();
619
620 dicomUntilPixelData = accessor.WriteInstance(dicomHeaderCustomData, dicom, dicom.GetBufferData(), pixelDataOffset,
621 FileContentType_DicomUntilPixelData, compression, storeMD5_, dicomHeaderUuid);
615 attachments.push_back(dicomUntilPixelData); 622 attachments.push_back(dicomUntilPixelData);
616 } 623 }
617 624
618 typedef std::map<MetadataType, std::string> InstanceMetadata; 625 typedef std::map<MetadataType, std::string> InstanceMetadata;
619 InstanceMetadata instanceMetadata; 626 InstanceMetadata instanceMetadata;
856 } 863 }
857 } 864 }
858 865
859 866
860 void ServerContext::ChangeAttachmentCompression(const std::string& resourceId, 867 void ServerContext::ChangeAttachmentCompression(const std::string& resourceId,
868 ResourceType resourceType,
861 FileContentType attachmentType, 869 FileContentType attachmentType,
862 CompressionType compression) 870 CompressionType compression)
863 { 871 {
864 LOG(INFO) << "Changing compression type for attachment " 872 LOG(INFO) << "Changing compression type for attachment "
865 << EnumerationToString(attachmentType) 873 << EnumerationToString(attachmentType)
882 std::string content; 890 std::string content;
883 891
884 StorageAccessor accessor(area_, &storageCache_, GetMetricsRegistry()); 892 StorageAccessor accessor(area_, &storageCache_, GetMetricsRegistry());
885 accessor.Read(content, attachment); 893 accessor.Read(content, attachment);
886 894
887 FileInfo modified = accessor.Write(content.empty() ? NULL : content.c_str(), 895 std::string newUuid = Toolbox::GenerateUuid();
888 content.size(), attachmentType, compression, storeMD5_); 896 std::string newCustomData;
897 FileInfo modified;
898
899 // if (attachmentType == FileContentType_Dicom || attachmentType == FileContentType_DicomUntilPixelData)
900 // {
901 // // DicomInstanceToStore instance;
902 // // TODO_CUSTOM_DATA: get the Instance such that we can call accessor.GetCustomData ...
903 // // modified = accessor.WriteInstance(newCustomData, instance, content.empty() ? NULL : content.c_str(),
904 // // content.size(), attachmentType, compression, storeMD5_, newUuid);
905 // }
906 // else
907 {
908 ResourceType resourceType = ResourceType_Instance; //TODO_CUSTOM_DATA: get it from above in the stack
909 modified = accessor.WriteAttachment(newCustomData, resourceId, resourceType, content.empty() ? NULL : content.c_str(),
910 content.size(), attachmentType, compression, storeMD5_, newUuid);
911 }
912
913
889 914
890 try 915 try
891 { 916 {
892 int64_t newRevision; // ignored 917 int64_t newRevision; // ignored
893 StoreStatus status = index_.AddAttachment(newRevision, modified, resourceId, 918 StoreStatus status = index_.AddAttachment(newRevision, modified, resourceId,
1002 1027
1003 std::string dicom; 1028 std::string dicom;
1004 1029
1005 { 1030 {
1006 StorageAccessor accessor(area_, &storageCache_, GetMetricsRegistry()); 1031 StorageAccessor accessor(area_, &storageCache_, GetMetricsRegistry());
1007 accessor.ReadStartRange(dicom, attachment.GetUuid(), FileContentType_Dicom, pixelDataOffset); 1032 accessor.ReadStartRange(dicom, attachment.GetUuid(), FileContentType_Dicom, pixelDataOffset, attachment.GetCustomData());
1008 } 1033 }
1009 1034
1010 assert(dicom.size() == pixelDataOffset); 1035 assert(dicom.size() == pixelDataOffset);
1011 ParsedDicomFile parsed(dicom); 1036 ParsedDicomFile parsed(dicom);
1012 OrthancConfiguration::DefaultDicomDatasetToJson(result, parsed, ignoreTagLength); 1037 OrthancConfiguration::DefaultDicomDatasetToJson(result, parsed, ignoreTagLength);
1068 1093
1069 if (!area_.HasReadRange() || 1094 if (!area_.HasReadRange() ||
1070 compressionEnabled_) 1095 compressionEnabled_)
1071 { 1096 {
1072 int64_t newRevision; 1097 int64_t newRevision;
1073 AddAttachment(newRevision, instancePublicId, FileContentType_DicomUntilPixelData, 1098 AddAttachment(newRevision, instancePublicId, ResourceType_Instance, FileContentType_DicomUntilPixelData,
1074 dicom.empty() ? NULL: dicom.c_str(), pixelDataOffset, 1099 dicom.empty() ? NULL: dicom.c_str(), pixelDataOffset,
1075 false /* no old revision */, -1 /* dummy revision */, "" /* dummy MD5 */); 1100 false /* no old revision */, -1 /* dummy revision */, "" /* dummy MD5 */);
1076 } 1101 }
1077 } 1102 }
1078 } 1103 }
1079 } 1104 }
1080 } 1105 }
1132 { 1157 {
1133 uint64_t pixelDataOffset = boost::lexical_cast<uint64_t>(s); 1158 uint64_t pixelDataOffset = boost::lexical_cast<uint64_t>(s);
1134 1159
1135 StorageAccessor accessor(area_, &storageCache_, GetMetricsRegistry()); 1160 StorageAccessor accessor(area_, &storageCache_, GetMetricsRegistry());
1136 1161
1137 accessor.ReadStartRange(dicom, attachment.GetUuid(), attachment.GetContentType(), pixelDataOffset); 1162 accessor.ReadStartRange(dicom, attachment.GetUuid(), attachment.GetContentType(), pixelDataOffset, attachment.GetCustomData());
1138 assert(dicom.size() == pixelDataOffset); 1163 assert(dicom.size() == pixelDataOffset);
1139 1164
1140 return true; // Success 1165 return true; // Success
1141 } 1166 }
1142 catch (boost::bad_lexical_cast&) 1167 catch (boost::bad_lexical_cast&)
1260 } 1285 }
1261 1286
1262 1287
1263 bool ServerContext::AddAttachment(int64_t& newRevision, 1288 bool ServerContext::AddAttachment(int64_t& newRevision,
1264 const std::string& resourceId, 1289 const std::string& resourceId,
1290 ResourceType resourceType,
1265 FileContentType attachmentType, 1291 FileContentType attachmentType,
1266 const void* data, 1292 const void* data,
1267 size_t size, 1293 size_t size,
1268 bool hasOldRevision, 1294 bool hasOldRevision,
1269 int64_t oldRevision, 1295 int64_t oldRevision,
1273 1299
1274 // TODO Should we use "gzip" instead? 1300 // TODO Should we use "gzip" instead?
1275 CompressionType compression = (compressionEnabled_ ? CompressionType_ZlibWithSize : CompressionType_None); 1301 CompressionType compression = (compressionEnabled_ ? CompressionType_ZlibWithSize : CompressionType_None);
1276 1302
1277 StorageAccessor accessor(area_, &storageCache_, GetMetricsRegistry()); 1303 StorageAccessor accessor(area_, &storageCache_, GetMetricsRegistry());
1278 FileInfo attachment = accessor.Write(data, size, attachmentType, compression, storeMD5_); 1304
1305 std::string uuid = Toolbox::GenerateUuid();
1306 std::string customData;
1307
1308 assert(attachmentType != FileContentType_Dicom && attachmentType != FileContentType_DicomUntilPixelData); // this method can not be used to store instances
1309
1310 FileInfo attachment = accessor.WriteAttachment(customData, resourceId, resourceType, data, size, attachmentType, compression, storeMD5_, uuid);
1279 1311
1280 try 1312 try
1281 { 1313 {
1282 StoreStatus status = index_.AddAttachment( 1314 StoreStatus status = index_.AddAttachment(
1283 newRevision, attachment, resourceId, hasOldRevision, oldRevision, oldMD5); 1315 newRevision, attachment, resourceId, hasOldRevision, oldRevision, oldMD5);