Mercurial > hg > orthanc
changeset 6571:3eafc8b4db4e
PermissiveStoreSopClasses
| author | Alain Mazy <am@orthanc.team> |
|---|---|
| date | Tue, 27 Jan 2026 12:14:45 +0100 |
| parents | bb56a9cccf75 |
| children | 43ff4470024d |
| files | NEWS OrthancFramework/Sources/DicomNetworking/DicomStoreUserConnection.cpp OrthancFramework/Sources/DicomNetworking/RemoteModalityParameters.cpp OrthancFramework/Sources/DicomNetworking/RemoteModalityParameters.h OrthancServer/Resources/Configuration.json |
| diffstat | 5 files changed, 45 insertions(+), 4 deletions(-) [+] |
line wrap: on
line diff
--- a/NEWS Tue Jan 20 09:19:56 2026 +0100 +++ b/NEWS Tue Jan 27 12:14:45 2026 +0100 @@ -4,6 +4,13 @@ General ------- +General +------- + +* New configuration "PermissiveStoreSopClasses" in "DicomModalities" to ignore errors when + a modality does not accept to receive the given SOP Classes. + + REST API --------
--- a/OrthancFramework/Sources/DicomNetworking/DicomStoreUserConnection.cpp Tue Jan 20 09:19:56 2026 +0100 +++ b/OrthancFramework/Sources/DicomNetworking/DicomStoreUserConnection.cpp Tue Jan 27 12:14:45 2026 +0100 @@ -547,8 +547,16 @@ if (accepted.size() == 0) { - throw OrthancException(ErrorCode_NoPresentationContext, "Cannot C-Store an instance of SOPClassUID " + - sopClassUid + ", the destination has not accepted any TransferSyntax for this SOPClassUID."); + if (parameters_.GetRemoteModality().IsPermissiveStoreSopClassUid(sopClassUid)) + { + LOG(INFO) << "Permissive SopClassUid '" << sopClassUid << "' is not accepted by '" << parameters_.GetRemoteModality().GetApplicationEntityTitle() << "'"; + return; + } + else + { + throw OrthancException(ErrorCode_NoPresentationContext, "Cannot C-Store an instance of SOPClassUID " + + sopClassUid + ", the destination has not accepted any TransferSyntax for this SOPClassUID."); + } } if (accepted.find(sourceSyntax) != accepted.end())
--- a/OrthancFramework/Sources/DicomNetworking/RemoteModalityParameters.cpp Tue Jan 20 09:19:56 2026 +0100 +++ b/OrthancFramework/Sources/DicomNetworking/RemoteModalityParameters.cpp Tue Jan 27 12:14:45 2026 +0100 @@ -51,6 +51,7 @@ static const char* KEY_LOCAL_AET = "LocalAet"; static const char* KEY_TIMEOUT = "Timeout"; static const char* KEY_RETRIEVE_METHOD = "RetrieveMethod"; +static const char* KEY_PERMISSIVE_STORE_SOP_CLASSES = "PermissiveStoreSopClasses"; namespace Orthanc @@ -74,6 +75,7 @@ localAet_.clear(); timeout_ = 0; retrieveMethod_ = RetrieveMethod_SystemDefault; + permissiveStoreSopClasses_.clear(); } @@ -321,6 +323,11 @@ retrieveMethod_ = RetrieveMethod_SystemDefault; } + if (serialized.isMember(KEY_PERMISSIVE_STORE_SOP_CLASSES)) + { + SerializationToolbox::ReadSetOfStrings(permissiveStoreSopClasses_, serialized[KEY_PERMISSIVE_STORE_SOP_CLASSES]); + } + } @@ -413,6 +420,7 @@ !allowNEventReport_ || !allowTranscoding_ || useDicomTls_ || + permissiveStoreSopClasses_.size() > 0 || HasLocalAet()); } @@ -441,6 +449,7 @@ target[KEY_LOCAL_AET] = localAet_; target[KEY_TIMEOUT] = timeout_; target[KEY_RETRIEVE_METHOD] = EnumerationToString(retrieveMethod_); + SerializationToolbox::WriteSetOfStrings(target, permissiveStoreSopClasses_, KEY_PERMISSIVE_STORE_SOP_CLASSES); } else { @@ -545,4 +554,9 @@ { retrieveMethod_ = retrieveMethod; } + + bool RemoteModalityParameters::IsPermissiveStoreSopClassUid(const std::string& sopClassUid) const + { + return permissiveStoreSopClasses_.find(sopClassUid) != permissiveStoreSopClasses_.end(); + } }
--- a/OrthancFramework/Sources/DicomNetworking/RemoteModalityParameters.h Tue Jan 20 09:19:56 2026 +0100 +++ b/OrthancFramework/Sources/DicomNetworking/RemoteModalityParameters.h Tue Jan 27 12:14:45 2026 +0100 @@ -28,6 +28,7 @@ #include <stdint.h> #include <string> +#include <set> #include <json/value.h> namespace Orthanc @@ -52,7 +53,8 @@ std::string localAet_; uint32_t timeout_; RetrieveMethod retrieveMethod_; // New in Orthanc 1.12.6 - + std::set<std::string> permissiveStoreSopClasses_; // New in 1.12.11: a list of sop classes that will not generate an error if they are not accepted by the remote modality + void Clear(); void UnserializeArray(const Json::Value& serialized); @@ -124,5 +126,6 @@ void SetRetrieveMethod(RetrieveMethod retrieveMethod); + bool IsPermissiveStoreSopClassUid(const std::string& sopClassUid) const; }; }
--- a/OrthancServer/Resources/Configuration.json Tue Jan 20 09:19:56 2026 +0100 +++ b/OrthancServer/Resources/Configuration.json Tue Jan 27 12:14:45 2026 +0100 @@ -513,6 +513,14 @@ * The "RetrieveMethod" option allows one to overwrite the global * "DicomDefaultRetrieveMethod" configuration option for this * specific modality. (Allowed values: "C-MOVE" or "C-GET"). + * + * The "PermissiveStoreSopClasses" option allows one to ignore + * errors when a modality does not accept to receive the given + * SOP Classes. + * E.g. CVI42 does not accept Encapsulated PDF files; by setting + * "PermissiveStoreSopClasses": ["1.2.840.10008.5.1.4.1.1.104.1"], + * a C-Store to CVI42 will be able to complete even if the study + * contains an encapsulated PDF. **/ //"untrusted" : { // "AET" : "ORTHANC", @@ -530,7 +538,8 @@ // "UseDicomTls" : false, // new in 1.9.0 // "LocalAet" : "HELLO", // new in 1.9.0 // "Timeout" : 60, // new in 1.9.1 - // "RetrieveMethod": "C-MOVE" // new in 1.12.6 + // "RetrieveMethod": "C-MOVE", // new in 1.12.6 + // "PermissiveStoreSopClasses": [] // new in 1.12.11 //} },
