Mercurial > hg > orthanc
changeset 3634:103ee029982e storage-commitment
integration default->storage-commitment
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Wed, 29 Jan 2020 08:51:31 +0100 |
parents | 7d1790d4fd74 (current diff) 5295a49dd78a (diff) |
children | 8c0ef729d5a8 |
files | |
diffstat | 11 files changed, 566 insertions(+), 2 deletions(-) [+] |
line wrap: on
line diff
--- a/.hgtags Thu Jan 23 18:00:46 2020 +0100 +++ b/.hgtags Wed Jan 29 08:51:31 2020 +0100 @@ -1,1 +1,4 @@ a95beca72e99f3a1110cffd252bcf3abf5a2db27 dcmtk-3.6.1 +19966d29968506773f90b733b6e34559839ca5c7 toa2020012701 +dfd9a2229c18abd5c794d8fec967ef0ed10b8e91 toa2020012702 +799a8278b151222ea9e8b8628b1d57b5b7943f41 toa2020012703
--- a/CMakeLists.txt Thu Jan 23 18:00:46 2020 +0100 +++ b/CMakeLists.txt Wed Jan 29 08:51:31 2020 +0100 @@ -37,6 +37,7 @@ SET(BUILD_MODALITY_WORKLISTS ON CACHE BOOL "Whether to build the sample plugin to serve modality worklists") SET(BUILD_RECOVER_COMPRESSED_FILE ON CACHE BOOL "Whether to build the companion tool to recover files compressed using Orthanc") SET(BUILD_SERVE_FOLDERS ON CACHE BOOL "Whether to build the ServeFolders plugin") +SET(BUILD_CONNECTIVITY_CHECKS ON CACHE BOOL "Whether to build the ConnectivityChecks plugin") SET(ENABLE_PLUGINS ON CACHE BOOL "Enable plugins") SET(UNIT_TESTS_WITH_HTTP_CONNEXIONS ON CACHE BOOL "Allow unit tests to make HTTP requests") @@ -461,6 +462,63 @@ ##################################################################### +## Build the "ConnectivityChecks" plugin +##################################################################### + +if (ENABLE_PLUGINS AND BUILD_CONNECTIVITY_CHECKS) + include(ExternalProject) + + set(Flags) + + if (CMAKE_TOOLCHAIN_FILE) + # Take absolute path to the toolchain + get_filename_component(TMP ${CMAKE_TOOLCHAIN_FILE} REALPATH BASE ${CMAKE_SOURCE_DIR}) + list(APPEND Flags -DCMAKE_TOOLCHAIN_FILE=${TMP}) + endif() + + if ("${CMAKE_SYSTEM_VERSION}" STREQUAL "LinuxStandardBase") + list(APPEND Flags + -DLSB_CC=${CMAKE_LSB_CC} + -DLSB_CXX=${CMAKE_LSB_CXX} + ) + endif() + + externalproject_add(ConnectivityChecksProject + SOURCE_DIR "${ORTHANC_ROOT}/Plugins/Samples/ConnectivityChecks" + + CMAKE_ARGS + -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE} + -DCMAKE_INSTALL_PREFIX=${CMAKE_CURRENT_BINARY_DIR} + -DPLUGIN_VERSION=${ORTHANC_VERSION} + -DSTATIC_BUILD=${STATIC_BUILD} + -DALLOW_DOWNLOADS=${ALLOW_DOWNLOADS} + -DUSE_LEGACY_JSONCPP=${USE_LEGACY_JSONCPP} + ${Flags} + ) + + if (${CMAKE_SYSTEM_NAME} STREQUAL "Windows") + if (MSVC) + set(Prefix "") + else() + set(Prefix "lib") # MinGW + endif() + + install(FILES + ${CMAKE_CURRENT_BINARY_DIR}/${Prefix}ConnectivityChecks.dll + DESTINATION "lib") + else() + list(GET CMAKE_FIND_LIBRARY_PREFIXES 0 Prefix) + list(GET CMAKE_FIND_LIBRARY_SUFFIXES 0 Suffix) + install(FILES + ${CMAKE_CURRENT_BINARY_DIR}/${Prefix}ConnectivityChecks${Suffix} + ${CMAKE_CURRENT_BINARY_DIR}/${Prefix}ConnectivityChecks${Suffix}.${ORTHANC_VERSION} + DESTINATION "share/orthanc/plugins") + endif() +endif() + + + +##################################################################### ## Build the companion tool to recover files compressed using Orthanc #####################################################################
--- a/Core/Logging.cpp Thu Jan 23 18:00:46 2020 +0100 +++ b/Core/Logging.cpp Wed Jan 29 08:51:31 2020 +0100 @@ -553,7 +553,7 @@ } } - bool IsInfoLevelEnable() + bool IsInfoLevelEnabled() { boost::mutex::scoped_lock lock(loggingMutex_); assert(loggingContext_.get() != NULL); @@ -575,7 +575,7 @@ } } - bool IsTraceLevelEnable() + bool IsTraceLevelEnabled() { boost::mutex::scoped_lock lock(loggingMutex_); assert(loggingContext_.get() != NULL);
--- a/NEWS Thu Jan 23 18:00:46 2020 +0100 +++ b/NEWS Wed Jan 29 08:51:31 2020 +0100 @@ -1,6 +1,11 @@ Pending changes in the mainline =============================== +Plugins +------- + +* New sample plugin: "ConnectivityChecks" + REST API --------
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Samples/ConnectivityChecks/CMakeLists.txt Wed Jan 29 08:51:31 2020 +0100 @@ -0,0 +1,65 @@ +cmake_minimum_required(VERSION 2.8) + +project(ConnectivityChecks) + +SET(PLUGIN_NAME "connectivity-checks" CACHE STRING "Name of the plugin") +SET(PLUGIN_VERSION "mainline" CACHE STRING "Version of the plugin") + +include(${CMAKE_CURRENT_SOURCE_DIR}/../../../Resources/CMake/OrthancFrameworkParameters.cmake) +include(${CMAKE_CURRENT_SOURCE_DIR}/../../../Resources/CMake/OrthancFrameworkConfiguration.cmake) + +include(JavaScriptLibraries.cmake) + +if (${CMAKE_SYSTEM_NAME} STREQUAL "Windows") + execute_process( + COMMAND + ${PYTHON_EXECUTABLE} ${ORTHANC_ROOT}/Resources/WindowsResources.py + ${PLUGIN_VERSION} ConnectivityChecks ConnectivityChecks.dll "Orthanc plugin to serve additional folders" + ERROR_VARIABLE Failure + OUTPUT_FILE ${AUTOGENERATED_DIR}/ConnectivityChecks.rc + ) + + if (Failure) + message(FATAL_ERROR "Error while computing the version information: ${Failure}") + endif() + + list(APPEND ADDITIONAL_RESOURCES ${AUTOGENERATED_DIR}/ConnectivityChecks.rc) +endif() + +EmbedResources( + WEB_RESOURCES ${CMAKE_CURRENT_SOURCE_DIR}/WebResources + LIBRARIES ${JAVASCRIPT_LIBS_DIR} + ) + +add_definitions( + -DHAS_ORTHANC_EXCEPTION=1 + -DORTHANC_ENABLE_LOGGING_PLUGIN=1 + -DORTHANC_PLUGIN_NAME="${PLUGIN_NAME}" + -DORTHANC_PLUGIN_VERSION="${PLUGIN_VERSION}" + ) + +include_directories( + ${ORTHANC_ROOT}/Plugins/Include/ + ) + +add_library(ConnectivityChecks SHARED + ${ADDITIONAL_RESOURCES} + ${AUTOGENERATED_SOURCES} + ${ORTHANC_CORE_SOURCES_DEPENDENCIES} + ${ORTHANC_ROOT}/Core/Enumerations.cpp + ${ORTHANC_ROOT}/Core/Logging.cpp + ${ORTHANC_ROOT}/Core/SystemToolbox.cpp + ${ORTHANC_ROOT}/Core/Toolbox.cpp + Plugin.cpp + ) + +set_target_properties( + ConnectivityChecks PROPERTIES + VERSION ${PLUGIN_VERSION} + SOVERSION ${PLUGIN_VERSION} + ) + +install( + TARGETS ConnectivityChecks + DESTINATION . + )
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Samples/ConnectivityChecks/JavaScriptLibraries.cmake Wed Jan 29 08:51:31 2020 +0100 @@ -0,0 +1,42 @@ +set(BASE_URL "http://orthanc.osimis.io/ThirdPartyDownloads") + +DownloadPackage( + "da0189f7c33bf9f652ea65401e0a3dc9" + "${BASE_URL}/dicom-web/bootstrap-4.3.1.zip" + "${CMAKE_CURRENT_BINARY_DIR}/bootstrap-4.3.1") + +DownloadPackage( + "8242afdc5bd44105d9dc9e6535315484" + "${BASE_URL}/dicom-web/vuejs-2.6.10.tar.gz" + "${CMAKE_CURRENT_BINARY_DIR}/vue-2.6.10") + +DownloadPackage( + "3e2b4e1522661f7fcf8ad49cb933296c" + "${BASE_URL}/dicom-web/axios-0.19.0.tar.gz" + "${CMAKE_CURRENT_BINARY_DIR}/axios-0.19.0") + +DownloadFile( + "220afd743d9e9643852e31a135a9f3ae" + "${BASE_URL}/jquery-3.4.1.min.js") + + +set(JAVASCRIPT_LIBS_DIR ${CMAKE_CURRENT_BINARY_DIR}/javascript-libs) +file(MAKE_DIRECTORY ${JAVASCRIPT_LIBS_DIR}) + +file(COPY + ${CMAKE_CURRENT_BINARY_DIR}/axios-0.19.0/dist/axios.min.js + ${CMAKE_CURRENT_BINARY_DIR}/axios-0.19.0/dist/axios.min.map + ${CMAKE_CURRENT_BINARY_DIR}/bootstrap-4.3.1/dist/js/bootstrap.min.js + ${CMAKE_CURRENT_BINARY_DIR}/bootstrap-4.3.1/dist/js/bootstrap.min.js.map + ${CMAKE_CURRENT_BINARY_DIR}/vue-2.6.10/dist/vue.min.js + ${CMAKE_SOURCE_DIR}/ThirdPartyDownloads/jquery-3.4.1.min.js + DESTINATION + ${JAVASCRIPT_LIBS_DIR}/js + ) + +file(COPY + ${CMAKE_CURRENT_BINARY_DIR}/bootstrap-4.3.1/dist/css/bootstrap.min.css + ${CMAKE_CURRENT_BINARY_DIR}/bootstrap-4.3.1/dist/css/bootstrap.min.css.map + DESTINATION + ${JAVASCRIPT_LIBS_DIR}/css + )
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Samples/ConnectivityChecks/Plugin.cpp Wed Jan 29 08:51:31 2020 +0100 @@ -0,0 +1,124 @@ +/** + * Orthanc - A Lightweight, RESTful DICOM Store + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017-2019 Osimis S.A., Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * In addition, as a special exception, the copyright holders of this + * program give permission to link the code of its release with the + * OpenSSL project's "OpenSSL" library (or with modified versions of it + * that use the same license as the "OpenSSL" library), and distribute + * the linked executables. You must obey the GNU General Public License + * in all respects for all of the code used other than "OpenSSL". If you + * modify file(s) with this exception, you may extend this exception to + * your version of the file(s), but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. If you delete this exception statement from all source files + * in the program, then also delete it here. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + **/ + + +#include <EmbeddedResources.h> +#include <orthanc/OrthancCPlugin.h> + +#include "../../../Core/OrthancException.h" +#include "../../../Core/SystemToolbox.h" + +#define ROOT_URI "/connectivity-checks" + + +static OrthancPluginContext* context_ = NULL; + + +template <Orthanc::EmbeddedResources::DirectoryResourceId DIRECTORY> +static OrthancPluginErrorCode ServeStaticResource(OrthancPluginRestOutput* output, + const char* url, + const OrthancPluginHttpRequest* request) +{ + if (request->method != OrthancPluginHttpMethod_Get) + { + OrthancPluginSendMethodNotAllowed(context_, output, "GET"); + return OrthancPluginErrorCode_Success; + } + + std::string path = "/" + std::string(request->groups[0]); + std::string mime = Orthanc::EnumerationToString(Orthanc::SystemToolbox::AutodetectMimeType(path)); + + try + { + std::string s; + Orthanc::EmbeddedResources::GetDirectoryResource(s, DIRECTORY, path.c_str()); + + const char* resource = s.size() ? s.c_str() : NULL; + OrthancPluginAnswerBuffer(context_, output, resource, s.size(), mime.c_str()); + } + catch (Orthanc::OrthancException&) + { + std::string s = "Unknown static resource in plugin: " + std::string(request->groups[0]); + OrthancPluginLogError(context_, s.c_str()); + OrthancPluginSendHttpStatusCode(context_, output, 404); + } + + return OrthancPluginErrorCode_Success; +} + + + +extern "C" +{ + ORTHANC_PLUGINS_API int32_t OrthancPluginInitialize(OrthancPluginContext* c) + { + context_ = c; + + /* Check the version of the Orthanc core */ + if (OrthancPluginCheckVersion(c) == 0) + { + char info[256]; + sprintf(info, "Your version of Orthanc (%s) must be above %d.%d.%d to run this plugin", + c->orthancVersion, + ORTHANC_PLUGINS_MINIMAL_MAJOR_NUMBER, + ORTHANC_PLUGINS_MINIMAL_MINOR_NUMBER, + ORTHANC_PLUGINS_MINIMAL_REVISION_NUMBER); + OrthancPluginLogError(context_, info); + return -1; + } + + /* Register the callbacks */ + OrthancPluginSetDescription(context_, "Utilities to check connectivity to DICOM modalities, DICOMweb servers and Orthanc peers."); + OrthancPluginSetRootUri(context_, ROOT_URI "/app/index.html"); + OrthancPluginRegisterRestCallback(context_, ROOT_URI "/libs/(.*)", ServeStaticResource<Orthanc::EmbeddedResources::LIBRARIES>); + OrthancPluginRegisterRestCallback(context_, ROOT_URI "/app/(.*)", ServeStaticResource<Orthanc::EmbeddedResources::WEB_RESOURCES>); + + return 0; + } + + + ORTHANC_PLUGINS_API void OrthancPluginFinalize() + { + } + + + ORTHANC_PLUGINS_API const char* OrthancPluginGetName() + { + return ORTHANC_PLUGIN_NAME; + } + + + ORTHANC_PLUGINS_API const char* OrthancPluginGetVersion() + { + return ORTHANC_PLUGIN_VERSION; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Samples/ConnectivityChecks/WebResources/app.js Wed Jan 29 08:51:31 2020 +0100 @@ -0,0 +1,145 @@ +/** + * Orthanc - A Lightweight, RESTful DICOM Store + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017-2019 Osimis S.A., Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * In addition, as a special exception, the copyright holders of this + * program give permission to link the code of its release with the + * OpenSSL project's "OpenSSL" library (or with modified versions of it + * that use the same license as the "OpenSSL" library), and distribute + * the linked executables. You must obey the GNU General Public License + * in all respects for all of the code used other than "OpenSSL". If you + * modify file(s) with this exception, you may extend this exception to + * your version of the file(s), but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. If you delete this exception statement from all source files + * in the program, then also delete it here. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + **/ + + +new Vue({ + el: '#app', + data: { + dicomNodes: {}, + peers: [], + canTestPeers: false, + dicomWebServers: [] + }, + methods: { + toggle: function (todo) { + todo.done = !todo.done + }, + + testDicomModalities: function () { + console.log('testing DICOM modalities'); + axios + .get('../../modalities?expand') + .then(response => { + this.dicomNodes = response.data; + for (let alias of Object.keys(this.dicomNodes)) { + this.dicomNodes[alias]['alias'] = alias; + this.dicomNodes[alias]['status'] = 'testing'; + axios + .post('../../modalities/' + alias + '/echo') + .then(response => { + this.dicomNodes[alias]['status'] = 'ok'; + this.$forceUpdate(); + }) + .catch(response => { + this.dicomNodes[alias]['status'] = 'ko'; + this.$forceUpdate(); + }) + } + }) + }, + + testOrthancPeers: function () { + console.log('testing Orthanc peers'); + axios + .get('../../peers?expand') + .then(response => { + this.peers = response.data; + for (let alias of Object.keys(this.peers)) { + this.peers[alias]['alias'] = alias; + + if (this.canTestPeers) { + this.peers[alias]['status'] = 'testing'; + axios + .get('../../peers/' + alias + '/system') // introduced in ApiVersion 5 only ! + .then(response => { + this.peers[alias]['status'] = 'ok'; + this.$forceUpdate(); + }) + .catch(response => { + this.peers[alias]['status'] = 'ko'; + this.$forceUpdate(); + }) + } + else { + this.peers[alias]['status'] = 'unknown'; + this.$forceUpdate(); + } + } + }) + }, + + testDicomWebServers: function () { + console.log('testing Dicom-web servers'); + axios + .get('../../dicom-web/servers?expand') + .then(response => { + this.dicomWebServers = response.data; + for (let alias of Object.keys(this.dicomWebServers)) { + this.dicomWebServers[alias]['alias'] = alias; + this.dicomWebServers[alias]['status'] = 'testing'; + + // perform a dummy qido-rs to test the connectivity + axios + .post('../../dicom-web/servers/' + alias + '/qido', { + 'Uri' : '/studies', + 'Arguments' : { + '00100010' : 'CONNECTIVITY^CHECKS' + } + }) + .then(response => { + this.dicomWebServers[alias]['status'] = 'ok'; + this.$forceUpdate(); + }) + .catch(response => { + this.dicomWebServers[alias]['status'] = 'ko'; + this.$forceUpdate(); + }) + } + }) + }, + + }, + computed: { + }, + mounted() { + axios + .get('../../system') + .then(response => { + this.canTestPeers = response.data.ApiVersion >= 5; + this.testDicomModalities(); + if (this.canTestPeers) { + this.testOrthancPeers(); + } + this.testDicomWebServers(); + }) + } +})
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Samples/ConnectivityChecks/WebResources/index.html Wed Jan 29 08:51:31 2020 +0100 @@ -0,0 +1,100 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="UTF-8"> + + <link rel="stylesheet" href="../libs/css/bootstrap.min.css"> + + <title>Orthanc Connectivity checks</title> + <link rel="stylesheet" href="style.css" type="text/css"> + </head> + + <body> + <div id="app" class="container-fluid"> + <h2>DICOM nodes</h2> + <table class="table"> + <thead> + <tr> + <th scope="col">Alias</th> + <th scope="col">AET</th> + <th scope="col">Host</th> + <th scope="col">Port</th> + <th scope="col">Status</th> + </tr> + </thead> + <tbody> + <tr v-for="node in dicomNodes"> + <th scope="row">{{node.alias}}</th> + <td>{{node.AET}}</td> + <td>{{node.Host}}</td> + <td>{{node.Port}}</td> + <td v-if="node.status=='ok'" class="connected">Connected</td> + <td v-if="node.status=='ko'" class="disconnected">Disconnected</td> + <td v-if="node.status=='testing'"> + <div class="spinner-border" role="status"> + <span class="sr-only">Testing...</span> + </div> + </td> + </tr> + </tbody> + </table> + + <h2>Orthanc peers</h2> + <table class="table" v-if="canTestPeers"> + <thead> + <tr> + <th scope="col">Alias</th> + <th scope="col">Url</th> + <th scope="col">Status</th> + </tr> + </thead> + <tbody> + <tr v-for="node in peers"> + <th scope="row">{{node.alias}}</th> + <td>{{node.Url}}</td> + <td v-if="node.status=='ok'" class="connected">Connected</td> + <td v-if="node.status=='ko'" class="disconnected">Disconnected</td> + <td v-if="node.status=='unknown'" class="unknown"> + Can not test the peers connectivity with this version of Orthanc + </td> + <td v-if="node.status=='testing'"> + <div class="spinner-border" role="status"> + <span class="sr-only">Testing...</span> + </div> + </td> + </tr> + </tbody> + </table> + + <h2>DicomWeb servers</h2> + <table class="table"> + <thead> + <tr> + <th scope="col">Alias</th> + <th scope="col">Url</th> + <th scope="col">Status</th> + </tr> + </thead> + <tbody> + <tr v-for="node in dicomWebServers"> + <th scope="row">{{node.alias}}</th> + <td>{{node.Url}}</td> + <td v-if="node.status=='ok'" class="connected">Connected</td> + <td v-if="node.status=='ko'" class="disconnected">Disconnected</td> + <td v-if="node.status=='testing'"> + <div class="spinner-border" role="status"> + <span class="sr-only">Testing...</span> + </div> + </td> + </tr> + </tbody> + </table> + </div> + + <script src="../libs/js/jquery-3.4.1.min.js" type="text/javascript"></script> + <script src="../libs/js/bootstrap.min.js" type="text/javascript"></script> + <script src="../libs/js/axios.min.js" type="text/javascript"></script> + <script src="../libs/js/vue.min.js" type="text/javascript"></script> + <script src="app.js" type="text/javascript"></script> + </body> +</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Samples/ConnectivityChecks/WebResources/style.css Wed Jan 29 08:51:31 2020 +0100 @@ -0,0 +1,13 @@ +.connected { + background-color: darkgreen; + color: white; +} + +.disconnected { + background-color: darkred; + color: white; +} + +.unknown { + background-color: gold; +}
--- a/Resources/CMake/Compiler.cmake Thu Jan 23 18:00:46 2020 +0100 +++ b/Resources/CMake/Compiler.cmake Wed Jan 29 08:51:31 2020 +0100 @@ -7,6 +7,15 @@ SET(STANDALONE_BUILD ON) endif() + +if ("${CMAKE_SYSTEM_VERSION}" STREQUAL "LinuxStandardBase") + # Cache the environment variables "LSB_CC" and "LSB_CXX" for further + # use by "ExternalProject" in CMake + SET(CMAKE_LSB_CC $ENV{LSB_CC} CACHE STRING "") + SET(CMAKE_LSB_CXX $ENV{LSB_CXX} CACHE STRING "") +endif() + + if (CMAKE_COMPILER_IS_GNUCXX) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wno-long-long")