# HG changeset patch # User Alain Mazy # Date 1733735239 -3600 # Node ID bfae0fc2ea1ba7df1244bb25d45cf054e6ac022c # Parent 866defb5f95ad99b993423bf3a2c6a420bc2c7fb Started to work on handling errors as warnings when trying to store instances whose SOPClassUID has not been accepted during the negotiation. Work to be finalized later diff -r 866defb5f95a -r bfae0fc2ea1b OrthancFramework/Sources/DicomNetworking/DicomStoreUserConnection.cpp --- a/OrthancFramework/Sources/DicomNetworking/DicomStoreUserConnection.cpp Mon Dec 09 10:04:34 2024 +0100 +++ b/OrthancFramework/Sources/DicomNetworking/DicomStoreUserConnection.cpp Mon Dec 09 10:07:19 2024 +0100 @@ -377,7 +377,8 @@ DcmFileFormat& dicom, bool hasMoveOriginator, const std::string& moveOriginatorAET, - uint16_t moveOriginatorID) + uint16_t moveOriginatorID, + bool ignoreErrors) { DicomTransferSyntax transferSyntax; LookupParameters(sopClassUid, sopInstanceUid, transferSyntax, dicom); @@ -388,12 +389,21 @@ if (!NegotiatePresentationContext(presID, sopClassUid, transferSyntax, proposeUncompressedSyntaxes_, DicomTransferSyntax_LittleEndianExplicit)) { - throw OrthancException(ErrorCode_NetworkProtocol, - "No valid presentation context was negotiated for " - "SOP class UID [" + sopClassUid + "] and transfer " - "syntax [" + GetTransferSyntaxUid(transferSyntax) + "] " - "while sending to modality [" + - parameters_.GetRemoteModality().GetApplicationEntityTitle() + "]"); + if (ignoreErrors) + { + LOG(INFO) << "No valid presentation context was negotiated for SOP class UID [" << sopClassUid << "] and transfer " + "syntax [" << GetTransferSyntaxUid(transferSyntax) << "] " + "while sending to modality [" << parameters_.GetRemoteModality().GetApplicationEntityTitle() << "]"; + } + else + { + throw OrthancException(ErrorCode_NetworkProtocol, + "No valid presentation context was negotiated for " + "SOP class UID [" + sopClassUid + "] and transfer " + "syntax [" + GetTransferSyntaxUid(transferSyntax) + "] " + "while sending to modality [" + + parameters_.GetRemoteModality().GetApplicationEntityTitle() + "]"); + } } // Prepare the transmission of data @@ -469,7 +479,8 @@ size_t size, bool hasMoveOriginator, const std::string& moveOriginatorAET, - uint16_t moveOriginatorID) + uint16_t moveOriginatorID, + bool ignoreErrors) { std::unique_ptr dicom( FromDcmtkBridge::LoadFromMemoryBuffer(buffer, size)); @@ -479,7 +490,7 @@ throw OrthancException(ErrorCode_InternalError); } - Store(sopClassUid, sopInstanceUid, *dicom, hasMoveOriginator, moveOriginatorAET, moveOriginatorID); + Store(sopClassUid, sopInstanceUid, *dicom, hasMoveOriginator, moveOriginatorAET, moveOriginatorID, ignoreErrors); } @@ -523,7 +534,8 @@ DicomTransferSyntax preferredTransferSyntax, bool hasMoveOriginator, const std::string& moveOriginatorAET, - uint16_t moveOriginatorID) + uint16_t moveOriginatorID, + bool ignoreErrors) { std::unique_ptr dicom(FromDcmtkBridge::LoadFromMemoryBuffer(buffer, size)); if (dicom.get() == NULL || @@ -540,15 +552,24 @@ 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 (ignoreErrors) + { + LOG(WARNING) << "Cannot C-Store an instance of SOPClassUID " << + sopClassUid + ", the destination has not accepted any TransferSyntax for this SOPClassUID."; // TODO: add an option to enable/disable this warning + 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()) { // No need for transcoding Store(sopClassUid, sopInstanceUid, *dicom, - hasMoveOriginator, moveOriginatorAET, moveOriginatorID); + hasMoveOriginator, moveOriginatorAET, moveOriginatorID, ignoreErrors); } else { @@ -639,7 +660,7 @@ else { Store(sopClassUid, sopInstanceUid, transcoded.GetParsed(), - hasMoveOriginator, moveOriginatorAET, moveOriginatorID); + hasMoveOriginator, moveOriginatorAET, moveOriginatorID, ignoreErrors); } } else @@ -669,10 +690,11 @@ size_t size, bool hasMoveOriginator, const std::string& moveOriginatorAET, - uint16_t moveOriginatorID) + uint16_t moveOriginatorID, + bool ignoreErrors) { Transcode(sopClassUid, sopInstanceUid, transcoder, buffer, size, DicomTransferSyntax_LittleEndianExplicit, - hasMoveOriginator, moveOriginatorAET, moveOriginatorID); + hasMoveOriginator, moveOriginatorAET, moveOriginatorID, ignoreErrors); } #endif } diff -r 866defb5f95a -r bfae0fc2ea1b OrthancFramework/Sources/DicomNetworking/DicomStoreUserConnection.h --- a/OrthancFramework/Sources/DicomNetworking/DicomStoreUserConnection.h Mon Dec 09 10:04:34 2024 +0100 +++ b/OrthancFramework/Sources/DicomNetworking/DicomStoreUserConnection.h Mon Dec 09 10:07:19 2024 +0100 @@ -130,7 +130,8 @@ DcmFileFormat& dicom, bool hasMoveOriginator, const std::string& moveOriginatorAET, - uint16_t moveOriginatorID); + uint16_t moveOriginatorID, + bool ignoreErrors); void Store(std::string& sopClassUid, std::string& sopInstanceUid, @@ -138,7 +139,8 @@ size_t size, bool hasMoveOriginator, const std::string& moveOriginatorAET, - uint16_t moveOriginatorID); + uint16_t moveOriginatorID, + bool ignoreErrors); void LookupParameters(std::string& sopClassUid, std::string& sopInstanceUid, @@ -154,7 +156,8 @@ DicomTransferSyntax preferredTransferSyntax, bool hasMoveOriginator, const std::string& moveOriginatorAET, - uint16_t moveOriginatorID); + uint16_t moveOriginatorID, + bool errorsAsWarning); #endif #if ORTHANC_ENABLE_DCMTK_TRANSCODING == 1 @@ -165,7 +168,8 @@ size_t size, bool hasMoveOriginator, const std::string& moveOriginatorAET, - uint16_t moveOriginatorID); + uint16_t moveOriginatorID, + bool errorsAsWarning); #endif }; } diff -r 866defb5f95a -r bfae0fc2ea1b OrthancFramework/UnitTestsSources/FromDcmtkTests.cpp --- a/OrthancFramework/UnitTestsSources/FromDcmtkTests.cpp Mon Dec 09 10:04:34 2024 +0100 +++ b/OrthancFramework/UnitTestsSources/FromDcmtkTests.cpp Mon Dec 09 10:07:19 2024 +0100 @@ -3583,7 +3583,7 @@ try { scu.Transcode(c, k, transcoder, source.c_str(), source.size(), - DicomTransferSyntax_LittleEndianExplicit, false, "", 0); + DicomTransferSyntax_LittleEndianExplicit, false, "", 0, false); } catch (OrthancException& e) { diff -r 866defb5f95a -r bfae0fc2ea1b OrthancServer/Sources/OrthancGetRequestHandler.cpp --- a/OrthancServer/Sources/OrthancGetRequestHandler.cpp Mon Dec 09 10:04:34 2024 +0100 +++ b/OrthancServer/Sources/OrthancGetRequestHandler.cpp Mon Dec 09 10:07:19 2024 +0100 @@ -250,10 +250,9 @@ { failedCount_++; AddFailedUIDInstance(sopInstanceUid); - throw OrthancException(ErrorCode_NetworkProtocol, - "C-GET SCP: storeSCU: No presentation context for: (" + - std::string(dcmSOPClassUIDToModality(sopClassUid.c_str(), "OT")) + - ") " + sopClassUid); + LOG(WARNING) << "C-GET SCP: storeSCU: No presentation context for: (" + << dcmSOPClassUIDToModality(sopClassUid.c_str(), "OT") << ") " << sopClassUid; + return true; } else { diff -r 866defb5f95a -r bfae0fc2ea1b OrthancServer/Sources/OrthancMoveRequestHandler.cpp --- a/OrthancServer/Sources/OrthancMoveRequestHandler.cpp Mon Dec 09 10:04:34 2024 +0100 +++ b/OrthancServer/Sources/OrthancMoveRequestHandler.cpp Mon Dec 09 10:07:19 2024 +0100 @@ -110,7 +110,7 @@ std::string sopClassUid, sopInstanceUid; // Unused context_.StoreWithTranscoding(sopClassUid, sopInstanceUid, *connection_, dicom, - true, originatorAet_, originatorId_); + true, originatorAet_, originatorId_, false); // TODO: ignoreErrors return Status_Success; } diff -r 866defb5f95a -r bfae0fc2ea1b OrthancServer/Sources/OrthancRestApi/OrthancRestModalities.cpp --- a/OrthancServer/Sources/OrthancRestApi/OrthancRestModalities.cpp Mon Dec 09 10:04:34 2024 +0100 +++ b/OrthancServer/Sources/OrthancRestApi/OrthancRestModalities.cpp Mon Dec 09 10:07:19 2024 +0100 @@ -1577,7 +1577,7 @@ connection.Store(sopClassUid, sopInstanceUid, call.GetBodyData(), call.GetBodySize(), false /* Not a C-MOVE */, - "", 0); + "", 0, false); Json::Value answer = Json::objectValue; answer[SOP_CLASS_UID] = sopClassUid; diff -r 866defb5f95a -r bfae0fc2ea1b OrthancServer/Sources/ServerContext.cpp --- a/OrthancServer/Sources/ServerContext.cpp Mon Dec 09 10:04:34 2024 +0100 +++ b/OrthancServer/Sources/ServerContext.cpp Mon Dec 09 10:07:19 2024 +0100 @@ -2007,7 +2007,8 @@ const std::string& dicom, bool hasMoveOriginator, const std::string& moveOriginatorAet, - uint16_t moveOriginatorId) + uint16_t moveOriginatorId, + bool ignoreErrors) { const void* data = dicom.empty() ? NULL : dicom.c_str(); const RemoteModalityParameters& modality = connection.GetParameters().GetRemoteModality(); @@ -2016,12 +2017,12 @@ !modality.IsTranscodingAllowed()) { connection.Store(sopClassUid, sopInstanceUid, data, dicom.size(), - hasMoveOriginator, moveOriginatorAet, moveOriginatorId); + hasMoveOriginator, moveOriginatorAet, moveOriginatorId, ignoreErrors); } else { connection.Transcode(sopClassUid, sopInstanceUid, *this, data, dicom.size(), preferredTransferSyntax_, - hasMoveOriginator, moveOriginatorAet, moveOriginatorId); + hasMoveOriginator, moveOriginatorAet, moveOriginatorId, ignoreErrors); } } diff -r 866defb5f95a -r bfae0fc2ea1b OrthancServer/Sources/ServerContext.h --- a/OrthancServer/Sources/ServerContext.h Mon Dec 09 10:04:34 2024 +0100 +++ b/OrthancServer/Sources/ServerContext.h Mon Dec 09 10:07:19 2024 +0100 @@ -577,7 +577,8 @@ const std::string& dicom, bool hasMoveOriginator, const std::string& moveOriginatorAet, - uint16_t moveOriginatorId); + uint16_t moveOriginatorId, + bool ignoreErrors); // This method can be used even if the global option // "TranscodeDicomProtocol" is set to "false" diff -r 866defb5f95a -r bfae0fc2ea1b OrthancServer/Sources/ServerJobs/DicomModalityStoreJob.cpp --- a/OrthancServer/Sources/ServerJobs/DicomModalityStoreJob.cpp Mon Dec 09 10:04:34 2024 +0100 +++ b/OrthancServer/Sources/ServerJobs/DicomModalityStoreJob.cpp Mon Dec 09 10:07:19 2024 +0100 @@ -65,7 +65,7 @@ std::string sopClassUid, sopInstanceUid; context_.StoreWithTranscoding(sopClassUid, sopInstanceUid, *connection_, dicom, - HasMoveOriginator(), moveOriginatorAet_, moveOriginatorId_); + HasMoveOriginator(), moveOriginatorAet_, moveOriginatorId_, IsPermissive()); if (storageCommitment_) { diff -r 866defb5f95a -r bfae0fc2ea1b OrthancServer/Sources/ServerJobs/Operations/StoreScuOperation.cpp --- a/OrthancServer/Sources/ServerJobs/Operations/StoreScuOperation.cpp Mon Dec 09 10:04:34 2024 +0100 +++ b/OrthancServer/Sources/ServerJobs/Operations/StoreScuOperation.cpp Mon Dec 09 10:07:19 2024 +0100 @@ -56,7 +56,7 @@ std::string sopClassUid, sopInstanceUid; // Unused context_.StoreWithTranscoding(sopClassUid, sopInstanceUid, lock.GetConnection(), dicom, - false /* Not a C-MOVE */, "", 0); + false /* Not a C-MOVE */, "", 0, false); // TODO: get "permissive from job" } catch (OrthancException& e) {