# HG changeset patch # User Sebastien Jodogne # Date 1481536869 -3600 # Node ID 9a8fab016145705ccb7bf57b9fb5983b043a97d9 # Parent 028214a95194ac93c2fc0227e38d18d62803d3ab sample worklist plugin fine-tuning the C-Find query diff -r 028214a95194 -r 9a8fab016145 OrthancServer/FromDcmtkBridge.cpp --- a/OrthancServer/FromDcmtkBridge.cpp Sat Dec 10 11:41:17 2016 +0100 +++ b/OrthancServer/FromDcmtkBridge.cpp Mon Dec 12 11:01:09 2016 +0100 @@ -1646,7 +1646,9 @@ if (!ok) { - throw OrthancException(ErrorCode_InternalError); + LOG(ERROR) << "While creating a DICOM instance, tag (" << tag.Format() + << ") has out-of-range value: \"" << *decoded << "\""; + throw OrthancException(ErrorCode_BadFileFormat); } } @@ -1665,6 +1667,11 @@ FillElementWithString(*element, tag, value.asString(), decodeDataUriScheme, dicomEncoding); break; + case Json::nullValue: + element.reset(CreateElementForTag(tag)); + FillElementWithString(*element, tag, "", decodeDataUriScheme, dicomEncoding); + break; + case Json::arrayValue: { DcmTag key(tag.GetGroup(), tag.GetElement()); @@ -1742,11 +1749,17 @@ { const Json::Value& value = json[tags[i]]; if (value.type() != Json::stringValue || - !GetDicomEncoding(encoding, value.asCString())) + (value.asString().length() != 0 && + !GetDicomEncoding(encoding, value.asCString()))) { LOG(ERROR) << "Unknown encoding while creating DICOM from JSON: " << value; throw OrthancException(ErrorCode_BadRequest); } + + if (value.asString().length() == 0) + { + return defaultEncoding; + } } } diff -r 028214a95194 -r 9a8fab016145 Plugins/Include/orthanc/OrthancCPlugin.h --- a/Plugins/Include/orthanc/OrthancCPlugin.h Sat Dec 10 11:41:17 2016 +0100 +++ b/Plugins/Include/orthanc/OrthancCPlugin.h Mon Dec 12 11:01:09 2016 +0100 @@ -717,6 +717,7 @@ **/ typedef enum { + OrthancPluginDicomToJsonFlags_None = 0, OrthancPluginDicomToJsonFlags_IncludeBinary = (1 << 0), /*!< Include the binary tags */ OrthancPluginDicomToJsonFlags_IncludePrivateTags = (1 << 1), /*!< Include the private tags */ OrthancPluginDicomToJsonFlags_IncludeUnknownTags = (1 << 2), /*!< Include the tags unknown by the dictionary */ @@ -735,6 +736,7 @@ **/ typedef enum { + OrthancPluginCreateDicomFlags_None = 0, OrthancPluginCreateDicomFlags_DecodeDataUriScheme = (1 << 0), /*!< Decode fields encoded using data URI scheme */ OrthancPluginCreateDicomFlags_GenerateIdentifiers = (1 << 1), /*!< Automatically generate DICOM identifiers */ diff -r 028214a95194 -r 9a8fab016145 Plugins/Samples/ModalityWorklists/Plugin.cpp --- a/Plugins/Samples/ModalityWorklists/Plugin.cpp Sat Dec 10 11:41:17 2016 +0100 +++ b/Plugins/Samples/ModalityWorklists/Plugin.cpp Mon Dec 12 11:01:09 2016 +0100 @@ -57,23 +57,71 @@ } -OrthancPlugins::FindMatcher* CreateMatcher(const OrthancPluginWorklistQuery* query, - const char* remoteAet) +static OrthancPlugins::FindMatcher* CreateMatcher(const OrthancPluginWorklistQuery* query, + const char* remoteAet) { + // Extract the DICOM instance underlying the C-Find query OrthancPlugins::MemoryBuffer dicom(context_); dicom.GetDicomQuery(query); + // Convert the DICOM as JSON, and dump it to the user in "--verbose" mode + Json::Value json; + dicom.DicomToJson(json, OrthancPluginDicomToJsonFormat_Short, + static_cast(0), 0); + + OrthancPlugins::LogInfo(context_, "Received worklist query from remote modality " + + std::string(remoteAet) + ":\n" + json.toStyledString()); + +#if 1 + return new OrthancPlugins::FindMatcher(context_, query); + +#else + // Alternative sample showing how to fine-tune an incoming C-Find + // request, before matching it against the worklist database. The + // code below will restrict the original DICOM request by requesting + // the ScheduledStationAETitle to correspond to the AET of the + // issuer. This code will make the integration test "test_other_aet" + // succeed (cf. the orthanc-tests repository). + + static const char* SCHEDULED_PROCEDURE_STEP_SEQUENCE = "0040,0100"; + static const char* SCHEDULED_STATION_AETITLE = "0040,0001"; + + if (!json.isMember(SCHEDULED_PROCEDURE_STEP_SEQUENCE)) { - Json::Value json; - dicom.DicomToJson(json, OrthancPluginDicomToJsonFormat_Short, - static_cast(0), 0); - - OrthancPlugins::LogInfo(context_, "Received worklist query from remote modality " + - std::string(remoteAet) + ":\n" + json.toStyledString()); + // Create a ScheduledProcedureStepSequence sequence, with one empty element + json[SCHEDULED_PROCEDURE_STEP_SEQUENCE] = Json::arrayValue; + json[SCHEDULED_PROCEDURE_STEP_SEQUENCE].append(Json::objectValue); } - return new OrthancPlugins::FindMatcher(context_, query); - //return new OrthancPlugins::FindMatcher(context_, dicom); + Json::Value& v = json[SCHEDULED_PROCEDURE_STEP_SEQUENCE]; + + if (v.type() != Json::arrayValue || + v.size() != 1 || + v[0].type() != Json::objectValue) + { + ORTHANC_PLUGINS_THROW_EXCEPTION(OrthancPluginErrorCode_BadFileFormat); + } + + // Set the ScheduledStationAETitle if none was provided + if (!v[0].isMember(SCHEDULED_STATION_AETITLE) || + v[0].type() != Json::stringValue || + v[0][SCHEDULED_STATION_AETITLE].asString().size() == 0 || + v[0][SCHEDULED_STATION_AETITLE].asString() == "*") + { + v[0][SCHEDULED_STATION_AETITLE] = remoteAet; + } + + if (json.isMember("0010,21c0") && + json["0010,21c0"].asString().size() == 0) + { + json.removeMember("0010,21c0"); + } + + // Encode the modified JSON as a DICOM instance, then convert it to a C-Find matcher + OrthancPlugins::MemoryBuffer modified(context_); + modified.CreateDicom(json, OrthancPluginCreateDicomFlags_None); + return new OrthancPlugins::FindMatcher(context_, modified); +#endif }