# HG changeset patch # User Alain Mazy # Date 1588156011 -7200 # Node ID 09798f2b985f0dfb474016add832671e858ce533 # Parent c23ef85c7d9c73661e09d6309f727cbd23de8213 added a Timeout argument to every DICOM command + 'TargetAet' not mandatory anymore in /retrieve diff -r c23ef85c7d9c -r 09798f2b985f Core/DicomNetworking/DicomControlUserConnection.cpp --- a/Core/DicomNetworking/DicomControlUserConnection.cpp Tue Apr 28 16:46:04 2020 +0200 +++ b/Core/DicomNetworking/DicomControlUserConnection.cpp Wed Apr 29 12:26:51 2020 +0200 @@ -669,6 +669,10 @@ MoveInternal(targetAet, ResourceType_Instance, query); } + void DicomControlUserConnection::SetTimeout(uint32_t seconds) + { + parameters_.SetTimeout(seconds); + } void DicomControlUserConnection::FindWorklist(DicomFindAnswers& result, ParsedDicomFile& query) diff -r c23ef85c7d9c -r 09798f2b985f Core/DicomNetworking/DicomControlUserConnection.h --- a/Core/DicomNetworking/DicomControlUserConnection.h Tue Apr 28 16:46:04 2020 +0200 +++ b/Core/DicomNetworking/DicomControlUserConnection.h Wed Apr 29 12:26:51 2020 +0200 @@ -108,5 +108,7 @@ void FindWorklist(DicomFindAnswers& result, ParsedDicomFile& query); + + void SetTimeout(uint32_t seconds); // 0 = no timeout }; } diff -r c23ef85c7d9c -r 09798f2b985f Core/DicomNetworking/DicomStoreUserConnection.h --- a/Core/DicomNetworking/DicomStoreUserConnection.h Tue Apr 28 16:46:04 2020 +0200 +++ b/Core/DicomNetworking/DicomStoreUserConnection.h Wed Apr 29 12:26:51 2020 +0200 @@ -95,6 +95,11 @@ return parameters_; } + void SetTimeout(int timeout) + { + parameters_.SetTimeout(timeout); + } + void SetCommonClassesProposed(bool proposed) { proposeCommonClasses_ = proposed; diff -r c23ef85c7d9c -r 09798f2b985f Core/SerializationToolbox.cpp --- a/Core/SerializationToolbox.cpp Tue Apr 28 16:46:04 2020 +0200 +++ b/Core/SerializationToolbox.cpp Wed Apr 29 12:26:51 2020 +0200 @@ -98,6 +98,21 @@ } + int ReadInteger(const Json::Value& value, + const std::string& field, + int defaultValue) + { + if (value.isMember(field.c_str())) + { + return ReadInteger(value, field); + } + else + { + return defaultValue; + } + } + + unsigned int ReadUnsignedInteger(const Json::Value& value, const std::string& field) { diff -r c23ef85c7d9c -r 09798f2b985f Core/SerializationToolbox.h --- a/Core/SerializationToolbox.h Tue Apr 28 16:46:04 2020 +0200 +++ b/Core/SerializationToolbox.h Wed Apr 29 12:26:51 2020 +0200 @@ -49,6 +49,10 @@ int ReadInteger(const Json::Value& value, const std::string& field); + int ReadInteger(const Json::Value& value, + const std::string& field, + int defaultValue); + unsigned int ReadUnsignedInteger(const Json::Value& value, const std::string& field); diff -r c23ef85c7d9c -r 09798f2b985f NEWS --- a/NEWS Tue Apr 28 16:46:04 2020 +0200 +++ b/NEWS Wed Apr 29 12:26:51 2020 +0200 @@ -4,9 +4,13 @@ REST API -------- +* API version has been upgraded to 7 * Improved: - "/instances/../modify": it is now possible to "Keep" the "SOPInstanceUID". Note that it was already possible to "Replace" it. + - added "Timeout" parameter to every DICOM operation + - "/queries/.../answers/../retrieve": "TargetAet" not mandatory anymore + (defaults to the local AET) diff -r c23ef85c7d9c -r 09798f2b985f OrthancServer/OrthancRestApi/OrthancRestModalities.cpp --- a/OrthancServer/OrthancRestApi/OrthancRestModalities.cpp Tue Apr 28 16:46:04 2020 +0200 +++ b/OrthancServer/OrthancRestApi/OrthancRestModalities.cpp Wed Apr 29 12:26:51 2020 +0200 @@ -80,10 +80,20 @@ RemoteModalityParameters remote = MyGetModalityUsingSymbolicName(call.GetUriComponent("id", "")); + Json::Value request; + call.ParseJsonRequest(request); + int timeout = Toolbox::GetJsonIntegerField(request, "Timeout", -1); + try { DicomControlUserConnection connection(localAet, remote); - + + // New in Orthanc 1.7.0 + if (timeout != -1) + { + connection.SetTimeout(timeout); + } + if (connection.Echo()) { // Echo has succeeded @@ -605,16 +615,25 @@ ServerContext& context = OrthancRestApi::GetContext(call); std::string targetAet; + int timeout = -1; Json::Value body; if (call.ParseJsonRequest(body)) { - targetAet = SerializationToolbox::ReadString(body, "TargetAet"); + targetAet = Toolbox::GetJsonStringField(body, "TargetAet", context.GetDefaultLocalApplicationEntityTitle()); + timeout = Toolbox::GetJsonIntegerField(body, "Timeout", -1); } else { body = Json::objectValue; - call.BodyToString(targetAet); + if (call.GetBodySize() > 0) + { + call.BodyToString(targetAet); + } + else + { + targetAet = context.GetDefaultLocalApplicationEntityTitle(); + } } std::unique_ptr job(new DicomMoveScuJob(context)); @@ -624,6 +643,7 @@ job->SetTargetAet(targetAet); job->SetLocalAet(query.GetHandler().GetLocalAet()); job->SetRemoteModality(query.GetHandler().GetRemoteModality()); + job->SetTimeout(timeout); LOG(WARNING) << "Driving C-Move SCU on remote modality " << query.GetHandler().GetRemoteModality().GetApplicationEntityTitle() @@ -953,6 +973,8 @@ (request, "MoveOriginatorAet", context.GetDefaultLocalApplicationEntityTitle()); int moveOriginatorID = Toolbox::GetJsonIntegerField (request, "MoveOriginatorID", 0 /* By default, not a C-MOVE */); + int timeout = Toolbox::GetJsonIntegerField + (request, "Timeout", -1); job->SetLocalAet(localAet); job->SetRemoteModality(MyGetModalityUsingSymbolicName(remote)); @@ -968,6 +990,9 @@ job->EnableStorageCommitment(true); } + // New in Orthanc 1.7.0 + job->SetTimeout(timeout); + OrthancRestApi::GetApi(call).SubmitCommandsJob (call, job.release(), true /* synchronous by default */, request); } @@ -1022,11 +1047,18 @@ (request, "LocalAet", context.GetDefaultLocalApplicationEntityTitle()); std::string targetAet = Toolbox::GetJsonStringField (request, "TargetAet", context.GetDefaultLocalApplicationEntityTitle()); + int timeout = Toolbox::GetJsonIntegerField + (request, "Timeout", -1); const RemoteModalityParameters source = MyGetModalityUsingSymbolicName(call.GetUriComponent("id", "")); DicomControlUserConnection connection(localAet, source); + + if (timeout > -1) + { + connection.SetTimeout(timeout); + } for (Json::Value::ArrayIndex i = 0; i < request[KEY_RESOURCES].size(); i++) { diff -r c23ef85c7d9c -r 09798f2b985f OrthancServer/ServerJobs/DicomModalityStoreJob.cpp --- a/OrthancServer/ServerJobs/DicomModalityStoreJob.cpp Tue Apr 28 16:46:04 2020 +0200 +++ b/OrthancServer/ServerJobs/DicomModalityStoreJob.cpp Wed Apr 29 12:26:51 2020 +0200 @@ -49,6 +49,11 @@ if (connection_.get() == NULL) { connection_.reset(new DicomStoreUserConnection(localAet_, remote_)); + + if (timeout_ > -1) + { + connection_->SetTimeout(timeout_); + } } } @@ -276,6 +281,7 @@ static const char* MOVE_ORIGINATOR_AET = "MoveOriginatorAet"; static const char* MOVE_ORIGINATOR_ID = "MoveOriginatorId"; static const char* STORAGE_COMMITMENT = "StorageCommitment"; + static const char* TIMEOUT = "Timeout"; DicomModalityStoreJob::DicomModalityStoreJob(ServerContext& context, @@ -289,6 +295,9 @@ moveOriginatorId_ = static_cast (SerializationToolbox::ReadUnsignedInteger(serialized, MOVE_ORIGINATOR_ID)); EnableStorageCommitment(SerializationToolbox::ReadBoolean(serialized, STORAGE_COMMITMENT)); + + // New in Orthanc in 1.7.0 + timeout_ = SerializationToolbox::ReadInteger(serialized, TIMEOUT, -1); } @@ -305,6 +314,7 @@ target[MOVE_ORIGINATOR_AET] = moveOriginatorAet_; target[MOVE_ORIGINATOR_ID] = moveOriginatorId_; target[STORAGE_COMMITMENT] = storageCommitment_; + target[TIMEOUT] = timeout_; return true; } } diff -r c23ef85c7d9c -r 09798f2b985f OrthancServer/ServerJobs/DicomModalityStoreJob.h --- a/OrthancServer/ServerJobs/DicomModalityStoreJob.h Tue Apr 28 16:46:04 2020 +0200 +++ b/OrthancServer/ServerJobs/DicomModalityStoreJob.h Wed Apr 29 12:26:51 2020 +0200 @@ -49,6 +49,7 @@ ServerContext& context_; std::string localAet_; RemoteModalityParameters remote_; + int timeout_; std::string moveOriginatorAet_; uint16_t moveOriginatorId_; std::unique_ptr connection_; @@ -88,6 +89,16 @@ void SetRemoteModality(const RemoteModalityParameters& remote); + void SetTimeout(int timeout) + { + timeout_ = timeout; + } + + int GetTimeout() const + { + return timeout_; + } + bool HasMoveOriginator() const { return moveOriginatorId_ != 0; diff -r c23ef85c7d9c -r 09798f2b985f OrthancServer/ServerJobs/DicomMoveScuJob.cpp --- a/OrthancServer/ServerJobs/DicomMoveScuJob.cpp Tue Apr 28 16:46:04 2020 +0200 +++ b/OrthancServer/ServerJobs/DicomMoveScuJob.cpp Wed Apr 29 12:26:51 2020 +0200 @@ -40,6 +40,7 @@ static const char* const TARGET_AET = "TargetAet"; static const char* const REMOTE = "Remote"; static const char* const QUERY = "Query"; +static const char* const TIMEOUT = "Timeout"; namespace Orthanc { @@ -99,6 +100,11 @@ connection_.reset(new DicomControlUserConnection(localAet_, remote_)); } + if (timeout_ > -1) + { + connection_->SetTimeout(timeout_); + } + connection_->Move(targetAet_, findAnswer); } @@ -214,6 +220,9 @@ { query_ = serialized[QUERY]; } + + // New in Orthanc in 1.7.0 + timeout_ = SerializationToolbox::ReadInteger(serialized, TIMEOUT, -1); } @@ -228,6 +237,7 @@ target[LOCAL_AET] = localAet_; target[TARGET_AET] = targetAet_; target[QUERY] = query_; + target[TIMEOUT] = timeout_; remote_.Serialize(target[REMOTE], true /* force advanced format */); return true; } diff -r c23ef85c7d9c -r 09798f2b985f OrthancServer/ServerJobs/DicomMoveScuJob.h --- a/OrthancServer/ServerJobs/DicomMoveScuJob.h Tue Apr 28 16:46:04 2020 +0200 +++ b/OrthancServer/ServerJobs/DicomMoveScuJob.h Wed Apr 29 12:26:51 2020 +0200 @@ -53,6 +53,7 @@ std::string localAet_; std::string targetAet_; RemoteModalityParameters remote_; + int timeout_; Json::Value query_; std::unique_ptr connection_; @@ -95,6 +96,17 @@ void SetRemoteModality(const RemoteModalityParameters& remote); + void SetTimeout(int timeout) + { + timeout_ = timeout; + } + + int GetTimeout() const + { + return timeout_; + } + + virtual void Stop(JobStopReason reason); virtual void GetJobType(std::string& target) diff -r c23ef85c7d9c -r 09798f2b985f Resources/CMake/OrthancFrameworkParameters.cmake --- a/Resources/CMake/OrthancFrameworkParameters.cmake Tue Apr 28 16:46:04 2020 +0200 +++ b/Resources/CMake/OrthancFrameworkParameters.cmake Wed Apr 29 12:26:51 2020 +0200 @@ -17,7 +17,7 @@ # Version of the Orthanc API, can be retrieved from "/system" URI in # order to check whether new URI endpoints are available even if using # the mainline version of Orthanc -set(ORTHANC_API_VERSION "6") +set(ORTHANC_API_VERSION "7") #####################################################################