Mercurial > hg > orthanc-dicomweb
changeset 318:1f948ba78c5d refactoring
control over job parameters for WadoRetrieveJob
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Thu, 20 Jun 2019 20:23:47 +0200 |
parents | ffe1c92c73c7 |
children | 59182b13a58c |
files | Plugin/Configuration.cpp Plugin/Configuration.h Plugin/DicomWebClient.cpp Plugin/DicomWebClient.h Plugin/Plugin.cpp |
diffstat | 5 files changed, 180 insertions(+), 268 deletions(-) [+] |
line wrap: on
line diff
--- a/Plugin/Configuration.cpp Thu Jun 20 18:37:20 2019 +0200 +++ b/Plugin/Configuration.cpp Thu Jun 20 20:23:47 2019 +0200 @@ -374,6 +374,82 @@ } + bool LookupStringValue(std::string& target, + const Json::Value& json, + const std::string& key) + { + if (json.type() != Json::objectValue) + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat); + } + else if (!json.isMember(key)) + { + return false; + } + else if (json[key].type() != Json::stringValue) + { + throw Orthanc::OrthancException( + Orthanc::ErrorCode_BadFileFormat, + "The field \"" + key + "\" in a JSON object should be a string"); + throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat); + } + else + { + target = json[key].asString(); + return true; + } + } + + + bool LookupIntegerValue(int& target, + const Json::Value& json, + const std::string& key) + { + if (json.type() != Json::objectValue) + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat); + } + else if (!json.isMember(key)) + { + return false; + } + else if (json[key].type() != Json::intValue && + json[key].type() != Json::uintValue) + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat); + } + else + { + target = json[key].asInt(); + return true; + } + } + + + bool LookupBooleanValue(bool& target, + const Json::Value& json, + const std::string& key) + { + if (json.type() != Json::objectValue) + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat); + } + else if (!json.isMember(key)) + { + return false; + } + else if (json[key].type() != Json::booleanValue) + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat); + } + else + { + target = json[key].asBool(); + return true; + } + } + + namespace Configuration { // Assume Latin-1 encoding by default (as in the Orthanc core)
--- a/Plugin/Configuration.h Thu Jun 20 18:37:20 2019 +0200 +++ b/Plugin/Configuration.h Thu Jun 20 20:23:47 2019 +0200 @@ -81,6 +81,18 @@ std::string RemoveMultipleSlashes(const std::string& source); + bool LookupStringValue(std::string& target, + const Json::Value& json, + const std::string& key); + + bool LookupIntegerValue(int& target, + const Json::Value& json, + const std::string& key); + + bool LookupBooleanValue(bool& target, + const Json::Value& json, + const std::string& key); + namespace Configuration { void Initialize();
--- a/Plugin/DicomWebClient.cpp Thu Jun 20 18:37:20 2019 +0200 +++ b/Plugin/DicomWebClient.cpp Thu Jun 20 20:23:47 2019 +0200 @@ -47,15 +47,14 @@ static void AddInstance(std::list<std::string>& target, const Json::Value& instance) { - if (instance.type() != Json::objectValue || - !instance.isMember("ID") || - instance["ID"].type() != Json::stringValue) + std::string id; + if (OrthancPlugins::LookupStringValue(id, instance, "ID")) { - throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); + target.push_back(id); } else { - target.push_back(instance["ID"].asString()); + throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); } } @@ -564,17 +563,17 @@ { OrthancPluginContext* context = OrthancPlugins::GetGlobalContext(); - if (request->groupsCount != 1) - { - throw Orthanc::OrthancException(Orthanc::ErrorCode_BadRequest); - } - if (request->method != OrthancPluginHttpMethod_Post) { OrthancPluginSendMethodNotAllowed(context, output, "POST"); return; } + if (request->groupsCount != 1) + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_BadRequest); + } + std::string serverName(request->groups[0]); #if 1 @@ -646,34 +645,6 @@ } -static bool GetStringValue(std::string& target, - const Json::Value& json, - const std::string& key) -{ - if (json.type() != Json::objectValue) - { - throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat); - } - else if (!json.isMember(key)) - { - target.clear(); - return false; - } - else if (json[key].type() != Json::stringValue) - { - throw Orthanc::OrthancException( - Orthanc::ErrorCode_BadFileFormat, - "The field \"" + key + "\" in a JSON object should be a string"); - } - else - { - target = json[key].asString(); - return true; - } -} - - - static void ParseGetFromServer(std::string& uri, std::map<std::string, std::string>& additionalHeaders, const Json::Value& resource) @@ -684,7 +655,7 @@ std::string tmp; if (resource.type() != Json::objectValue || - !GetStringValue(tmp, resource, URI)) + !OrthancPlugins::LookupStringValue(tmp, resource, URI)) { throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat, "A request to the DICOMweb client must provide a JSON object " @@ -802,7 +773,7 @@ } std::string study, series, instance; - if (!GetStringValue(study, resource, STUDY) || + if (!OrthancPlugins::LookupStringValue(study, resource, STUDY) || study.empty()) { throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat, @@ -810,8 +781,8 @@ "DICOMweb WADO-RS Retrieve client"); } - GetStringValue(series, resource, SERIES); - GetStringValue(instance, resource, INSTANCE); + OrthancPlugins::LookupStringValue(series, resource, SERIES); + OrthancPlugins::LookupStringValue(instance, resource, INSTANCE); if (series.empty() && !instance.empty()) @@ -967,15 +938,14 @@ Json::Value result; tmp.ToJson(result); - if (result.type() != Json::objectValue || - !result.isMember("ID") || - result["ID"].type() != Json::stringValue) + std::string id; + if (OrthancPlugins::LookupStringValue(id, result, "ID")) { - throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); + instances.insert(id); } else { - instances.insert(result["ID"].asString()); + throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); } } } @@ -1091,15 +1061,14 @@ Json::Value result; tmp.ToJson(result); - if (result.type() != Json::objectValue || - !result.isMember("ID") || - result["ID"].type() != Json::stringValue) + std::string id; + if (OrthancPlugins::LookupStringValue(id, result, "ID")) { - throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); + instances_.push_back(id); } else { - instances_.push_back(result["ID"].asString()); + throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); } } @@ -1213,43 +1182,6 @@ -void WadoRetrieveClient(OrthancPluginRestOutput* output, - const char* url, - const OrthancPluginHttpRequest* request) -{ - OrthancPlugins::HttpClient client; - ConfigureGetFromServer(client, request); - - std::list<std::string> instances; - - // Do some loop - { - WadoRetrieveAnswer answer; - answer.Cancel(); - client.Execute(answer); - answer.Close(); - - std::list<std::string> tmp; - answer.GetReceivedInstances(tmp); - instances.splice(instances.end(), tmp); - } - - Json::Value result = Json::objectValue; - result["InstancesCount"] = static_cast<int32_t>(instances.size()); - - std::string tmp = result.toStyledString(); - OrthancPluginAnswerBuffer(OrthancPlugins::GetGlobalContext(), output, - tmp.c_str(), tmp.size(), "application/json"); - -} - - - - - -#include <Core/IDynamicObject.h> - - class SingleFunctionJob : public OrthancPlugins::OrthancJob { public: @@ -1546,6 +1478,56 @@ content_ = Json::objectValue; ClearContent(); } + + + static void SubmitJob(OrthancPluginRestOutput* output, + OrthancPlugins::OrthancJob* job, + const Json::Value& body) + { + std::auto_ptr<OrthancPlugins::OrthancJob> protection(job); + + bool synchronous; + + bool b; + if (OrthancPlugins::LookupBooleanValue(b, body, "Synchronous")) + { + synchronous = b; + } + else if (OrthancPlugins::LookupBooleanValue(b, body, "Asynchronous")) + { + synchronous = !b; + } + else + { + synchronous = false; + } + + int priority; + if (!OrthancPlugins::LookupIntegerValue(priority, body, "Priority")) + { + priority = 0; + } + + Json::Value answer; + + if (synchronous) + { + OrthancPlugins::OrthancJob::SubmitAndWait(answer, protection.release(), priority); + } + else + { + std::string jobId = OrthancPlugins::OrthancJob::Submit(protection.release(), priority); + + answer = Json::objectValue; + answer["ID"] = jobId; + answer["Path"] = OrthancPlugins::RemoveMultipleSlashes + ("../../" + OrthancPlugins::Configuration::GetOrthancApiRoot() + "/jobs/" + jobId); + } + + std::string s = answer.toStyledString(); + OrthancPluginAnswerBuffer(OrthancPlugins::GetGlobalContext(), + output, s.c_str(), s.size(), "application/json"); + } }; @@ -1750,16 +1732,28 @@ }; - -void WadoTest() +void WadoRetrieveClient(OrthancPluginRestOutput* output, + const char* url, + const OrthancPluginHttpRequest* request) { - std::auto_ptr<WadoRetrieveJob> job(new WadoRetrieveJob("self")); - //job->AddResource("studies/2.16.840.1.113669.632.20.1211.10000315526"); // VIX - job->AddResource("studies/1.3.51.0.1.1.192.168.29.133.1688840.1688819"); // Cardiac + if (request->method != OrthancPluginHttpMethod_Post) + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); + } - //OrthancPlugins::OrthancJob::Submit(job.release(), 0); + if (request->groupsCount != 1) + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_BadRequest); + } + + std::string serverName(request->groups[0]); - Json::Value result; - OrthancPlugins::OrthancJob::SubmitAndWait(result, job.release(), 0); - std::cout << result.toStyledString() << std::endl; + Json::Value body; + OrthancPlugins::ParseJsonBody(body, request); + + std::auto_ptr<WadoRetrieveJob> job(new WadoRetrieveJob(serverName)); + job->AddResourceFromRequest(body); + + SingleFunctionJob::SubmitJob(output, job.release(), body); } +
--- a/Plugin/DicomWebClient.h Thu Jun 20 18:37:20 2019 +0200 +++ b/Plugin/DicomWebClient.h Thu Jun 20 20:23:47 2019 +0200 @@ -43,7 +43,3 @@ void WadoRetrieveClient(OrthancPluginRestOutput* output, const char* url, const OrthancPluginHttpRequest* request); - - -// TODO => remove -void WadoTest();
--- a/Plugin/Plugin.cpp Thu Jun 20 18:37:20 2019 +0200 +++ b/Plugin/Plugin.cpp Thu Jun 20 20:23:47 2019 +0200 @@ -430,170 +430,6 @@ -#include <boost/filesystem.hpp> -#include <Core/SystemToolbox.h> - -class StowClientBody : public OrthancPlugins::HttpClient::IRequestBody -{ -private: - std::vector<std::string> files_; - size_t position_; - std::string boundary_; - -public: - StowClientBody() : - position_(0), - boundary_(Orthanc::Toolbox::GenerateUuid() + "-" + Orthanc::Toolbox::GenerateUuid()) - { - //boost::filesystem::path p("/home/jodogne/DICOM/Demo/KNIX/Knee (R)/AX. FSE PD - 5"); - boost::filesystem::path p("/tmp/dicom"); - - boost::filesystem::directory_iterator end; - - // cycle through the directory - for (boost::filesystem::directory_iterator it(p); it != end; ++it) - { - if (is_regular_file(it->path())) - { - files_.push_back(it->path().string()); - } - } - } - - const std::string& GetBoundary() const - { - return boundary_; - } - - virtual bool ReadNextChunk(std::string& chunk) - { - if (position_ == files_.size() + 1) - { - return false; - } - else - { - if (position_ == files_.size()) - { - chunk = ("--" + boundary_ + "--"); - } - else - { - std::string f; - Orthanc::SystemToolbox::ReadFile(f, files_[position_]); - chunk = ("--" + boundary_ + "\r\n" + - "Content-Type: application/dicom\r\n" + - "Content-Length: " + boost::lexical_cast<std::string>(f.size()) + "\r\n" + - "\r\n" + f + "\r\n"); - } - - position_++; - return true; - } - } -}; - - -ORTHANC_PLUGINS_API OrthancPluginErrorCode OnChangeCallback(OrthancPluginChangeType changeType, - OrthancPluginResourceType resourceType, - const char* resourceId) -{ - if (changeType == OrthancPluginChangeType_OrthancStarted) - { - try - { -#if 1 - WadoTest(); -#endif - - -#if 0 - { - StowClientBody stow; - - OrthancPlugins::HttpClient client; - client.SetUrl("http://localhost:8080/dicom-web/studies"); - client.SetMethod(OrthancPluginHttpMethod_Post); - client.AddHeader("Accept", "application/dicom+json"); - client.AddHeader("Expect", ""); - client.AddHeader("Content-Type", "multipart/related; type=application/dicom; boundary=" + stow.GetBoundary()); - client.SetTimeout(120); - client.SetBody(stow); - - OrthancPlugins::HttpClient::HttpHeaders headers; - std::string answer; - client.Execute(headers, answer); - - Json::Value v; - Json::Reader reader; - if (reader.parse(answer, v)) - { - std::cout << v["00081190"].toStyledString() << std::endl; - } - else - { - throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat); - } - } -#endif - -#if 0 - { - OrthancPlugins::HttpClient client; - OrthancPlugins::DicomWebServers::GetInstance().ConfigureHttpClient(client, "google", "/studies"); - - OrthancPlugins::HttpClient::HttpHeaders headers; - Json::Value body; - client.Execute(headers, body); - - std::cout << body.toStyledString() << std::endl; - } -#endif - -#if 0 - { - OrthancPlugins::HttpClient client; - OrthancPlugins::DicomWebServers::GetInstance().ConfigureHttpClient(client, "self", "/studies"); - - client.SetMethod(OrthancPluginHttpMethod_Post); - client.AddHeader("Accept", "application/dicom+json"); - client.AddHeader("Expect", ""); - - std::string boundary = Orthanc::Toolbox::GenerateUuid() + "-" + Orthanc::Toolbox::GenerateUuid(); - client.AddHeader("Content-Type", "multipart/related; type=application/dicom; boundary=" + boundary); - - std::string f; - Orthanc::SystemToolbox::ReadFile(f, "/home/jodogne/Subversion/orthanc-tests/Database/Encodings/DavidClunie/SCSI2"); // Korean - //Orthanc::SystemToolbox::ReadFile(f, "/home/jodogne/Subversion/orthanc-tests/Database/Encodings/DavidClunie/SCSH31"); // Kanji - //Orthanc::SystemToolbox::ReadFile(f, "/home/jodogne/DICOM/Alain.dcm"); - - std::string body; - body += ("--" + boundary + "\r\nContent-Type: application/dicom\r\nContent-Length: " + - boost::lexical_cast<std::string>(f.size()) + "\r\n\r\n"); - body += f; - body += "\r\n--" + boundary + "--"; - - Orthanc::SystemToolbox::WriteFile(body, "/tmp/toto"); - - client.SetBody(body); - - OrthancPlugins::HttpClient::HttpHeaders headers; - Json::Value answer; - client.Execute(headers, answer); - - std::cout << answer.toStyledString() << std::endl; - } -#endif - } - catch (Orthanc::OrthancException& e) - { - LOG(ERROR) << "EXCEPTION: " << e.What(); - } - } - - return OrthancPluginErrorCode_Success; -} - template <enum Orthanc::EmbeddedResources::DirectoryResourceId folder> void ServeEmbeddedFolder(OrthancPluginRestOutput* output, @@ -673,8 +509,6 @@ // Read the configuration OrthancPlugins::Configuration::Initialize(); - OrthancPluginRegisterOnChangeCallback(context, OnChangeCallback); // TODO => REMOVE - // Initialize GDCM OrthancPlugins::GdcmParsedDicomFile::Initialize();