Mercurial > hg > orthanc
changeset 6112:91dde382f780 attach-custom-data
integration mainline->attach-custom-data
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Fri, 16 May 2025 17:19:35 +0200 (2 weeks ago) |
parents | e08274ea166e (current diff) 4e7f565e2604 (diff) |
children | 7dcc5e0a23b7 |
files | NEWS OrthancServer/Plugins/Include/orthanc/OrthancCPlugin.h OrthancServer/Plugins/Samples/Common/OrthancPluginCppWrapper.cpp OrthancServer/Plugins/Samples/Common/OrthancPluginCppWrapper.h OrthancServer/Sources/OrthancRestApi/OrthancRestResources.cpp |
diffstat | 10 files changed, 123 insertions(+), 22 deletions(-) [+] |
line wrap: on
line diff
--- a/NEWS Thu May 15 18:49:47 2025 +0200 +++ b/NEWS Fri May 16 17:19:35 2025 +0200 @@ -14,6 +14,15 @@ * New storage plugin SDK (v3) to handle customData for attachments. * New functions available to all plugins to store key-values and queues. +Maintenance +----------- + +* In verbose logs, added the elapsed time spent in each HTTP call. +* Housekeeper plugin: + - If "LimitMainDicomTagsReconstructLevel" was set, files were not transcoded if they had to. + The "LimitMainDicomTagsReconstructLevel" configuration is now ignored when a full processing + is required. + Version 1.12.7 (2025-04-07) ===========================
--- a/OrthancFramework/Resources/CMake/DcmtkConfiguration.cmake Thu May 15 18:49:47 2025 +0200 +++ b/OrthancFramework/Resources/CMake/DcmtkConfiguration.cmake Fri May 16 17:19:35 2025 +0200 @@ -80,6 +80,12 @@ ${DCMTK_SOURCES_DIR}/dcmimage/include ) endif() + + if (ENABLE_DCMTK_TRANSCODING OR ENABLE_DCMTK_JPEG OR ENABLE_DCMTK_JPEG_LOSSLESS) + include_directories( + ${DCMTK_SOURCES_DIR}/dcmimgle/include + ) + endif() if (ENABLE_DCMTK_JPEG) AUX_SOURCE_DIRECTORY(${DCMTK_SOURCES_DIR}/dcmjpeg/libsrc DCMTK_SOURCES) @@ -91,7 +97,6 @@ ${DCMTK_SOURCES_DIR}/dcmjpeg/libijg8 ${DCMTK_SOURCES_DIR}/dcmjpeg/libijg12 ${DCMTK_SOURCES_DIR}/dcmjpeg/libijg16 - ${DCMTK_SOURCES_DIR}/dcmimgle/include ) list(REMOVE_ITEM DCMTK_SOURCES ${DCMTK_SOURCES_DIR}/dcmjpeg/libsrc/ddpiimpl.cc
--- a/OrthancFramework/Sources/HttpServer/HttpServer.cpp Thu May 15 18:49:47 2025 +0200 +++ b/OrthancFramework/Sources/HttpServer/HttpServer.cpp Fri May 16 17:19:35 2025 +0200 @@ -1257,10 +1257,12 @@ HttpMethod filterMethod; - + std::unique_ptr<Toolbox::ApiElapsedTimeLogger> apiLogTimer; // to log the time spent in the API call + if (ExtractMethod(method, request, headers, argumentsGET)) { - CLOG(INFO, HTTP) << EnumerationToString(method) << " " << Toolbox::FlattenUri(uri); + apiLogTimer.reset(new Toolbox::ApiElapsedTimeLogger(std::string(EnumerationToString(method)) + " " + Toolbox::FlattenUri(uri))); + filterMethod = method; } #if ORTHANC_ENABLE_PUGIXML == 1 @@ -1268,8 +1270,7 @@ !strcmp(request->request_method, "PROPFIND") || !strcmp(request->request_method, "HEAD")) { - CLOG(INFO, HTTP) << "Incoming read-only WebDAV request: " - << request->request_method << " " << requestUri; + apiLogTimer.reset(new Toolbox::ApiElapsedTimeLogger(std::string("Incoming read-only WebDAV request: ") + request->request_method + " " + requestUri)); filterMethod = HttpMethod_Get; isWebDav = true; } @@ -1278,8 +1279,7 @@ !strcmp(request->request_method, "UNLOCK") || !strcmp(request->request_method, "MKCOL")) { - CLOG(INFO, HTTP) << "Incoming read-write WebDAV request: " - << request->request_method << " " << requestUri; + apiLogTimer.reset(new Toolbox::ApiElapsedTimeLogger(std::string("Incoming read-write WebDAV request: ") + request->request_method + " " + requestUri)); filterMethod = HttpMethod_Put; isWebDav = true; }
--- a/OrthancFramework/Sources/Toolbox.cpp Thu May 15 18:49:47 2025 +0200 +++ b/OrthancFramework/Sources/Toolbox.cpp Fri May 16 17:19:35 2025 +0200 @@ -2576,14 +2576,14 @@ return Toolbox::GetHumanTransferSpeed(full, sizeInBytes, GetElapsedNanoseconds()); } - Toolbox::ElapsedTimeLogger::ElapsedTimeLogger(const std::string& message) + Toolbox::DebugElapsedTimeLogger::DebugElapsedTimeLogger(const std::string& message) : message_(message), logged_(false) { Restart(); } - Toolbox::ElapsedTimeLogger::~ElapsedTimeLogger() + Toolbox::DebugElapsedTimeLogger::~DebugElapsedTimeLogger() { if (!logged_) { @@ -2591,17 +2591,29 @@ } } - void Toolbox::ElapsedTimeLogger::Restart() + void Toolbox::DebugElapsedTimeLogger::Restart() { timer_.Restart(); } - void Toolbox::ElapsedTimeLogger::StopAndLog() + void Toolbox::DebugElapsedTimeLogger::StopAndLog() { LOG(WARNING) << "ELAPSED TIMER: " << message_ << " (" << timer_.GetElapsedMicroseconds() << " us)"; logged_ = true; } + Toolbox::ApiElapsedTimeLogger::ApiElapsedTimeLogger(const std::string& message) : + message_(message) + { + timer_.Restart(); + CLOG(INFO, HTTP) << message_; + } + + Toolbox::ApiElapsedTimeLogger::~ApiElapsedTimeLogger() + { + CLOG(INFO, HTTP) << message_ << " (elapsed: " << timer_.GetElapsedMicroseconds() << " us)"; + } + std::string Toolbox::GetHumanFileSize(uint64_t sizeInBytes) { if (sizeInBytes < 1024)
--- a/OrthancFramework/Sources/Toolbox.h Thu May 15 18:49:47 2025 +0200 +++ b/OrthancFramework/Sources/Toolbox.h Fri May 16 17:19:35 2025 +0200 @@ -82,7 +82,7 @@ class ORTHANC_PUBLIC Toolbox { public: - class ORTHANC_PUBLIC LinesIterator + class ORTHANC_PUBLIC LinesIterator : public boost::noncopyable { private: const std::string& content_; @@ -377,11 +377,13 @@ static void RemoveSurroundingQuotes(std::string& value); - class ORTHANC_PUBLIC ElapsedTimer + class ORTHANC_PUBLIC ElapsedTimer : public boost::noncopyable { + private: boost::posix_time::ptime start_; + public: - explicit ElapsedTimer(); + ElapsedTimer(); uint64_t GetElapsedMilliseconds(); uint64_t GetElapsedMicroseconds(); @@ -394,23 +396,38 @@ }; // This is a helper class to measure and log time spend e.g in a method. - // This should be used only during debugging and should likely not ever used in a release. + // This should be used only during debugging and should likely not ever be used in a release. // By default, you should use it as a RAII but you may force Restart/StopAndLog manually if needed. - class ORTHANC_PUBLIC ElapsedTimeLogger + class ORTHANC_PUBLIC DebugElapsedTimeLogger : public boost::noncopyable { private: ElapsedTimer timer_; const std::string message_; - bool logged_; + bool logged_; public: - explicit ElapsedTimeLogger(const std::string& message); - ~ElapsedTimeLogger(); + explicit DebugElapsedTimeLogger(const std::string& message); + + ~DebugElapsedTimeLogger(); void Restart(); void StopAndLog(); }; + // This variant logs the same message when entering the method and when exiting (with the elapsed time). + // Logs goes to verbose-http. + class ORTHANC_PUBLIC ApiElapsedTimeLogger : public boost::noncopyable + { + private: + ElapsedTimer timer_; + const std::string message_; + + public: + explicit ApiElapsedTimeLogger(const std::string& message); + + ~ApiElapsedTimeLogger(); + }; + static std::string GetHumanFileSize(uint64_t sizeInBytes); static std::string GetHumanDuration(uint64_t durationInNanoseconds);
--- a/OrthancServer/Plugins/Include/orthanc/OrthancCPlugin.h Thu May 15 18:49:47 2025 +0200 +++ b/OrthancServer/Plugins/Include/orthanc/OrthancCPlugin.h Fri May 16 17:19:35 2025 +0200 @@ -1620,6 +1620,10 @@ * concurrently by different threads of the Web server of * Orthanc. You must implement proper locking if applicable. * + * Note that if you are using HTTP basic authentication, you can extract + * the username from the "Authorization" HTTP header. The value of that header + * contains username:pwd encoded in base64. + * * @param method The HTTP method used by the request. * @param uri The URI of interest. * @param ip The IP address of the HTTP client.
--- a/OrthancServer/Plugins/Samples/Common/OrthancPluginCppWrapper.cpp Thu May 15 18:49:47 2025 +0200 +++ b/OrthancServer/Plugins/Samples/Common/OrthancPluginCppWrapper.cpp Fri May 16 17:19:35 2025 +0200 @@ -2052,6 +2052,26 @@ DoPost(target, index, uri, body, headers)); } + bool OrthancPeers::DoPost(Json::Value& target, + size_t index, + const std::string& uri, + const std::string& body, + const HttpHeaders& headers, + unsigned int timeout) const + { + MemoryBuffer buffer; + + if (DoPost(buffer, index, uri, body, headers, timeout)) + { + buffer.ToJson(target); + return true; + } + else + { + return false; + } + } + bool OrthancPeers::DoPost(Json::Value& target, size_t index, @@ -2099,6 +2119,17 @@ const std::string& body, const HttpHeaders& headers) const { + return DoPost(target, index, uri, body, headers, timeout_); + } + + + bool OrthancPeers::DoPost(MemoryBuffer& target, + size_t index, + const std::string& uri, + const std::string& body, + const HttpHeaders& headers, + unsigned int timeout) const + { if (index >= index_.size()) { ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_ParameterOutOfRange); @@ -2117,7 +2148,7 @@ OrthancPluginErrorCode code = OrthancPluginCallPeerApi (GetGlobalContext(), *answer, NULL, &status, peers_, static_cast<uint32_t>(index), OrthancPluginHttpMethod_Post, uri.c_str(), - pluginHeaders.GetSize(), pluginHeaders.GetKeys(), pluginHeaders.GetValues(), body.empty() ? NULL : body.c_str(), body.size(), timeout_); + pluginHeaders.GetSize(), pluginHeaders.GetKeys(), pluginHeaders.GetValues(), body.empty() ? NULL : body.c_str(), body.size(), timeout); if (code == OrthancPluginErrorCode_Success) {
--- a/OrthancServer/Plugins/Samples/Common/OrthancPluginCppWrapper.h Thu May 15 18:49:47 2025 +0200 +++ b/OrthancServer/Plugins/Samples/Common/OrthancPluginCppWrapper.h Fri May 16 17:19:35 2025 +0200 @@ -855,6 +855,13 @@ const HttpHeaders& headers) const; bool DoPost(MemoryBuffer& target, + size_t index, + const std::string& uri, + const std::string& body, + const HttpHeaders& headers, + unsigned int timeout) const; + + bool DoPost(MemoryBuffer& target, const std::string& name, const std::string& uri, const std::string& body, @@ -867,6 +874,13 @@ const HttpHeaders& headers) const; bool DoPost(Json::Value& target, + size_t index, + const std::string& uri, + const std::string& body, + const HttpHeaders& headers, + unsigned int timeout) const; + + bool DoPost(Json::Value& target, const std::string& name, const std::string& uri, const std::string& body,
--- a/OrthancServer/Plugins/Samples/Housekeeper/Plugin.cpp Thu May 15 18:49:47 2025 +0200 +++ b/OrthancServer/Plugins/Samples/Housekeeper/Plugin.cpp Fri May 16 17:19:35 2025 +0200 @@ -651,6 +651,13 @@ needsFullProcessing = needsReconstruct || needsReingest || needsDicomWebCaching; needsProcessing = needsFullProcessing; + if (needsFullProcessing && !limitToChange_.empty()) + { + ORTHANC_PLUGINS_LOG_WARNING("Housekeeper: full processing needed -> ignoring the \"LimitMainDicomTagsReconstructLevel\" configuration"); + limitToChange_.clear(); + limitToUrl_.clear(); + } + // if a processing was in progress, check if the config has changed since if (pluginStatus_.currentlyProcessingConfiguration.IsDefined()) { @@ -679,7 +686,7 @@ } else { - ORTHANC_PLUGINS_LOG_WARNING("Housekeeper: the DB configuration has changed since last run, will reprocess the whole DB !"); + ORTHANC_PLUGINS_LOG_WARNING("Housekeeper: the Orthanc configuration has changed since last run, will reprocess the whole DB !"); } Json::Value changes; @@ -695,7 +702,7 @@ } else { - ORTHANC_PLUGINS_LOG_WARNING("Housekeeper: the DB configuration has not changed since last run, will continue processing changes"); + ORTHANC_PLUGINS_LOG_WARNING("Housekeeper: the Orthanc configuration has not changed since last run, will continue processing changes"); } bool completed = false;
--- a/OrthancServer/Sources/OrthancRestApi/OrthancRestResources.cpp Thu May 15 18:49:47 2025 +0200 +++ b/OrthancServer/Sources/OrthancRestApi/OrthancRestResources.cpp Fri May 16 17:19:35 2025 +0200 @@ -976,6 +976,8 @@ ImageToEncode image(decoded, mode, invert); HttpContentNegociation negociation; + + // The first call to "Register()" indicates the default content type (here, PNG) EncodePng png(image); negociation.Register(MIME_PNG, png);