comparison OrthancServer/main.cpp @ 2940:4767d36679ed

refactoring access to Orthanc configuration
author Sebastien Jodogne <s.jodogne@gmail.com>
date Thu, 29 Nov 2018 11:47:00 +0100
parents 1153b1a128fe
children e292798f9980
comparison
equal deleted inserted replaced
2939:577786f59252 2940:4767d36679ed
34 #include "PrecompiledHeadersServer.h" 34 #include "PrecompiledHeadersServer.h"
35 #include "OrthancRestApi/OrthancRestApi.h" 35 #include "OrthancRestApi/OrthancRestApi.h"
36 36
37 #include <boost/algorithm/string/predicate.hpp> 37 #include <boost/algorithm/string/predicate.hpp>
38 38
39 #include "../Core/Logging.h" 39 #include "../Core/DicomFormat/DicomArray.h"
40 #include "../Core/DicomNetworking/DicomServer.h"
41 #include "../Core/DicomParsing/FromDcmtkBridge.h"
40 #include "../Core/HttpServer/EmbeddedResourceHttpHandler.h" 42 #include "../Core/HttpServer/EmbeddedResourceHttpHandler.h"
41 #include "../Core/HttpServer/FilesystemHttpHandler.h" 43 #include "../Core/HttpServer/FilesystemHttpHandler.h"
44 #include "../Core/HttpServer/MongooseServer.h"
45 #include "../Core/Logging.h"
42 #include "../Core/Lua/LuaFunctionCall.h" 46 #include "../Core/Lua/LuaFunctionCall.h"
43 #include "../Core/DicomFormat/DicomArray.h" 47 #include "../Plugins/Engine/OrthancPlugins.h"
44 #include "../Core/DicomNetworking/DicomServer.h" 48 #include "OrthancConfiguration.h"
49 #include "OrthancFindRequestHandler.h"
45 #include "OrthancInitialization.h" 50 #include "OrthancInitialization.h"
51 #include "OrthancMoveRequestHandler.h"
46 #include "ServerContext.h" 52 #include "ServerContext.h"
47 #include "OrthancFindRequestHandler.h"
48 #include "OrthancMoveRequestHandler.h"
49 #include "ServerToolbox.h" 53 #include "ServerToolbox.h"
50 #include "../Plugins/Engine/OrthancPlugins.h"
51 #include "../Core/DicomParsing/FromDcmtkBridge.h"
52 54
53 using namespace Orthanc; 55 using namespace Orthanc;
54 56
55 57
56 class OrthancStoreRequestHandler : public IStoreRequestHandler 58 class OrthancStoreRequestHandler : public IStoreRequestHandler
87 } 89 }
88 }; 90 };
89 91
90 92
91 93
92 class ModalitiesFromConfiguration : public Orthanc::DicomServer::IRemoteModalities 94 class ModalitiesFromConfiguration : public DicomServer::IRemoteModalities
93 { 95 {
94 public: 96 public:
95 virtual bool IsSameAETitle(const std::string& aet1, 97 virtual bool IsSameAETitle(const std::string& aet1,
96 const std::string& aet2) 98 const std::string& aet2)
97 { 99 {
98 return Orthanc::Configuration::IsSameAETitle(aet1, aet2); 100 OrthancConfiguration::ReaderLock lock;
101 return lock.GetConfiguration().IsSameAETitle(aet1, aet2);
99 } 102 }
100 103
101 virtual bool LookupAETitle(RemoteModalityParameters& modality, 104 virtual bool LookupAETitle(RemoteModalityParameters& modality,
102 const std::string& aet) 105 const std::string& aet)
103 { 106 {
104 return Orthanc::Configuration::LookupDicomModalityUsingAETitle(modality, aet); 107 OrthancConfiguration::ReaderLock lock;
108 return lock.GetConfiguration().LookupDicomModalityUsingAETitle(modality, aet);
105 } 109 }
106 }; 110 };
107 111
108 112
109 class MyDicomServerFactory : 113 class MyDicomServerFactory :
126 130
127 virtual IFindRequestHandler* ConstructFindRequestHandler() 131 virtual IFindRequestHandler* ConstructFindRequestHandler()
128 { 132 {
129 std::auto_ptr<OrthancFindRequestHandler> result(new OrthancFindRequestHandler(context_)); 133 std::auto_ptr<OrthancFindRequestHandler> result(new OrthancFindRequestHandler(context_));
130 134
131 result->SetMaxResults(Configuration::GetGlobalUnsignedIntegerParameter("LimitFindResults", 0)); 135 {
132 result->SetMaxInstances(Configuration::GetGlobalUnsignedIntegerParameter("LimitFindInstances", 0)); 136 OrthancConfiguration::ReaderLock lock;
137 result->SetMaxResults(lock.GetConfiguration().GetUnsignedIntegerParameter("LimitFindResults", 0));
138 result->SetMaxInstances(lock.GetConfiguration().GetUnsignedIntegerParameter("LimitFindInstances", 0));
139 }
133 140
134 if (result->GetMaxResults() == 0) 141 if (result->GetMaxResults() == 0)
135 { 142 {
136 LOG(INFO) << "No limit on the number of C-FIND results at the Patient, Study and Series levels"; 143 LOG(INFO) << "No limit on the number of C-FIND results at the Patient, Study and Series levels";
137 } 144 }
174 181
175 public: 182 public:
176 OrthancApplicationEntityFilter(ServerContext& context) : 183 OrthancApplicationEntityFilter(ServerContext& context) :
177 context_(context) 184 context_(context)
178 { 185 {
179 alwaysAllowEcho_ = Configuration::GetGlobalBoolParameter("DicomAlwaysAllowEcho", true); 186 OrthancConfiguration::ReaderLock lock;
180 alwaysAllowStore_ = Configuration::GetGlobalBoolParameter("DicomAlwaysAllowStore", true); 187 alwaysAllowEcho_ = lock.GetConfiguration().GetBooleanParameter("DicomAlwaysAllowEcho", true);
188 alwaysAllowStore_ = lock.GetConfiguration().GetBooleanParameter("DicomAlwaysAllowStore", true);
181 } 189 }
182 190
183 virtual bool IsAllowedConnection(const std::string& remoteIp, 191 virtual bool IsAllowedConnection(const std::string& remoteIp,
184 const std::string& remoteAet, 192 const std::string& remoteAet,
185 const std::string& calledAet) 193 const std::string& calledAet)
186 { 194 {
187 LOG(INFO) << "Incoming connection from AET " << remoteAet 195 LOG(INFO) << "Incoming connection from AET " << remoteAet
188 << " on IP " << remoteIp << ", calling AET " << calledAet; 196 << " on IP " << remoteIp << ", calling AET " << calledAet;
189 197
190 return (alwaysAllowEcho_ || 198 if (alwaysAllowEcho_ ||
191 alwaysAllowStore_ || 199 alwaysAllowStore_)
192 Configuration::IsKnownAETitle(remoteAet, remoteIp)); 200 {
201 return true;
202 }
203 else
204 {
205 OrthancConfiguration::ReaderLock lock;
206 return lock.GetConfiguration().IsKnownAETitle(remoteAet, remoteIp);
207 }
193 } 208 }
194 209
195 virtual bool IsAllowedRequest(const std::string& remoteIp, 210 virtual bool IsAllowedRequest(const std::string& remoteIp,
196 const std::string& remoteAet, 211 const std::string& remoteAet,
197 const std::string& calledAet, 212 const std::string& calledAet,
198 DicomRequestType type) 213 DicomRequestType type)
199 { 214 {
200 LOG(INFO) << "Incoming " << Orthanc::EnumerationToString(type) << " request from AET " 215 LOG(INFO) << "Incoming " << EnumerationToString(type) << " request from AET "
201 << remoteAet << " on IP " << remoteIp << ", calling AET " << calledAet; 216 << remoteAet << " on IP " << remoteIp << ", calling AET " << calledAet;
202 217
203 if (type == DicomRequestType_Echo && 218 if (type == DicomRequestType_Echo &&
204 alwaysAllowEcho_) 219 alwaysAllowEcho_)
205 { 220 {
212 // Incoming C-Store requests are always accepted, even from unknown AET 227 // Incoming C-Store requests are always accepted, even from unknown AET
213 return true; 228 return true;
214 } 229 }
215 else 230 else
216 { 231 {
232 OrthancConfiguration::ReaderLock lock;
233
217 RemoteModalityParameters modality; 234 RemoteModalityParameters modality;
218 235 if (lock.GetConfiguration().LookupDicomModalityUsingAETitle(modality, remoteAet))
219 if (Configuration::LookupDicomModalityUsingAETitle(modality, remoteAet))
220 { 236 {
221 return modality.IsRequestAllowed(type); 237 return modality.IsRequestAllowed(type);
222 } 238 }
223 else 239 else
224 { 240 {
281 call.PushString(calledAet); 297 call.PushString(calledAet);
282 return call.ExecutePredicate(); 298 return call.ExecutePredicate();
283 } 299 }
284 } 300 }
285 301
286 return Configuration::GetGlobalBoolParameter(configuration, true); 302 {
303 OrthancConfiguration::ReaderLock lock;
304 return lock.GetConfiguration().GetBooleanParameter(configuration, true);
305 }
287 } 306 }
288 307
289 308
290 virtual bool IsUnknownSopClassAccepted(const std::string& remoteIp, 309 virtual bool IsUnknownSopClassAccepted(const std::string& remoteIp,
291 const std::string& remoteAet, 310 const std::string& remoteAet,
306 call.PushString(calledAet); 325 call.PushString(calledAet);
307 return call.ExecutePredicate(); 326 return call.ExecutePredicate();
308 } 327 }
309 } 328 }
310 329
311 return Configuration::GetGlobalBoolParameter(configuration, false); 330 {
331 OrthancConfiguration::ReaderLock lock;
332 return lock.GetConfiguration().GetBooleanParameter(configuration, false);
333 }
312 } 334 }
313 }; 335 };
314 336
315 337
316 class MyIncomingHttpRequestFilter : public IIncomingHttpRequestFilter 338 class MyIncomingHttpRequestFilter : public IIncomingHttpRequestFilter
650 672
651 #if ORTHANC_ENABLE_PLUGINS == 1 673 #if ORTHANC_ENABLE_PLUGINS == 1
652 static void LoadPlugins(OrthancPlugins& plugins) 674 static void LoadPlugins(OrthancPlugins& plugins)
653 { 675 {
654 std::list<std::string> path; 676 std::list<std::string> path;
655 Configuration::GetGlobalListOfStringsParameter(path, "Plugins"); 677
678 {
679 OrthancConfiguration::ReaderLock lock;
680 lock.GetConfiguration().GetListOfStringsParameter(path, "Plugins");
681 }
682
656 for (std::list<std::string>::const_iterator 683 for (std::list<std::string>::const_iterator
657 it = path.begin(); it != path.end(); ++it) 684 it = path.begin(); it != path.end(); ++it)
658 { 685 {
659 std::string path = Configuration::InterpretStringParameterAsPath(*it); 686 std::string path;
687
688 {
689 OrthancConfiguration::ReaderLock lock;
690 path = lock.GetConfiguration().InterpretStringParameterAsPath(*it);
691 }
692
660 LOG(WARNING) << "Loading plugin(s) from: " << path; 693 LOG(WARNING) << "Loading plugin(s) from: " << path;
661 plugins.GetManager().RegisterPlugin(path); 694 plugins.GetManager().RegisterPlugin(path);
662 } 695 }
663 } 696 }
664 #endif 697 #endif
691 if (!restart && 724 if (!restart &&
692 event == ServerBarrierEvent_Reload) 725 event == ServerBarrierEvent_Reload)
693 { 726 {
694 // Handling of SIGHUP 727 // Handling of SIGHUP
695 728
696 if (Configuration::HasConfigurationChanged()) 729 OrthancConfiguration::ReaderLock lock;
730 if (lock.GetConfiguration().HasConfigurationChanged())
697 { 731 {
698 LOG(WARNING) << "A SIGHUP signal has been received, resetting Orthanc"; 732 LOG(WARNING) << "A SIGHUP signal has been received, resetting Orthanc";
699 Logging::Flush(); 733 Logging::Flush();
700 restart = true; 734 restart = true;
701 break; 735 break;
738 772
739 static bool StartHttpServer(ServerContext& context, 773 static bool StartHttpServer(ServerContext& context,
740 OrthancRestApi& restApi, 774 OrthancRestApi& restApi,
741 OrthancPlugins* plugins) 775 OrthancPlugins* plugins)
742 { 776 {
743 if (!Configuration::GetGlobalBoolParameter("HttpServerEnabled", true)) 777 bool httpServerEnabled;
778
779 {
780 OrthancConfiguration::ReaderLock lock;
781 httpServerEnabled = lock.GetConfiguration().GetBooleanParameter("HttpServerEnabled", true);
782 }
783
784 if (!httpServerEnabled)
744 { 785 {
745 LOG(WARNING) << "The HTTP server is disabled"; 786 LOG(WARNING) << "The HTTP server is disabled";
746 return WaitForExit(context, restApi); 787 return WaitForExit(context, restApi);
747 } 788 }
748 789 else
749 MyHttpExceptionFormatter exceptionFormatter(Configuration::GetGlobalBoolParameter("HttpDescribeErrors", true), plugins); 790 {
791 MyIncomingHttpRequestFilter httpFilter(context, plugins);
792 MongooseServer httpServer;
793 bool httpDescribeErrors;
794
795 {
796 OrthancConfiguration::ReaderLock lock;
797
798 httpDescribeErrors = lock.GetConfiguration().GetBooleanParameter("HttpDescribeErrors", true);
750 799
751 800 // HTTP server
752 // HTTP server 801 //httpServer.SetThreadsCount(50);
753 MyIncomingHttpRequestFilter httpFilter(context, plugins); 802 httpServer.SetPortNumber(lock.GetConfiguration().GetUnsignedIntegerParameter("HttpPort", 8042));
754 MongooseServer httpServer; 803 httpServer.SetRemoteAccessAllowed(lock.GetConfiguration().GetBooleanParameter("RemoteAccessAllowed", false));
755 //httpServer.SetThreadsCount(50); 804 httpServer.SetKeepAliveEnabled(lock.GetConfiguration().GetBooleanParameter("KeepAlive", false));
756 httpServer.SetPortNumber(Configuration::GetGlobalUnsignedIntegerParameter("HttpPort", 8042)); 805 httpServer.SetHttpCompressionEnabled(lock.GetConfiguration().GetBooleanParameter("HttpCompressionEnabled", true));
757 httpServer.SetRemoteAccessAllowed(Configuration::GetGlobalBoolParameter("RemoteAccessAllowed", false)); 806 httpServer.SetAuthenticationEnabled(lock.GetConfiguration().GetBooleanParameter("AuthenticationEnabled", false));
758 httpServer.SetKeepAliveEnabled(Configuration::GetGlobalBoolParameter("KeepAlive", false)); 807
759 httpServer.SetHttpCompressionEnabled(Configuration::GetGlobalBoolParameter("HttpCompressionEnabled", true)); 808 lock.GetConfiguration().SetupRegisteredUsers(httpServer);
760 httpServer.SetIncomingHttpRequestFilter(httpFilter); 809
761 httpServer.SetHttpExceptionFormatter(exceptionFormatter); 810 if (lock.GetConfiguration().GetBooleanParameter("SslEnabled", false))
762 811 {
763 httpServer.SetAuthenticationEnabled(Configuration::GetGlobalBoolParameter("AuthenticationEnabled", false)); 812 std::string certificate = lock.GetConfiguration().InterpretStringParameterAsPath(
764 Configuration::SetupRegisteredUsers(httpServer); 813 lock.GetConfiguration().GetStringParameter("SslCertificate", "certificate.pem"));
765 814 httpServer.SetSslEnabled(true);
766 if (Configuration::GetGlobalBoolParameter("SslEnabled", false)) 815 httpServer.SetSslCertificate(certificate.c_str());
767 { 816 }
768 std::string certificate = Configuration::InterpretStringParameterAsPath( 817 else
769 Configuration::GetGlobalStringParameter("SslCertificate", "certificate.pem")); 818 {
770 httpServer.SetSslEnabled(true); 819 httpServer.SetSslEnabled(false);
771 httpServer.SetSslCertificate(certificate.c_str()); 820 }
772 } 821 }
773 else 822
774 { 823 MyHttpExceptionFormatter exceptionFormatter(httpDescribeErrors, plugins);
775 httpServer.SetSslEnabled(false); 824
776 } 825 httpServer.SetIncomingHttpRequestFilter(httpFilter);
777 826 httpServer.SetHttpExceptionFormatter(exceptionFormatter);
778 httpServer.Register(context.GetHttpHandler()); 827 httpServer.Register(context.GetHttpHandler());
779 828
780 if (httpServer.GetPortNumber() < 1024) 829 if (httpServer.GetPortNumber() < 1024)
781 { 830 {
782 LOG(WARNING) << "The HTTP port is privileged (" 831 LOG(WARNING) << "The HTTP port is privileged ("
783 << httpServer.GetPortNumber() << " is below 1024), " 832 << httpServer.GetPortNumber() << " is below 1024), "
784 << "make sure you run Orthanc as root/administrator"; 833 << "make sure you run Orthanc as root/administrator";
785 } 834 }
786 835
787 httpServer.Start(); 836 httpServer.Start();
788 837
789 bool restart = WaitForExit(context, restApi); 838 bool restart = WaitForExit(context, restApi);
790 839
791 httpServer.Stop(); 840 httpServer.Stop();
792 LOG(WARNING) << " HTTP server has stopped"; 841 LOG(WARNING) << " HTTP server has stopped";
793 842
794 return restart; 843 return restart;
844 }
795 } 845 }
796 846
797 847
798 static bool StartDicomServer(ServerContext& context, 848 static bool StartDicomServer(ServerContext& context,
799 OrthancRestApi& restApi, 849 OrthancRestApi& restApi,
800 OrthancPlugins* plugins) 850 OrthancPlugins* plugins)
801 { 851 {
802 if (!Configuration::GetGlobalBoolParameter("DicomServerEnabled", true)) 852 bool dicomServerEnabled;
853
854 {
855 OrthancConfiguration::ReaderLock lock;
856 dicomServerEnabled = lock.GetConfiguration().GetBooleanParameter("DicomServerEnabled", true);
857 }
858
859 if (!dicomServerEnabled)
803 { 860 {
804 LOG(WARNING) << "The DICOM server is disabled"; 861 LOG(WARNING) << "The DICOM server is disabled";
805 return StartHttpServer(context, restApi, plugins); 862 return StartHttpServer(context, restApi, plugins);
806 } 863 }
807 864 else
808 MyDicomServerFactory serverFactory(context); 865 {
809 OrthancApplicationEntityFilter dicomFilter(context); 866 MyDicomServerFactory serverFactory(context);
810 ModalitiesFromConfiguration modalities; 867 OrthancApplicationEntityFilter dicomFilter(context);
868 ModalitiesFromConfiguration modalities;
811 869
812 // Setup the DICOM server 870 // Setup the DICOM server
813 DicomServer dicomServer; 871 DicomServer dicomServer;
814 dicomServer.SetRemoteModalities(modalities); 872 dicomServer.SetRemoteModalities(modalities);
815 dicomServer.SetCalledApplicationEntityTitleCheck(Configuration::GetGlobalBoolParameter("DicomCheckCalledAet", false)); 873 dicomServer.SetStoreRequestHandlerFactory(serverFactory);
816 dicomServer.SetStoreRequestHandlerFactory(serverFactory); 874 dicomServer.SetMoveRequestHandlerFactory(serverFactory);
817 dicomServer.SetMoveRequestHandlerFactory(serverFactory); 875 dicomServer.SetFindRequestHandlerFactory(serverFactory);
818 dicomServer.SetFindRequestHandlerFactory(serverFactory); 876
819 dicomServer.SetAssociationTimeout(Configuration::GetGlobalUnsignedIntegerParameter("DicomScpTimeout", 30)); 877 {
820 878 OrthancConfiguration::ReaderLock lock;
879 dicomServer.SetCalledApplicationEntityTitleCheck(lock.GetConfiguration().GetBooleanParameter("DicomCheckCalledAet", false));
880 dicomServer.SetAssociationTimeout(lock.GetConfiguration().GetUnsignedIntegerParameter("DicomScpTimeout", 30));
881 dicomServer.SetPortNumber(lock.GetConfiguration().GetUnsignedIntegerParameter("DicomPort", 4242));
882 dicomServer.SetApplicationEntityTitle(lock.GetConfiguration().GetStringParameter("DicomAet", "ORTHANC"));
883 }
821 884
822 #if ORTHANC_ENABLE_PLUGINS == 1 885 #if ORTHANC_ENABLE_PLUGINS == 1
823 if (plugins != NULL) 886 if (plugins != NULL)
824 { 887 {
825 if (plugins->HasWorklistHandler()) 888 if (plugins->HasWorklistHandler())
826 { 889 {
827 dicomServer.SetWorklistRequestHandlerFactory(*plugins); 890 dicomServer.SetWorklistRequestHandlerFactory(*plugins);
828 } 891 }
829 892
830 if (plugins->HasFindHandler()) 893 if (plugins->HasFindHandler())
831 { 894 {
832 dicomServer.SetFindRequestHandlerFactory(*plugins); 895 dicomServer.SetFindRequestHandlerFactory(*plugins);
833 } 896 }
834 897
835 if (plugins->HasMoveHandler()) 898 if (plugins->HasMoveHandler())
836 { 899 {
837 dicomServer.SetMoveRequestHandlerFactory(*plugins); 900 dicomServer.SetMoveRequestHandlerFactory(*plugins);
838 } 901 }
839 } 902 }
840 #endif 903 #endif
841 904
842 dicomServer.SetPortNumber(Configuration::GetGlobalUnsignedIntegerParameter("DicomPort", 4242)); 905 dicomServer.SetApplicationEntityFilter(dicomFilter);
843 dicomServer.SetApplicationEntityTitle(Configuration::GetGlobalStringParameter("DicomAet", "ORTHANC")); 906
844 dicomServer.SetApplicationEntityFilter(dicomFilter); 907 if (dicomServer.GetPortNumber() < 1024)
845 908 {
846 if (dicomServer.GetPortNumber() < 1024) 909 LOG(WARNING) << "The DICOM port is privileged ("
847 { 910 << dicomServer.GetPortNumber() << " is below 1024), "
848 LOG(WARNING) << "The DICOM port is privileged (" 911 << "make sure you run Orthanc as root/administrator";
849 << dicomServer.GetPortNumber() << " is below 1024), " 912 }
850 << "make sure you run Orthanc as root/administrator"; 913
851 } 914 dicomServer.Start();
852 915 LOG(WARNING) << "DICOM server listening with AET " << dicomServer.GetApplicationEntityTitle()
853 dicomServer.Start(); 916 << " on port: " << dicomServer.GetPortNumber();
854 LOG(WARNING) << "DICOM server listening with AET " << dicomServer.GetApplicationEntityTitle() 917
855 << " on port: " << dicomServer.GetPortNumber(); 918 bool restart = false;
856 919 ErrorCode error = ErrorCode_Success;
857 bool restart = false; 920
858 ErrorCode error = ErrorCode_Success; 921 try
859 922 {
860 try 923 restart = StartHttpServer(context, restApi, plugins);
861 { 924 }
862 restart = StartHttpServer(context, restApi, plugins); 925 catch (OrthancException& e)
863 } 926 {
864 catch (OrthancException& e) 927 error = e.GetErrorCode();
865 { 928 }
866 error = e.GetErrorCode(); 929
867 } 930 dicomServer.Stop();
868 931 LOG(WARNING) << " DICOM server has stopped";
869 dicomServer.Stop(); 932
870 LOG(WARNING) << " DICOM server has stopped"; 933 serverFactory.Done();
871 934
872 serverFactory.Done(); 935 if (error != ErrorCode_Success)
873 936 {
874 if (error != ErrorCode_Success) 937 throw OrthancException(error);
875 { 938 }
876 throw OrthancException(error); 939
877 } 940 return restart;
878 941 }
879 return restart;
880 } 942 }
881 943
882 944
883 static bool ConfigureHttpHandler(ServerContext& context, 945 static bool ConfigureHttpHandler(ServerContext& context,
884 OrthancPlugins *plugins, 946 OrthancPlugins *plugins,
972 static bool ConfigureServerContext(IDatabaseWrapper& database, 1034 static bool ConfigureServerContext(IDatabaseWrapper& database,
973 IStorageArea& storageArea, 1035 IStorageArea& storageArea,
974 OrthancPlugins *plugins, 1036 OrthancPlugins *plugins,
975 bool loadJobsFromDatabase) 1037 bool loadJobsFromDatabase)
976 { 1038 {
977 // These configuration options must be set before creating the
978 // ServerContext, otherwise the possible Lua scripts will not be
979 // able to properly issue HTTP/HTTPS queries
980 HttpClient::ConfigureSsl(Configuration::GetGlobalBoolParameter("HttpsVerifyPeers", true),
981 Configuration::InterpretStringParameterAsPath
982 (Configuration::GetGlobalStringParameter("HttpsCACertificates", "")));
983 HttpClient::SetDefaultVerbose(Configuration::GetGlobalBoolParameter("HttpVerbose", false));
984 HttpClient::SetDefaultTimeout(Configuration::GetGlobalUnsignedIntegerParameter("HttpTimeout", 0));
985 HttpClient::SetDefaultProxy(Configuration::GetGlobalStringParameter("HttpProxy", ""));
986
987 DicomUserConnection::SetDefaultTimeout(Configuration::GetGlobalUnsignedIntegerParameter("DicomScuTimeout", 10));
988
989 ServerContext context(database, storageArea, false /* not running unit tests */); 1039 ServerContext context(database, storageArea, false /* not running unit tests */);
990 context.SetCompressionEnabled(Configuration::GetGlobalBoolParameter("StorageCompression", false)); 1040
991 context.SetStoreMD5ForAttachments(Configuration::GetGlobalBoolParameter("StoreMD5ForAttachments", true)); 1041 {
992 1042 OrthancConfiguration::ReaderLock lock;
993 // New option in Orthanc 1.4.2 1043
994 context.GetIndex().SetOverwriteInstances(Configuration::GetGlobalBoolParameter("OverwriteInstances", false)); 1044 // These configuration options must be set before creating the
995 1045 // ServerContext, otherwise the possible Lua scripts will not be
996 try 1046 // able to properly issue HTTP/HTTPS queries
997 { 1047 HttpClient::ConfigureSsl(lock.GetConfiguration().GetBooleanParameter("HttpsVerifyPeers", true),
998 context.GetIndex().SetMaximumPatientCount(Configuration::GetGlobalUnsignedIntegerParameter("MaximumPatientCount", 0)); 1048 lock.GetConfiguration().InterpretStringParameterAsPath
999 } 1049 (lock.GetConfiguration().GetStringParameter("HttpsCACertificates", "")));
1000 catch (...) 1050 HttpClient::SetDefaultVerbose(lock.GetConfiguration().GetBooleanParameter("HttpVerbose", false));
1001 { 1051 HttpClient::SetDefaultTimeout(lock.GetConfiguration().GetUnsignedIntegerParameter("HttpTimeout", 0));
1002 context.GetIndex().SetMaximumPatientCount(0); 1052 HttpClient::SetDefaultProxy(lock.GetConfiguration().GetStringParameter("HttpProxy", ""));
1003 } 1053
1004 1054 DicomUserConnection::SetDefaultTimeout(lock.GetConfiguration().GetUnsignedIntegerParameter("DicomScuTimeout", 10));
1005 try 1055 context.SetCompressionEnabled(lock.GetConfiguration().GetBooleanParameter("StorageCompression", false));
1006 { 1056 context.SetStoreMD5ForAttachments(lock.GetConfiguration().GetBooleanParameter("StoreMD5ForAttachments", true));
1007 uint64_t size = Configuration::GetGlobalUnsignedIntegerParameter("MaximumStorageSize", 0); 1057
1008 context.GetIndex().SetMaximumStorageSize(size * 1024 * 1024); 1058 // New option in Orthanc 1.4.2
1009 } 1059 context.GetIndex().SetOverwriteInstances(lock.GetConfiguration().GetBooleanParameter("OverwriteInstances", false));
1010 catch (...) 1060
1011 { 1061 try
1012 context.GetIndex().SetMaximumStorageSize(0); 1062 {
1013 } 1063 context.GetIndex().SetMaximumPatientCount(lock.GetConfiguration().GetUnsignedIntegerParameter("MaximumPatientCount", 0));
1014 1064 }
1015 context.GetJobsEngine().GetRegistry().SetMaxCompletedJobs 1065 catch (...)
1016 (Configuration::GetGlobalUnsignedIntegerParameter("JobsHistorySize", 10)); 1066 {
1067 context.GetIndex().SetMaximumPatientCount(0);
1068 }
1069
1070 try
1071 {
1072 uint64_t size = lock.GetConfiguration().GetUnsignedIntegerParameter("MaximumStorageSize", 0);
1073 context.GetIndex().SetMaximumStorageSize(size * 1024 * 1024);
1074 }
1075 catch (...)
1076 {
1077 context.GetIndex().SetMaximumStorageSize(0);
1078 }
1079
1080 context.GetJobsEngine().GetRegistry().SetMaxCompletedJobs
1081 (lock.GetConfiguration().GetUnsignedIntegerParameter("JobsHistorySize", 10));
1082 }
1083
1017 1084
1018 #if ORTHANC_ENABLE_PLUGINS == 1 1085 #if ORTHANC_ENABLE_PLUGINS == 1
1019 if (plugins) 1086 if (plugins)
1020 { 1087 {
1021 plugins->SetServerContext(context); 1088 plugins->SetServerContext(context);
1103 LOG(WARNING) << "Using a custom database from plugins"; 1170 LOG(WARNING) << "Using a custom database from plugins";
1104 database = &plugins.GetDatabaseBackend(); 1171 database = &plugins.GetDatabaseBackend();
1105 } 1172 }
1106 else 1173 else
1107 { 1174 {
1108 databasePtr.reset(Configuration::CreateDatabaseWrapper()); 1175 databasePtr.reset(CreateDatabaseWrapper());
1109 database = databasePtr.get(); 1176 database = databasePtr.get();
1110 } 1177 }
1111 1178
1112 if (plugins.HasStorageArea()) 1179 if (plugins.HasStorageArea())
1113 { 1180 {
1114 LOG(WARNING) << "Using a custom storage area from plugins"; 1181 LOG(WARNING) << "Using a custom storage area from plugins";
1115 storage.reset(plugins.CreateStorageArea()); 1182 storage.reset(plugins.CreateStorageArea());
1116 } 1183 }
1117 else 1184 else
1118 { 1185 {
1119 storage.reset(Configuration::CreateStorageArea()); 1186 storage.reset(CreateStorageArea());
1120 } 1187 }
1121 1188
1122 assert(database != NULL); 1189 assert(database != NULL);
1123 assert(storage.get() != NULL); 1190 assert(storage.get() != NULL);
1124 1191
1125 return ConfigureDatabase(*database, *storage, &plugins, 1192 return ConfigureDatabase(*database, *storage, &plugins,
1126 upgradeDatabase, loadJobsFromDatabase); 1193 upgradeDatabase, loadJobsFromDatabase);
1127 1194
1128 #elif ORTHANC_ENABLE_PLUGINS == 0 1195 #elif ORTHANC_ENABLE_PLUGINS == 0
1129 // The plugins are disabled 1196 // The plugins are disabled
1130 databasePtr.reset(Configuration::CreateDatabaseWrapper()); 1197 databasePtr.reset(lock.GetConfiguration().CreateDatabaseWrapper());
1131 storage.reset(Configuration::CreateStorageArea()); 1198 storage.reset(lock.GetConfiguration().CreateStorageArea());
1132 1199
1133 return ConfigureDatabase(*databasePtr, *storage, NULL, 1200 return ConfigureDatabase(*databasePtr, *storage, NULL,
1134 upgradeDatabase, loadJobsFromDatabase); 1201 upgradeDatabase, loadJobsFromDatabase);
1135 1202
1136 #else 1203 #else