changeset 1452:b737acb13da5

refactoring of the main function
author Sebastien Jodogne <s.jodogne@gmail.com>
date Thu, 02 Jul 2015 11:35:41 +0200
parents 538fc8359a9a
children c0bdc47165ef
files OrthancServer/ServerContext.h OrthancServer/main.cpp Plugins/Engine/OrthancPlugins.cpp Plugins/Engine/OrthancPlugins.h
diffstat 4 files changed, 211 insertions(+), 181 deletions(-) [+]
line wrap: on
line diff
--- 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;
-
   };
 }
--- 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<IDatabaseWrapper> database;
-  std::auto_ptr<IStorageArea>  storage;
-  std::auto_ptr<ServerContext> 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<IDatabaseWrapper>  databasePtr;
+  std::auto_ptr<IStorageArea>  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();
       }
--- 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<const _OrthancPluginGetDicomForInstance*>(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())
     {
--- 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;