# HG changeset patch # User Sebastien Jodogne # Date 1435829741 -7200 # Node ID b737acb13da50dc22fb624cd5320089c9055472f # Parent 538fc8359a9a606a56533af0f1094fbdd7406cce refactoring of the main function diff -r 538fc8359a9a -r b737acb13da5 OrthancServer/ServerContext.h --- a/OrthancServer/ServerContext.h Thu Jul 02 09:45:36 2015 +0200 +++ b/OrthancServer/ServerContext.h Thu Jul 02 11:35:41 2015 +0200 @@ -251,6 +251,5 @@ bool HasPlugins() const; const OrthancPlugins& GetPlugins() const; - }; } diff -r 538fc8359a9a -r b737acb13da5 OrthancServer/main.cpp --- a/OrthancServer/main.cpp Thu Jul 02 09:45:36 2015 +0200 +++ b/OrthancServer/main.cpp Thu Jul 02 11:35:41 2015 +0200 @@ -383,189 +383,239 @@ +// Returns "true" if restart is required +static bool WaitForExit(ServerContext& context, + OrthancRestApi& restApi) +{ + LOG(WARNING) << "Orthanc has started"; + + Toolbox::ServerBarrier(restApi.ResetRequestReceivedFlag()); + bool restart = restApi.ResetRequestReceivedFlag(); + + if (restart) + { + LOG(WARNING) << "Reset request received, restarting Orthanc"; + } + + // We're done + LOG(WARNING) << "Orthanc is stopping"; + + return restart; +} + -static bool StartOrthanc(int argc, char *argv[]) +static bool StartHttpServer(ServerContext& context, + OrthancRestApi& restApi) { -#if ENABLE_PLUGINS == 1 - OrthancPlugins plugins; - plugins.SetCommandLineArguments(argc, argv); - LoadPlugins(plugins); -#endif + if (!Configuration::GetGlobalBoolParameter("HttpServerEnabled", true)) + { + LOG(WARNING) << "The HTTP server is disabled"; + return WaitForExit(context, restApi); + } - // "storage" and "database" must be declared BEFORE "ServerContext - // context", to avoid mess in the invokation order of the destructors. - std::auto_ptr database; - std::auto_ptr storage; - std::auto_ptr context; + // HTTP server + MyIncomingHttpRequestFilter httpFilter(context); + MongooseServer httpServer; + httpServer.SetPortNumber(Configuration::GetGlobalIntegerParameter("HttpPort", 8042)); + httpServer.SetRemoteAccessAllowed(Configuration::GetGlobalBoolParameter("RemoteAccessAllowed", false)); + httpServer.SetKeepAliveEnabled(Configuration::GetGlobalBoolParameter("KeepAlive", false)); + httpServer.SetIncomingHttpRequestFilter(httpFilter); - if (plugins.HasDatabase()) + httpServer.SetAuthenticationEnabled(Configuration::GetGlobalBoolParameter("AuthenticationEnabled", false)); + Configuration::SetupRegisteredUsers(httpServer); + + if (Configuration::GetGlobalBoolParameter("SslEnabled", false)) { - context.reset(new ServerContext(plugins.GetDatabase())); + std::string certificate = Configuration::InterpretStringParameterAsPath( + Configuration::GetGlobalStringParameter("SslCertificate", "certificate.pem")); + httpServer.SetSslEnabled(true); + httpServer.SetSslCertificate(certificate.c_str()); } else { - database.reset(Configuration::CreateDatabaseWrapper()); - context.reset(new ServerContext(*database)); + httpServer.SetSslEnabled(false); } - context->SetCompressionEnabled(Configuration::GetGlobalBoolParameter("StorageCompression", false)); - context->SetStoreMD5ForAttachments(Configuration::GetGlobalBoolParameter("StoreMD5ForAttachments", true)); + httpServer.Register(context.GetHttpHandler()); - LoadLuaScripts(*context); + httpServer.Start(); + LOG(WARNING) << "HTTP server listening on port: " << httpServer.GetPortNumber(); + + bool restart = WaitForExit(context, restApi); + + httpServer.Stop(); + LOG(WARNING) << " HTTP server has stopped"; - try + return restart; +} + + +static bool StartDicomServer(ServerContext& context, + OrthancRestApi& restApi) +{ + if (!Configuration::GetGlobalBoolParameter("DicomServerEnabled", true)) { - context->GetIndex().SetMaximumPatientCount(Configuration::GetGlobalIntegerParameter("MaximumPatientCount", 0)); - } - catch (...) - { - context->GetIndex().SetMaximumPatientCount(0); + LOG(WARNING) << "The DICOM server is disabled"; + return StartHttpServer(context, restApi); } - try + MyDicomServerFactory serverFactory(context); + + // DICOM server + DicomServer dicomServer; + OrthancApplicationEntityFilter dicomFilter(context); + dicomServer.SetCalledApplicationEntityTitleCheck(Configuration::GetGlobalBoolParameter("DicomCheckCalledAet", false)); + dicomServer.SetStoreRequestHandlerFactory(serverFactory); + dicomServer.SetMoveRequestHandlerFactory(serverFactory); + dicomServer.SetFindRequestHandlerFactory(serverFactory); + dicomServer.SetPortNumber(Configuration::GetGlobalIntegerParameter("DicomPort", 4242)); + dicomServer.SetApplicationEntityTitle(Configuration::GetGlobalStringParameter("DicomAet", "ORTHANC")); + dicomServer.SetApplicationEntityFilter(dicomFilter); + + dicomServer.Start(); + LOG(WARNING) << "DICOM server listening on port: " << dicomServer.GetPortNumber(); + + bool restart = StartHttpServer(context, restApi); + + dicomServer.Stop(); + LOG(WARNING) << " DICOM server has stopped"; + + serverFactory.Done(); + + return restart; +} + + +static bool ConfigureHttpHandler(ServerContext& context, + OrthancPlugins *plugins) +{ + // By order of priority, first apply the "plugins" layer, so that + // plugins can overwrite the built-in REST API of Orthanc + if (plugins) { - uint64_t size = Configuration::GetGlobalIntegerParameter("MaximumStorageSize", 0); - context->GetIndex().SetMaximumStorageSize(size * 1024 * 1024); - } - catch (...) - { - context->GetIndex().SetMaximumStorageSize(0); + assert(context.HasPlugins()); + context.GetHttpHandler().Register(*plugins, false); } - -#if ENABLE_PLUGINS == 1 - OrthancRestApi restApi(*context); - plugins.SetServerContext(*context); - context->GetHttpHandler().Register(plugins, false); - context->SetPlugins(plugins); -#endif - + // Secondly, apply the "static resources" layer #if ORTHANC_STANDALONE == 1 EmbeddedResourceHttpHandler staticResources("/app", EmbeddedResources::ORTHANC_EXPLORER); #else FilesystemHttpHandler staticResources("/app", ORTHANC_PATH "/OrthancExplorer"); #endif - context->GetHttpHandler().Register(staticResources, false); - context->GetHttpHandler().Register(restApi, true); - - - MyDicomServerFactory serverFactory(*context); - bool isReset = false; - - { - // DICOM server - DicomServer dicomServer; - OrthancApplicationEntityFilter dicomFilter(*context); - dicomServer.SetCalledApplicationEntityTitleCheck(Configuration::GetGlobalBoolParameter("DicomCheckCalledAet", false)); - dicomServer.SetStoreRequestHandlerFactory(serverFactory); - dicomServer.SetMoveRequestHandlerFactory(serverFactory); - dicomServer.SetFindRequestHandlerFactory(serverFactory); - dicomServer.SetPortNumber(Configuration::GetGlobalIntegerParameter("DicomPort", 4242)); - dicomServer.SetApplicationEntityTitle(Configuration::GetGlobalStringParameter("DicomAet", "ORTHANC")); - dicomServer.SetApplicationEntityFilter(dicomFilter); - - // HTTP server - MyIncomingHttpRequestFilter httpFilter(*context); - MongooseServer httpServer; - httpServer.SetPortNumber(Configuration::GetGlobalIntegerParameter("HttpPort", 8042)); - httpServer.SetRemoteAccessAllowed(Configuration::GetGlobalBoolParameter("RemoteAccessAllowed", false)); - httpServer.SetKeepAliveEnabled(Configuration::GetGlobalBoolParameter("KeepAlive", false)); - httpServer.SetIncomingHttpRequestFilter(httpFilter); - - httpServer.SetAuthenticationEnabled(Configuration::GetGlobalBoolParameter("AuthenticationEnabled", false)); - Configuration::SetupRegisteredUsers(httpServer); - - if (Configuration::GetGlobalBoolParameter("SslEnabled", false)) - { - std::string certificate = Configuration::InterpretStringParameterAsPath( - Configuration::GetGlobalStringParameter("SslCertificate", "certificate.pem")); - httpServer.SetSslEnabled(true); - httpServer.SetSslCertificate(certificate.c_str()); - } - else - { - httpServer.SetSslEnabled(false); - } - - httpServer.Register(context->GetHttpHandler()); - + context.GetHttpHandler().Register(staticResources, false); -#if ENABLE_PLUGINS == 1 - // Prepare the storage area - if (plugins.HasStorageArea()) - { - LOG(WARNING) << "Using a custom storage area from plugins"; - storage.reset(plugins.GetStorageArea()); - } - else -#endif - { - storage.reset(Configuration::CreateStorageArea()); - } - - context->SetStorageArea(*storage); - - // GO !!! Start the requested servers - if (Configuration::GetGlobalBoolParameter("HttpServerEnabled", true)) - { -#if ENABLE_PLUGINS == 1 - plugins.SetOrthancRestApi(restApi); -#endif - - httpServer.Start(); - LOG(WARNING) << "HTTP server listening on port: " << httpServer.GetPortNumber(); - } - else - { - LOG(WARNING) << "The HTTP server is disabled"; - } + // Thirdly, consider the built-in REST API of Orthanc + OrthancRestApi restApi(context); + context.GetHttpHandler().Register(restApi, true); - if (Configuration::GetGlobalBoolParameter("DicomServerEnabled", true)) - { - dicomServer.Start(); - LOG(WARNING) << "DICOM server listening on port: " << dicomServer.GetPortNumber(); - } - else - { - LOG(WARNING) << "The DICOM server is disabled"; - } - - LOG(WARNING) << "Orthanc has started"; - - Toolbox::ServerBarrier(restApi.ResetRequestReceivedFlag()); - isReset = restApi.ResetRequestReceivedFlag(); - - if (isReset) - { - LOG(WARNING) << "Reset request received, restarting Orthanc"; - } - - // We're done - LOG(WARNING) << "Orthanc is stopping"; - - context->Stop(); - -#if ENABLE_PLUGINS == 1 - context->ResetPlugins(); - plugins.ResetOrthancRestApi(); - LOG(WARNING) << " Plugins have stopped"; -#endif - - dicomServer.Stop(); - LOG(WARNING) << " DICOM server has stopped"; - - httpServer.Stop(); - LOG(WARNING) << " HTTP server has stopped"; - } - - serverFactory.Done(); - - return isReset; + return StartDicomServer(context, restApi); } +static bool ConfigureServerContext(IDatabaseWrapper& database, + IStorageArea& storageArea, + OrthancPlugins *plugins) +{ + ServerContext context(database); + context.SetStorageArea(storageArea); + + context.SetCompressionEnabled(Configuration::GetGlobalBoolParameter("StorageCompression", false)); + context.SetStoreMD5ForAttachments(Configuration::GetGlobalBoolParameter("StoreMD5ForAttachments", true)); + + try + { + context.GetIndex().SetMaximumPatientCount(Configuration::GetGlobalIntegerParameter("MaximumPatientCount", 0)); + } + catch (...) + { + context.GetIndex().SetMaximumPatientCount(0); + } + + try + { + uint64_t size = Configuration::GetGlobalIntegerParameter("MaximumStorageSize", 0); + context.GetIndex().SetMaximumStorageSize(size * 1024 * 1024); + } + catch (...) + { + context.GetIndex().SetMaximumStorageSize(0); + } + + LoadLuaScripts(context); + + if (plugins) + { + plugins->SetServerContext(context); + context.SetPlugins(*plugins); + } + + bool restart = ConfigureHttpHandler(context, plugins); + context.Stop(); + + if (plugins) + { + context.ResetPlugins(); + } + + return restart; +} + + +static bool ConfigurePlugins(int argc, + char* argv[]) +{ + std::auto_ptr databasePtr; + std::auto_ptr storage; + +#if ENABLE_PLUGINS == 1 + OrthancPlugins plugins; + plugins.SetCommandLineArguments(argc, argv); + LoadPlugins(plugins); + + IDatabaseWrapper* database = NULL; + if (plugins.HasDatabase()) + { + LOG(WARNING) << "Using a custom database from plugins"; + database = &plugins.GetDatabase(); + } + else + { + databasePtr.reset(Configuration::CreateDatabaseWrapper()); + database = databasePtr.get(); + } + + if (plugins.HasStorageArea()) + { + LOG(WARNING) << "Using a custom storage area from plugins"; + storage.reset(plugins.CreateStorageArea()); + } + else + { + storage.reset(Configuration::CreateStorageArea()); + } + + assert(database != NULL); + assert(storage.get() != NULL); + + return ConfigureServerContext(*database, *storage, &plugins); + +#else + // The plugins are disabled + databasePtr.reset(Configuration::CreateDatabaseWrapper()); + storage.reset(Configuration::CreateStorageArea()); + + return ConfigureServerContext(*databasePtr, *storage, NULL); +#endif +} + + +static bool StartOrthanc(int argc, char* argv[]) +{ + return ConfigurePlugins(argc, argv); +} int main(int argc, char* argv[]) @@ -646,8 +696,8 @@ { OrthancInitialize(configurationFile); - bool reset = StartOrthanc(argc, argv); - if (reset) + bool restart = StartOrthanc(argc, argv); + if (restart) { OrthancFinalize(); } diff -r 538fc8359a9a -r b737acb13da5 Plugins/Engine/OrthancPlugins.cpp --- a/Plugins/Engine/OrthancPlugins.cpp Thu Jul 02 09:45:36 2015 +0200 +++ b/Plugins/Engine/OrthancPlugins.cpp Thu Jul 02 11:35:41 2015 +0200 @@ -33,12 +33,11 @@ #include "OrthancPlugins.h" #include "../../Core/ChunkedBuffer.h" -#include "../../Core/HttpServer/StringHttpOutput.h" +#include "../../Core/HttpServer/HttpToolbox.h" #include "../../Core/ImageFormats/PngWriter.h" #include "../../Core/OrthancException.h" #include "../../Core/Toolbox.h" #include "../../OrthancServer/OrthancInitialization.h" -#include "../../OrthancServer/OrthancRestApi/OrthancRestApi.h" #include "../../OrthancServer/ServerContext.h" #include "../../OrthancServer/ServerToolbox.h" @@ -123,7 +122,6 @@ PluginsManager manager_; ServerContext* context_; RestCallbacks restCallbacks_; - OrthancRestApi* restApi_; OnStoredCallbacks onStoredCallbacks_; OnChangeCallbacks onChangeCallbacks_; bool hasStorageArea_; @@ -136,7 +134,6 @@ PImpl() : context_(NULL), - restApi_(NULL), hasStorageArea_(false), argc_(1), argv_(NULL) @@ -600,13 +597,14 @@ void OrthancPlugins::GetDicomForInstance(const void* parameters) { - CheckContextAvailable(); - const _OrthancPluginGetDicomForInstance& p = *reinterpret_cast(parameters); std::string dicom; + + CheckContextAvailable(); pimpl_->context_->ReadFile(dicom, p.instanceId, FileContentType_Dicom); + CopyToMemoryBuffer(*p.target, dicom); } @@ -1119,18 +1117,6 @@ } - void OrthancPlugins::SetOrthancRestApi(OrthancRestApi& restApi) - { - pimpl_->restApi_ = &restApi; - } - - - void OrthancPlugins::ResetOrthancRestApi() - { - pimpl_->restApi_ = NULL; - } - - bool OrthancPlugins::HasStorageArea() const { return pimpl_->hasStorageArea_; @@ -1231,7 +1217,7 @@ } - IStorageArea* OrthancPlugins::GetStorageArea() + IStorageArea* OrthancPlugins::CreateStorageArea() { if (!HasStorageArea()) { diff -r 538fc8359a9a -r b737acb13da5 Plugins/Engine/OrthancPlugins.h --- a/Plugins/Engine/OrthancPlugins.h Thu Jul 02 09:45:36 2015 +0200 +++ b/Plugins/Engine/OrthancPlugins.h Thu Jul 02 11:35:41 2015 +0200 @@ -43,7 +43,6 @@ namespace Orthanc { - class OrthancRestApi; class ServerContext; class OrthancPlugins : @@ -124,13 +123,9 @@ return true; // TODO Enable filtering of instances from plugins } - void SetOrthancRestApi(OrthancRestApi& restApi); - - void ResetOrthancRestApi(); - bool HasStorageArea() const; - IStorageArea* GetStorageArea(); // To be freed after use + IStorageArea* CreateStorageArea(); // To be freed after use bool HasDatabase() const;