# HG changeset patch # User Sebastien Jodogne # Date 1611148837 -3600 # Node ID 6831de40acd9c8f567b5a8653d94feccac7a458b # Parent 16392fe89ce0679e7b9953d3c223499452579c4b New metadata automatically computed at the series level: "RemoteAET" diff -r 16392fe89ce0 -r 6831de40acd9 NEWS --- a/NEWS Wed Jan 20 13:30:54 2021 +0100 +++ b/NEWS Wed Jan 20 14:20:37 2021 +0100 @@ -13,6 +13,7 @@ - "UseDicomTls" in "DicomModalities" to enable DICOM TLS in outgoing SCU on a per-modality basis - "MaximumPduLength" to tune the maximum PDU length (Protocol Data Unit) * New command-line option: "--openapi" to write the OpenAPI documentation of the REST API to a file +* New metadata automatically computed at the series level: "RemoteAET" Plugins ------- diff -r 16392fe89ce0 -r 6831de40acd9 OrthancServer/Sources/LuaScripting.cpp --- a/OrthancServer/Sources/LuaScripting.cpp Wed Jan 20 13:30:54 2021 +0100 +++ b/OrthancServer/Sources/LuaScripting.cpp Wed Jan 20 14:20:37 2021 +0100 @@ -169,7 +169,7 @@ if (that.context_.GetIndex().LookupResource(tags, change_.GetPublicId(), change_.GetResourceType())) { std::map metadata; - that.context_.GetIndex().GetAllMetadata(metadata, change_.GetPublicId()); + that.context_.GetIndex().GetAllMetadata(metadata, change_.GetPublicId(), change_.GetResourceType()); Json::Value formattedMetadata = Json::objectValue; diff -r 16392fe89ce0 -r 6831de40acd9 OrthancServer/Sources/OrthancFindRequestHandler.cpp --- a/OrthancServer/Sources/OrthancFindRequestHandler.cpp Wed Jan 20 13:30:54 2021 +0100 +++ b/OrthancServer/Sources/OrthancFindRequestHandler.cpp Wed Jan 20 14:20:37 2021 +0100 @@ -200,7 +200,7 @@ it = instances.begin(); it != instances.end(); ++it) { std::string value; - if (context.LookupOrReconstructMetadata(value, *it, MetadataType_Instance_SopClassUid)) + if (context.LookupOrReconstructMetadata(value, *it, ResourceType_Instance, MetadataType_Instance_SopClassUid)) { values.insert(value); } diff -r 16392fe89ce0 -r 6831de40acd9 OrthancServer/Sources/OrthancRestApi/OrthancRestModalities.cpp --- a/OrthancServer/Sources/OrthancRestApi/OrthancRestModalities.cpp Wed Jan 20 13:30:54 2021 +0100 +++ b/OrthancServer/Sources/OrthancRestApi/OrthancRestModalities.cpp Wed Jan 20 14:20:37 2021 +0100 @@ -2154,7 +2154,7 @@ { std::string sopClassUid, sopInstanceUid; DicomMap tags; - if (context.LookupOrReconstructMetadata(sopClassUid, *it, MetadataType_Instance_SopClassUid) && + if (context.LookupOrReconstructMetadata(sopClassUid, *it, ResourceType_Instance, MetadataType_Instance_SopClassUid) && context.GetIndex().GetAllMainDicomTags(tags, *it) && tags.LookupStringValue(sopInstanceUid, DICOM_TAG_SOP_INSTANCE_UID, false)) { diff -r 16392fe89ce0 -r 6831de40acd9 OrthancServer/Sources/OrthancRestApi/OrthancRestResources.cpp --- a/OrthancServer/Sources/OrthancRestApi/OrthancRestResources.cpp Wed Jan 20 13:30:54 2021 +0100 +++ b/OrthancServer/Sources/OrthancRestApi/OrthancRestResources.cpp Wed Jan 20 14:20:37 2021 +0100 @@ -1420,6 +1420,7 @@ static void CheckValidResourceType(const RestApiCall& call) { + assert(!call.GetFullUri().empty()); const std::string resourceType = call.GetFullUri() [0]; StringToResourceType(resourceType.c_str()); } @@ -1444,12 +1445,13 @@ return; } - CheckValidResourceType(call); - - std::string publicId = call.GetUriComponent("id", ""); std::map metadata; - OrthancRestApi::GetIndex(call).GetAllMetadata(metadata, publicId); + assert(!call.GetFullUri().empty()); + const std::string publicId = call.GetUriComponent("id", ""); + const ResourceType level = StringToResourceType(call.GetFullUri() [0].c_str()); + + OrthancRestApi::GetIndex(call).GetAllMetadata(metadata, publicId, level); Json::Value result; @@ -1495,14 +1497,15 @@ return; } - CheckValidResourceType(call); - - std::string publicId = call.GetUriComponent("id", ""); + assert(!call.GetFullUri().empty()); + const std::string publicId = call.GetUriComponent("id", ""); + const ResourceType level = StringToResourceType(call.GetFullUri() [0].c_str()); + std::string name = call.GetUriComponent("name", ""); MetadataType metadata = StringToMetadata(name); std::string value; - if (OrthancRestApi::GetIndex(call).LookupMetadata(value, publicId, metadata)) + if (OrthancRestApi::GetIndex(call).LookupMetadata(value, publicId, level, metadata)) { call.GetOutput().AnswerBuffer(value, MimeType_PlainText); } diff -r 16392fe89ce0 -r 6831de40acd9 OrthancServer/Sources/OrthancWebDav.cpp --- a/OrthancServer/Sources/OrthancWebDav.cpp Wed Jan 20 13:30:54 2021 +0100 +++ b/OrthancServer/Sources/OrthancWebDav.cpp Wed Jan 20 14:20:37 2021 +0100 @@ -66,10 +66,11 @@ static void LookupTime(boost::posix_time::ptime& target, ServerContext& context, const std::string& publicId, + ResourceType level, MetadataType metadata) { std::string value; - if (context.GetIndex().LookupMetadata(value, publicId, metadata)) + if (context.GetIndex().LookupMetadata(value, publicId, level, metadata)) { try { @@ -168,7 +169,7 @@ if (resource.get() != NULL) { boost::posix_time::ptime t; - LookupTime(t, context_, publicId, timeMetadata); + LookupTime(t, context_, publicId, level_, timeMetadata); resource->SetCreationTime(t); target_.AddResource(resource.release()); } @@ -221,7 +222,7 @@ } else { - LookupTime(time_, context_, publicId, MetadataType_Instance_ReceptionDate); + LookupTime(time_, context_, publicId, ResourceType_Instance, MetadataType_Instance_ReceptionDate); context_.ReadDicom(target_, publicId); success_ = true; } @@ -504,7 +505,7 @@ it = resources.begin(); it != resources.end(); ++it) { boost::posix_time::ptime time; - LookupTime(time, context_, *it, MetadataType_Instance_ReceptionDate); + LookupTime(time, context_, *it, ResourceType_Instance, MetadataType_Instance_ReceptionDate); FileInfo info; if (context_.GetIndex().LookupAttachment(info, *it, FileContentType_Dicom)) @@ -537,7 +538,7 @@ { mime = MimeType_Dicom; context_.ReadDicom(content, instanceId); - LookupTime(time, context_, instanceId, MetadataType_Instance_ReceptionDate); + LookupTime(time, context_, instanceId, ResourceType_Instance, MetadataType_Instance_ReceptionDate); return true; } catch (OrthancException&) @@ -804,7 +805,7 @@ for (ResourcesIndex::Map::const_iterator it = paths.begin(); it != paths.end(); ++it) { boost::posix_time::ptime time; - LookupTime(time, context_, it->second, timeMetadata_); + LookupTime(time, context_, it->second, index_->GetLevel(), timeMetadata_); std::unique_ptr resource(new IWebDavBucket::Folder(it->first)); resource->SetCreationTime(time); diff -r 16392fe89ce0 -r 6831de40acd9 OrthancServer/Sources/ServerContext.cpp --- a/OrthancServer/Sources/ServerContext.cpp Wed Jan 20 13:30:54 2021 +0100 +++ b/OrthancServer/Sources/ServerContext.cpp Wed Jan 20 14:20:37 2021 +0100 @@ -1441,6 +1441,7 @@ bool ServerContext::LookupOrReconstructMetadata(std::string& target, const std::string& publicId, + ResourceType level, MetadataType metadata) { // This is a backwards-compatibility function, that can @@ -1450,7 +1451,7 @@ if (metadata == MetadataType_Instance_SopClassUid || metadata == MetadataType_Instance_TransferSyntax) { - if (index_.LookupMetadata(target, publicId, metadata)) + if (index_.LookupMetadata(target, publicId, level, metadata)) { return true; } @@ -1505,7 +1506,7 @@ else { // No backward - return index_.LookupMetadata(target, publicId, metadata); + return index_.LookupMetadata(target, publicId, level, metadata); } } diff -r 16392fe89ce0 -r 6831de40acd9 OrthancServer/Sources/ServerContext.h --- a/OrthancServer/Sources/ServerContext.h Wed Jan 20 13:30:54 2021 +0100 +++ b/OrthancServer/Sources/ServerContext.h Wed Jan 20 14:20:37 2021 +0100 @@ -396,6 +396,7 @@ bool LookupOrReconstructMetadata(std::string& target, const std::string& publicId, + ResourceType level, MetadataType type); diff -r 16392fe89ce0 -r 6831de40acd9 OrthancServer/Sources/ServerEnumerations.cpp --- a/OrthancServer/Sources/ServerEnumerations.cpp Wed Jan 20 13:30:54 2021 +0100 +++ b/OrthancServer/Sources/ServerEnumerations.cpp Wed Jan 20 14:20:37 2021 +0100 @@ -59,7 +59,7 @@ dictMetadataType_.Add(MetadataType_Instance_IndexInSeries, "IndexInSeries"); dictMetadataType_.Add(MetadataType_Instance_ReceptionDate, "ReceptionDate"); - dictMetadataType_.Add(MetadataType_Instance_RemoteAet, "RemoteAET"); + dictMetadataType_.Add(MetadataType_RemoteAet, "RemoteAET"); dictMetadataType_.Add(MetadataType_Series_ExpectedNumberOfInstances, "ExpectedNumberOfInstances"); dictMetadataType_.Add(MetadataType_ModifiedFrom, "ModifiedFrom"); dictMetadataType_.Add(MetadataType_AnonymizedFrom, "AnonymizedFrom"); diff -r 16392fe89ce0 -r 6831de40acd9 OrthancServer/Sources/ServerEnumerations.h --- a/OrthancServer/Sources/ServerEnumerations.h Wed Jan 20 13:30:54 2021 +0100 +++ b/OrthancServer/Sources/ServerEnumerations.h Wed Jan 20 14:20:37 2021 +0100 @@ -130,7 +130,7 @@ { MetadataType_Instance_IndexInSeries = 1, MetadataType_Instance_ReceptionDate = 2, - MetadataType_Instance_RemoteAet = 3, + MetadataType_RemoteAet = 3, // Renamed from "MetadataType_Series_RemoteAet" in Orthanc 1.9.0 MetadataType_Series_ExpectedNumberOfInstances = 4, MetadataType_ModifiedFrom = 5, MetadataType_AnonymizedFrom = 6, diff -r 16392fe89ce0 -r 6831de40acd9 OrthancServer/Sources/ServerIndex.cpp --- a/OrthancServer/Sources/ServerIndex.cpp Wed Jan 20 13:30:54 2021 +0100 +++ b/OrthancServer/Sources/ServerIndex.cpp Wed Jan 20 14:20:37 2021 +0100 @@ -914,11 +914,17 @@ content.AddMetadata(status.studyId_, MetadataType_LastUpdate, now); content.AddMetadata(status.patientId_, MetadataType_LastUpdate, now); - if (status.isNewSeries_ && - hasExpectedInstances) + if (status.isNewSeries_) { - content.AddMetadata(status.seriesId_, MetadataType_Series_ExpectedNumberOfInstances, - boost::lexical_cast(expectedInstances)); + if (hasExpectedInstances) + { + content.AddMetadata(status.seriesId_, MetadataType_Series_ExpectedNumberOfInstances, + boost::lexical_cast(expectedInstances)); + } + + // New in Orthanc 1.9.0 + content.AddMetadata(status.seriesId_, MetadataType_RemoteAet, + instanceToStore.GetOrigin().GetRemoteAetC()); } @@ -926,7 +932,7 @@ // reflecting these additions into the input metadata map SetInstanceMetadata(content, instanceMetadata, instanceId, MetadataType_Instance_ReceptionDate, now); - SetInstanceMetadata(content, instanceMetadata, instanceId, MetadataType_Instance_RemoteAet, + SetInstanceMetadata(content, instanceMetadata, instanceId, MetadataType_RemoteAet, instanceToStore.GetOrigin().GetRemoteAetC()); SetInstanceMetadata(content, instanceMetadata, instanceId, MetadataType_Instance_Origin, EnumerationToString(instanceToStore.GetOrigin().GetRequestOrigin())); @@ -1849,13 +1855,15 @@ bool ServerIndex::LookupMetadata(std::string& target, const std::string& publicId, + ResourceType expectedType, MetadataType type) { boost::mutex::scoped_lock lock(mutex_); ResourceType rtype; int64_t id; - if (!db_.LookupResource(id, rtype, publicId)) + if (!db_.LookupResource(id, rtype, publicId) || + rtype != expectedType) { throw OrthancException(ErrorCode_UnknownResource); } @@ -1865,13 +1873,15 @@ void ServerIndex::GetAllMetadata(std::map& target, - const std::string& publicId) + const std::string& publicId, + ResourceType expectedType) { boost::mutex::scoped_lock lock(mutex_); ResourceType type; int64_t id; - if (!db_.LookupResource(id, type, publicId)) + if (!db_.LookupResource(id, type, publicId) || + expectedType != type) { throw OrthancException(ErrorCode_UnknownResource); } diff -r 16392fe89ce0 -r 6831de40acd9 OrthancServer/Sources/ServerIndex.h --- a/OrthancServer/Sources/ServerIndex.h Wed Jan 20 13:30:54 2021 +0100 +++ b/OrthancServer/Sources/ServerIndex.h Wed Jan 20 14:20:37 2021 +0100 @@ -204,10 +204,12 @@ MetadataType type); void GetAllMetadata(std::map& target, - const std::string& publicId); + const std::string& publicId, + ResourceType expectedType); bool LookupMetadata(std::string& target, const std::string& publicId, + ResourceType expectedType, MetadataType type); void ListAvailableAttachments(std::list& target, diff -r 16392fe89ce0 -r 6831de40acd9 OrthancServer/Sources/SliceOrdering.cpp --- a/OrthancServer/Sources/SliceOrdering.cpp Wed Jan 20 13:30:54 2021 +0100 +++ b/OrthancServer/Sources/SliceOrdering.cpp Wed Jan 20 14:20:37 2021 +0100 @@ -208,7 +208,7 @@ try { - if (index.LookupMetadata(s, instanceId, MetadataType_Instance_IndexInSeries)) + if (index.LookupMetadata(s, instanceId, ResourceType_Instance, MetadataType_Instance_IndexInSeries)) { indexInSeries_ = boost::lexical_cast(Toolbox::StripSpaces(s)); hasIndexInSeries_ = true; diff -r 16392fe89ce0 -r 6831de40acd9 OrthancServer/UnitTestsSources/ServerIndexTests.cpp --- a/OrthancServer/UnitTestsSources/ServerIndexTests.cpp Wed Jan 20 13:30:54 2021 +0100 +++ b/OrthancServer/UnitTestsSources/ServerIndexTests.cpp Wed Jan 20 14:20:37 2021 +0100 @@ -303,11 +303,11 @@ CompressionType_ZlibWithSize, 21, "compressedMD5")); index_->AddAttachment(a[4], FileInfo("my dicom file", FileContentType_Dicom, 42, "md5")); index_->AddAttachment(a[6], FileInfo("world", FileContentType_Dicom, 44, "md5")); - index_->SetMetadata(a[4], MetadataType_Instance_RemoteAet, "PINNACLE"); + index_->SetMetadata(a[4], MetadataType_RemoteAet, "PINNACLE"); index_->GetAllMetadata(md, a[4]); ASSERT_EQ(1u, md.size()); - ASSERT_EQ("PINNACLE", md[MetadataType_Instance_RemoteAet]); + ASSERT_EQ("PINNACLE", md[MetadataType_RemoteAet]); index_->SetMetadata(a[4], MetadataType_ModifiedFrom, "TUTU"); index_->GetAllMetadata(md, a[4]); ASSERT_EQ(2u, md.size()); @@ -316,16 +316,16 @@ index_->GetAllMetadata(md2, a[4]); ASSERT_EQ(2u, md2.size()); ASSERT_EQ("TUTU", md2[MetadataType_ModifiedFrom]); - ASSERT_EQ("PINNACLE", md2[MetadataType_Instance_RemoteAet]); + ASSERT_EQ("PINNACLE", md2[MetadataType_RemoteAet]); index_->DeleteMetadata(a[4], MetadataType_ModifiedFrom); index_->GetAllMetadata(md, a[4]); ASSERT_EQ(1u, md.size()); - ASSERT_EQ("PINNACLE", md[MetadataType_Instance_RemoteAet]); + ASSERT_EQ("PINNACLE", md[MetadataType_RemoteAet]); index_->GetAllMetadata(md2, a[4]); ASSERT_EQ(1u, md2.size()); - ASSERT_EQ("PINNACLE", md2[MetadataType_Instance_RemoteAet]); + ASSERT_EQ("PINNACLE", md2[MetadataType_RemoteAet]); ASSERT_EQ(21u + 42u + 44u, index_->GetTotalCompressedSize()); @@ -339,12 +339,12 @@ ASSERT_EQ(7, b); ASSERT_EQ(ResourceType_Study, t); - ASSERT_TRUE(index_->LookupMetadata(s, a[4], MetadataType_Instance_RemoteAet)); + ASSERT_TRUE(index_->LookupMetadata(s, a[4], MetadataType_RemoteAet)); ASSERT_FALSE(index_->LookupMetadata(s, a[4], MetadataType_Instance_IndexInSeries)); ASSERT_EQ("PINNACLE", s); std::string u; - ASSERT_TRUE(index_->LookupMetadata(u, a[4], MetadataType_Instance_RemoteAet)); + ASSERT_TRUE(index_->LookupMetadata(u, a[4], MetadataType_RemoteAet)); ASSERT_EQ("PINNACLE", u); ASSERT_FALSE(index_->LookupMetadata(u, a[4], MetadataType_Instance_IndexInSeries)); @@ -730,7 +730,7 @@ ASSERT_EQ(StoreStatus_Success, index.Store(instanceMetadata, toStore, attachments, false /* don't overwrite */)); ASSERT_EQ(5u, instanceMetadata.size()); - ASSERT_TRUE(instanceMetadata.find(MetadataType_Instance_RemoteAet) != instanceMetadata.end()); + ASSERT_TRUE(instanceMetadata.find(MetadataType_RemoteAet) != instanceMetadata.end()); ASSERT_TRUE(instanceMetadata.find(MetadataType_Instance_ReceptionDate) != instanceMetadata.end()); ASSERT_TRUE(instanceMetadata.find(MetadataType_Instance_TransferSyntax) != instanceMetadata.end()); ASSERT_TRUE(instanceMetadata.find(MetadataType_Instance_SopClassUid) != instanceMetadata.end());