changeset 4460:6831de40acd9

New metadata automatically computed at the series level: "RemoteAET"
author Sebastien Jodogne <s.jodogne@gmail.com>
date Wed, 20 Jan 2021 14:20:37 +0100
parents 16392fe89ce0
children 22abc6851191
files NEWS OrthancServer/Sources/LuaScripting.cpp OrthancServer/Sources/OrthancFindRequestHandler.cpp OrthancServer/Sources/OrthancRestApi/OrthancRestModalities.cpp OrthancServer/Sources/OrthancRestApi/OrthancRestResources.cpp OrthancServer/Sources/OrthancWebDav.cpp OrthancServer/Sources/ServerContext.cpp OrthancServer/Sources/ServerContext.h OrthancServer/Sources/ServerEnumerations.cpp OrthancServer/Sources/ServerEnumerations.h OrthancServer/Sources/ServerIndex.cpp OrthancServer/Sources/ServerIndex.h OrthancServer/Sources/SliceOrdering.cpp OrthancServer/UnitTestsSources/ServerIndexTests.cpp
diffstat 14 files changed, 58 insertions(+), 39 deletions(-) [+]
line wrap: on
line diff
--- 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
 -------
--- 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<MetadataType, std::string> metadata;
-        that.context_.GetIndex().GetAllMetadata(metadata, change_.GetPublicId());
+        that.context_.GetIndex().GetAllMetadata(metadata, change_.GetPublicId(), change_.GetResourceType());
         
         Json::Value formattedMetadata = Json::objectValue;
 
--- 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);
         }
--- 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))
               {
--- 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<MetadataType, std::string> 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);
     }
--- 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<IWebDavBucket::Resource> resource(new IWebDavBucket::Folder(it->first));
           resource->SetCreationTime(time);
--- 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);
     }
   }
 
--- 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);
 
 
--- 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");
--- 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,
--- 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<std::string>(expectedInstances));
+          if (hasExpectedInstances)
+          {
+            content.AddMetadata(status.seriesId_, MetadataType_Series_ExpectedNumberOfInstances,
+                                boost::lexical_cast<std::string>(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<MetadataType, std::string>& 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);
     }
--- 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<MetadataType, std::string>& 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<FileContentType>& target,
--- 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<size_t>(Toolbox::StripSpaces(s));
           hasIndexInSeries_ = true;
--- 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());