Mercurial > hg > orthanc
comparison OrthancServer/Sources/Database/StatelessDatabaseOperations.cpp @ 4988:8fba26292a9f
Housekeeper plugin: finalizing + integration tests ok
author | Alain Mazy <am@osimis.io> |
---|---|
date | Sat, 30 Apr 2022 19:39:40 +0200 |
parents | 304514ce84ee |
children | 877bc3b96476 |
comparison
equal
deleted
inserted
replaced
4986:a25e74fad379 | 4988:8fba26292a9f |
---|---|
2848 bool hasTransferSyntax, | 2848 bool hasTransferSyntax, |
2849 DicomTransferSyntax transferSyntax, | 2849 DicomTransferSyntax transferSyntax, |
2850 bool hasPixelDataOffset, | 2850 bool hasPixelDataOffset, |
2851 uint64_t pixelDataOffset, | 2851 uint64_t pixelDataOffset, |
2852 uint64_t maximumStorageSize, | 2852 uint64_t maximumStorageSize, |
2853 unsigned int maximumPatients) | 2853 unsigned int maximumPatients, |
2854 bool isReconstruct) | |
2854 { | 2855 { |
2855 class Operations : public IReadWriteOperations | 2856 class Operations : public IReadWriteOperations |
2856 { | 2857 { |
2857 private: | 2858 private: |
2858 StoreStatus storeStatus_; | 2859 StoreStatus storeStatus_; |
2866 DicomTransferSyntax transferSyntax_; | 2867 DicomTransferSyntax transferSyntax_; |
2867 bool hasPixelDataOffset_; | 2868 bool hasPixelDataOffset_; |
2868 uint64_t pixelDataOffset_; | 2869 uint64_t pixelDataOffset_; |
2869 uint64_t maximumStorageSize_; | 2870 uint64_t maximumStorageSize_; |
2870 unsigned int maximumPatientCount_; | 2871 unsigned int maximumPatientCount_; |
2872 bool isReconstruct_; | |
2871 | 2873 |
2872 // Auto-computed fields | 2874 // Auto-computed fields |
2873 bool hasExpectedInstances_; | 2875 bool hasExpectedInstances_; |
2874 int64_t expectedInstances_; | 2876 int64_t expectedInstances_; |
2875 std::string hashPatient_; | 2877 std::string hashPatient_; |
2953 bool hasTransferSyntax, | 2955 bool hasTransferSyntax, |
2954 DicomTransferSyntax transferSyntax, | 2956 DicomTransferSyntax transferSyntax, |
2955 bool hasPixelDataOffset, | 2957 bool hasPixelDataOffset, |
2956 uint64_t pixelDataOffset, | 2958 uint64_t pixelDataOffset, |
2957 uint64_t maximumStorageSize, | 2959 uint64_t maximumStorageSize, |
2958 unsigned int maximumPatientCount) : | 2960 unsigned int maximumPatientCount, |
2961 bool isReconstruct) : | |
2959 storeStatus_(StoreStatus_Failure), | 2962 storeStatus_(StoreStatus_Failure), |
2960 instanceMetadata_(instanceMetadata), | 2963 instanceMetadata_(instanceMetadata), |
2961 dicomSummary_(dicomSummary), | 2964 dicomSummary_(dicomSummary), |
2962 attachments_(attachments), | 2965 attachments_(attachments), |
2963 metadata_(metadata), | 2966 metadata_(metadata), |
2966 hasTransferSyntax_(hasTransferSyntax), | 2969 hasTransferSyntax_(hasTransferSyntax), |
2967 transferSyntax_(transferSyntax), | 2970 transferSyntax_(transferSyntax), |
2968 hasPixelDataOffset_(hasPixelDataOffset), | 2971 hasPixelDataOffset_(hasPixelDataOffset), |
2969 pixelDataOffset_(pixelDataOffset), | 2972 pixelDataOffset_(pixelDataOffset), |
2970 maximumStorageSize_(maximumStorageSize), | 2973 maximumStorageSize_(maximumStorageSize), |
2971 maximumPatientCount_(maximumPatientCount) | 2974 maximumPatientCount_(maximumPatientCount), |
2975 isReconstruct_(isReconstruct) | |
2972 { | 2976 { |
2973 hasExpectedInstances_ = ComputeExpectedNumberOfInstances(expectedInstances_, dicomSummary); | 2977 hasExpectedInstances_ = ComputeExpectedNumberOfInstances(expectedInstances_, dicomSummary); |
2974 | 2978 |
2975 instanceMetadata_.clear(); | 2979 instanceMetadata_.clear(); |
2976 | 2980 |
3020 return; | 3024 return; |
3021 } | 3025 } |
3022 } | 3026 } |
3023 | 3027 |
3024 | 3028 |
3025 // Warn about the creation of new resources. The order must be | 3029 if (!isReconstruct_) // don't signal new resources if this is a reconstruction |
3026 // from instance to patient. | 3030 { |
3027 | 3031 // Warn about the creation of new resources. The order must be |
3028 // NB: In theory, could be sped up by grouping the underlying | 3032 // from instance to patient. |
3029 // calls to "transaction.LogChange()". However, this would only have an | 3033 |
3030 // impact when new patient/study/series get created, which | 3034 // NB: In theory, could be sped up by grouping the underlying |
3031 // occurs far less often that creating new instances. The | 3035 // calls to "transaction.LogChange()". However, this would only have an |
3032 // positive impact looks marginal in practice. | 3036 // impact when new patient/study/series get created, which |
3033 transaction.LogChange(instanceId, ChangeType_NewInstance, ResourceType_Instance, hashInstance_); | 3037 // occurs far less often that creating new instances. The |
3034 | 3038 // positive impact looks marginal in practice. |
3035 if (status.isNewSeries_) | 3039 transaction.LogChange(instanceId, ChangeType_NewInstance, ResourceType_Instance, hashInstance_); |
3036 { | 3040 |
3037 transaction.LogChange(status.seriesId_, ChangeType_NewSeries, ResourceType_Series, hashSeries_); | 3041 if (status.isNewSeries_) |
3038 } | 3042 { |
3039 | 3043 transaction.LogChange(status.seriesId_, ChangeType_NewSeries, ResourceType_Series, hashSeries_); |
3040 if (status.isNewStudy_) | 3044 } |
3041 { | 3045 |
3042 transaction.LogChange(status.studyId_, ChangeType_NewStudy, ResourceType_Study, hashStudy_); | 3046 if (status.isNewStudy_) |
3043 } | 3047 { |
3044 | 3048 transaction.LogChange(status.studyId_, ChangeType_NewStudy, ResourceType_Study, hashStudy_); |
3045 if (status.isNewPatient_) | 3049 } |
3046 { | 3050 |
3047 transaction.LogChange(status.patientId_, ChangeType_NewPatient, ResourceType_Patient, hashPatient_); | 3051 if (status.isNewPatient_) |
3048 } | 3052 { |
3049 | 3053 transaction.LogChange(status.patientId_, ChangeType_NewPatient, ResourceType_Patient, hashPatient_); |
3054 } | |
3055 } | |
3050 | 3056 |
3051 // Ensure there is enough room in the storage for the new instance | 3057 // Ensure there is enough room in the storage for the new instance |
3052 uint64_t instanceSize = 0; | 3058 uint64_t instanceSize = 0; |
3053 for (Attachments::const_iterator it = attachments_.begin(); | 3059 for (Attachments::const_iterator it = attachments_.begin(); |
3054 it != attachments_.end(); ++it) | 3060 it != attachments_.end(); ++it) |
3055 { | 3061 { |
3056 instanceSize += it->GetCompressedSize(); | 3062 instanceSize += it->GetCompressedSize(); |
3057 } | 3063 } |
3058 | 3064 |
3059 transaction.Recycle(maximumStorageSize_, maximumPatientCount_, | 3065 if (!isReconstruct_) // reconstruction should not affect recycling |
3060 instanceSize, hashPatient_ /* don't consider the current patient for recycling */); | 3066 { |
3061 | 3067 transaction.Recycle(maximumStorageSize_, maximumPatientCount_, |
3068 instanceSize, hashPatient_ /* don't consider the current patient for recycling */); | |
3069 } | |
3062 | 3070 |
3063 // Attach the files to the newly created instance | 3071 // Attach the files to the newly created instance |
3064 for (Attachments::const_iterator it = attachments_.begin(); | 3072 for (Attachments::const_iterator it = attachments_.begin(); |
3065 it != attachments_.end(); ++it) | 3073 it != attachments_.end(); ++it) |
3066 { | 3074 { |
3068 } | 3076 } |
3069 | 3077 |
3070 | 3078 |
3071 { | 3079 { |
3072 ResourcesContent content(true /* new resource, metadata can be set */); | 3080 ResourcesContent content(true /* new resource, metadata can be set */); |
3073 | 3081 |
3074 // Populate the tags of the newly-created resources | 3082 |
3075 | 3083 // Attach the user-specified metadata (in case of reconstruction, metadata_ contains all past metadata, including the system ones we want to keep) |
3076 content.AddResource(instanceId, ResourceType_Instance, dicomSummary_); | |
3077 content.AddMetadata(instanceId, MetadataType_MainDicomTagsSignature, DicomMap::GetMainDicomTagsSignature(ResourceType_Instance)); // New in Orthanc 1.11.0 | |
3078 | |
3079 if (status.isNewSeries_) | |
3080 { | |
3081 content.AddResource(status.seriesId_, ResourceType_Series, dicomSummary_); | |
3082 content.AddMetadata(status.seriesId_, MetadataType_MainDicomTagsSignature, DicomMap::GetMainDicomTagsSignature(ResourceType_Series)); // New in Orthanc 1.11.0 | |
3083 } | |
3084 | |
3085 if (status.isNewStudy_) | |
3086 { | |
3087 content.AddResource(status.studyId_, ResourceType_Study, dicomSummary_); | |
3088 content.AddMetadata(status.studyId_, MetadataType_MainDicomTagsSignature, DicomMap::GetMainDicomTagsSignature(ResourceType_Study)); // New in Orthanc 1.11.0 | |
3089 } | |
3090 | |
3091 if (status.isNewPatient_) | |
3092 { | |
3093 content.AddResource(status.patientId_, ResourceType_Patient, dicomSummary_); | |
3094 content.AddMetadata(status.patientId_, MetadataType_MainDicomTagsSignature, DicomMap::GetMainDicomTagsSignature(ResourceType_Patient)); // New in Orthanc 1.11.0 | |
3095 } | |
3096 | |
3097 | |
3098 // Attach the user-specified metadata | |
3099 | |
3100 for (MetadataMap::const_iterator | 3084 for (MetadataMap::const_iterator |
3101 it = metadata_.begin(); it != metadata_.end(); ++it) | 3085 it = metadata_.begin(); it != metadata_.end(); ++it) |
3102 { | 3086 { |
3103 switch (it->first.first) | 3087 switch (it->first.first) |
3104 { | 3088 { |
3122 default: | 3106 default: |
3123 throw OrthancException(ErrorCode_ParameterOutOfRange); | 3107 throw OrthancException(ErrorCode_ParameterOutOfRange); |
3124 } | 3108 } |
3125 } | 3109 } |
3126 | 3110 |
3127 | 3111 // Populate the tags of the newly-created resources |
3112 | |
3113 content.AddResource(instanceId, ResourceType_Instance, dicomSummary_); | |
3114 SetInstanceMetadata(content, instanceMetadata_, instanceId, MetadataType_MainDicomTagsSignature, DicomMap::GetMainDicomTagsSignature(ResourceType_Instance)); // New in Orthanc 1.11.0 | |
3115 | |
3116 if (status.isNewSeries_) | |
3117 { | |
3118 content.AddResource(status.seriesId_, ResourceType_Series, dicomSummary_); | |
3119 content.AddMetadata(status.seriesId_, MetadataType_MainDicomTagsSignature, DicomMap::GetMainDicomTagsSignature(ResourceType_Series)); // New in Orthanc 1.11.0 | |
3120 } | |
3121 | |
3122 if (status.isNewStudy_) | |
3123 { | |
3124 content.AddResource(status.studyId_, ResourceType_Study, dicomSummary_); | |
3125 content.AddMetadata(status.studyId_, MetadataType_MainDicomTagsSignature, DicomMap::GetMainDicomTagsSignature(ResourceType_Study)); // New in Orthanc 1.11.0 | |
3126 } | |
3127 | |
3128 if (status.isNewPatient_) | |
3129 { | |
3130 content.AddResource(status.patientId_, ResourceType_Patient, dicomSummary_); | |
3131 content.AddMetadata(status.patientId_, MetadataType_MainDicomTagsSignature, DicomMap::GetMainDicomTagsSignature(ResourceType_Patient)); // New in Orthanc 1.11.0 | |
3132 } | |
3133 | |
3128 // Attach the auto-computed metadata for the patient/study/series levels | 3134 // Attach the auto-computed metadata for the patient/study/series levels |
3129 std::string now = SystemToolbox::GetNowIsoString(true /* use UTC time (not local time) */); | 3135 std::string now = SystemToolbox::GetNowIsoString(true /* use UTC time (not local time) */); |
3130 content.AddMetadata(status.seriesId_, MetadataType_LastUpdate, now); | 3136 content.AddMetadata(status.seriesId_, MetadataType_LastUpdate, now); |
3131 content.AddMetadata(status.studyId_, MetadataType_LastUpdate, now); | 3137 content.AddMetadata(status.studyId_, MetadataType_LastUpdate, now); |
3132 content.AddMetadata(status.patientId_, MetadataType_LastUpdate, now); | 3138 content.AddMetadata(status.patientId_, MetadataType_LastUpdate, now); |
3142 // New in Orthanc 1.9.0 | 3148 // New in Orthanc 1.9.0 |
3143 content.AddMetadata(status.seriesId_, MetadataType_RemoteAet, | 3149 content.AddMetadata(status.seriesId_, MetadataType_RemoteAet, |
3144 origin_.GetRemoteAetC()); | 3150 origin_.GetRemoteAetC()); |
3145 } | 3151 } |
3146 | 3152 |
3147 | |
3148 // Attach the auto-computed metadata for the instance level, | |
3149 // reflecting these additions into the input metadata map | |
3150 SetInstanceMetadata(content, instanceMetadata_, instanceId, | |
3151 MetadataType_Instance_ReceptionDate, now); | |
3152 SetInstanceMetadata(content, instanceMetadata_, instanceId, MetadataType_RemoteAet, | |
3153 origin_.GetRemoteAetC()); | |
3154 SetInstanceMetadata(content, instanceMetadata_, instanceId, MetadataType_Instance_Origin, | |
3155 EnumerationToString(origin_.GetRequestOrigin())); | |
3156 | |
3157 | |
3158 if (hasTransferSyntax_) | 3153 if (hasTransferSyntax_) |
3159 { | 3154 { |
3160 // New in Orthanc 1.2.0 | 3155 // New in Orthanc 1.2.0 |
3161 SetInstanceMetadata(content, instanceMetadata_, instanceId, | 3156 SetInstanceMetadata(content, instanceMetadata_, instanceId, |
3162 MetadataType_Instance_TransferSyntax, | 3157 MetadataType_Instance_TransferSyntax, |
3163 GetTransferSyntaxUid(transferSyntax_)); | 3158 GetTransferSyntaxUid(transferSyntax_)); |
3164 } | 3159 } |
3165 | 3160 |
3166 { | 3161 if (!isReconstruct_) // don't change origin metadata |
3162 { | |
3163 // Attach the auto-computed metadata for the instance level, | |
3164 // reflecting these additions into the input metadata map | |
3165 SetInstanceMetadata(content, instanceMetadata_, instanceId, | |
3166 MetadataType_Instance_ReceptionDate, now); | |
3167 SetInstanceMetadata(content, instanceMetadata_, instanceId, MetadataType_RemoteAet, | |
3168 origin_.GetRemoteAetC()); | |
3169 SetInstanceMetadata(content, instanceMetadata_, instanceId, MetadataType_Instance_Origin, | |
3170 EnumerationToString(origin_.GetRequestOrigin())); | |
3171 | |
3167 std::string s; | 3172 std::string s; |
3168 | 3173 |
3169 if (origin_.LookupRemoteIp(s)) | 3174 if (origin_.LookupRemoteIp(s)) |
3170 { | 3175 { |
3171 // New in Orthanc 1.4.0 | 3176 // New in Orthanc 1.4.0 |
3268 }; | 3273 }; |
3269 | 3274 |
3270 | 3275 |
3271 Operations operations(instanceMetadata, dicomSummary, attachments, metadata, origin, | 3276 Operations operations(instanceMetadata, dicomSummary, attachments, metadata, origin, |
3272 overwrite, hasTransferSyntax, transferSyntax, hasPixelDataOffset, | 3277 overwrite, hasTransferSyntax, transferSyntax, hasPixelDataOffset, |
3273 pixelDataOffset, maximumStorageSize, maximumPatients); | 3278 pixelDataOffset, maximumStorageSize, maximumPatients, isReconstruct); |
3274 Apply(operations); | 3279 Apply(operations); |
3275 return operations.GetStoreStatus(); | 3280 return operations.GetStoreStatus(); |
3276 } | 3281 } |
3277 | 3282 |
3278 | 3283 |