# HG changeset patch # User Sebastien Jodogne # Date 1403090949 -7200 # Node ID bb0a515610162d8260cb07f09dedd27f31cffb83 # Parent 7000fc86fe624eacef58dedfb812923632fd1b5b refactoring diff -r 7000fc86fe62 -r bb0a51561016 Core/HttpServer/MongooseServer.cpp --- a/Core/HttpServer/MongooseServer.cpp Wed Jun 18 09:18:28 2014 +0200 +++ b/Core/HttpServer/MongooseServer.cpp Wed Jun 18 13:29:09 2014 +0200 @@ -843,23 +843,17 @@ } - void MongooseServer::RegisterHandler(HttpHandler* handler) + void MongooseServer::RegisterHandler(HttpHandler& handler) { Stop(); - handlers_.push_back(handler); + handlers_.push_back(&handler); } void MongooseServer::ClearHandlers() { Stop(); - - for (Handlers::iterator it = - handlers_.begin(); it != handlers_.end(); ++it) - { - delete *it; - } } diff -r 7000fc86fe62 -r bb0a51561016 Core/HttpServer/MongooseServer.h --- a/Core/HttpServer/MongooseServer.h Wed Jun 18 09:18:28 2014 +0200 +++ b/Core/HttpServer/MongooseServer.h Wed Jun 18 13:29:09 2014 +0200 @@ -100,7 +100,7 @@ void RegisterUser(const char* username, const char* password); - void RegisterHandler(HttpHandler* handler); // This takes the ownership + void RegisterHandler(HttpHandler& handler); bool IsAuthenticationEnabled() const { diff -r 7000fc86fe62 -r bb0a51561016 OrthancServer/main.cpp --- a/OrthancServer/main.cpp Wed Jun 18 09:18:28 2014 +0200 +++ b/OrthancServer/main.cpp Wed Jun 18 13:29:09 2014 +0200 @@ -374,7 +374,10 @@ LoadLuaScripts(context); + PluginsHttpHandler httpPlugins; + PluginsManager pluginsManager; + pluginsManager.RegisterServiceProvider(httpPlugins); LoadPlugins(pluginsManager); try @@ -432,15 +435,17 @@ httpServer.SetSslEnabled(false); } - httpServer.RegisterHandler(new PluginsHttpHandler(pluginsManager)); + OrthancRestApi restApi(context); #if ORTHANC_STANDALONE == 1 - httpServer.RegisterHandler(new EmbeddedResourceHttpHandler("/app", EmbeddedResources::ORTHANC_EXPLORER)); + EmbeddedResourceHttpHandler staticResources("/app", EmbeddedResources::ORTHANC_EXPLORER); #else - httpServer.RegisterHandler(new FilesystemHttpHandler("/app", ORTHANC_PATH "/OrthancExplorer")); + FilesystemHttpHandler staticResources("/app", ORTHANC_PATH "/OrthancExplorer"); #endif - httpServer.RegisterHandler(new OrthancRestApi(context)); + httpServer.RegisterHandler(httpPlugins); + httpServer.RegisterHandler(staticResources); + httpServer.RegisterHandler(restApi); // GO !!! Start the requested servers if (Configuration::GetGlobalBoolParameter("HttpServerEnabled", true)) diff -r 7000fc86fe62 -r bb0a51561016 Plugins/Engine/IPluginServiceProvider.h --- a/Plugins/Engine/IPluginServiceProvider.h Wed Jun 18 09:18:28 2014 +0200 +++ b/Plugins/Engine/IPluginServiceProvider.h Wed Jun 18 13:29:09 2014 +0200 @@ -41,9 +41,11 @@ class IPluginServiceProvider : boost::noncopyable { public: - virtual ~IPluginServiceProvider(); + virtual ~IPluginServiceProvider() + { + } - virtual bool Handle(OrthancPluginService service, - const void* parameters) = 0; + virtual bool InvokeService(OrthancPluginService service, + const void* parameters) = 0; }; } diff -r 7000fc86fe62 -r bb0a51561016 Plugins/Engine/PluginsHttpHandler.cpp --- a/Plugins/Engine/PluginsHttpHandler.cpp Wed Jun 18 09:18:28 2014 +0200 +++ b/Plugins/Engine/PluginsHttpHandler.cpp Wed Jun 18 13:29:09 2014 +0200 @@ -34,6 +34,7 @@ #include "../../Core/OrthancException.h" #include "../../Core/Toolbox.h" +#include "../../Core/HttpServer/HttpOutput.h" #include #include @@ -54,15 +55,9 @@ }; - PluginsHttpHandler::PluginsHttpHandler(const PluginsManager& manager) + PluginsHttpHandler::PluginsHttpHandler() { pimpl_.reset(new PImpl); - - for (PluginsManager::RestCallbacks::const_iterator - it = manager.GetRestCallbacks().begin(); it != manager.GetRestCallbacks().end(); ++it) - { - pimpl_->callbacks_.push_back(std::make_pair(new boost::regex(it->first), it->second)); - } } @@ -108,12 +103,14 @@ std::vector getKeys(getArguments.size()); std::vector getValues(getArguments.size()); - OrthancPluginHttpMethod methodPlugin; + OrthancPluginHttpRequest request; + memset(&request, 0, sizeof(OrthancPluginHttpRequest)); + switch (method) { case HttpMethod_Get: { - methodPlugin = OrthancPluginHttpMethod_Get; + request.method = OrthancPluginHttpMethod_Get; size_t i = 0; for (Arguments::const_iterator it = getArguments.begin(); @@ -127,29 +124,36 @@ } case HttpMethod_Post: - methodPlugin = OrthancPluginHttpMethod_Post; + request.method = OrthancPluginHttpMethod_Post; break; case HttpMethod_Delete: - methodPlugin = OrthancPluginHttpMethod_Delete; + request.method = OrthancPluginHttpMethod_Delete; break; case HttpMethod_Put: - methodPlugin = OrthancPluginHttpMethod_Put; + request.method = OrthancPluginHttpMethod_Put; break; default: throw OrthancException(ErrorCode_InternalError); } + + request.getCount = getArguments.size(); + request.body = (postData.size() ? &postData[0] : NULL); + request.bodySize = postData.size(); + + if (getArguments.size() > 0) + { + request.getKeys = &getKeys[0]; + request.getValues = &getValues[0]; + } + assert(pimpl_->currentCallback_ != NULL); - assert(getKeys.size() == getValues.size()); int32_t error = (*pimpl_->currentCallback_) (reinterpret_cast(&output), - methodPlugin, flatUri.c_str(), - getKeys.size() ? &getKeys[0] : NULL, - getKeys.size() ? &getValues[0] : NULL, - getKeys.size(), - postData.size() ? &postData[0] : NULL, postData.size()); + flatUri.c_str(), + &request); if (error < 0) { @@ -166,4 +170,68 @@ return true; } } + + + bool PluginsHttpHandler::InvokeService(OrthancPluginService service, + const void* parameters) + { + + + /*void PluginsManager::RegisterRestCallback(const OrthancPluginContext* context, + const char* pathRegularExpression, + OrthancPluginRestCallback callback) + { + LOG(INFO) << "Plugin has registered a REST callback on: " << pathRegularExpression; + PluginsManager* manager = reinterpret_cast(context->pluginsManager); + manager->restCallbacks_.push_back(std::make_pair(pathRegularExpression, callback)); + }*/ + + + /*static void AnswerBuffer(OrthancPluginRestOutput* output, + const char* answer, + uint32_t answerSize, + const char* mimeType) + { + HttpOutput* translatedOutput = reinterpret_cast(output); + translatedOutput->AnswerBufferWithContentType(answer, answerSize, mimeType); + }*/ + + + + /*for (PluginsManager::RestCallbacks::const_iterator + it = manager.GetRestCallbacks().begin(); it != manager.GetRestCallbacks().end(); ++it) + { + pimpl_->callbacks_.push_back(std::make_pair(new boost::regex(it->first), it->second)); + }*/ + + + switch (service) + { + case OrthancPluginService_RegisterRestCallback: + { + const OrthancPluginRestCallbackParams& p = + *reinterpret_cast(parameters); + + LOG(INFO) << "Plugin has registered a REST callback on: " << p.pathRegularExpression; + pimpl_->callbacks_.push_back(std::make_pair(new boost::regex(p.pathRegularExpression), p.callback)); + + return true; + } + + case OrthancPluginService_AnswerBuffer: + { + const OrthancPluginAnswerBufferParams& p = + *reinterpret_cast(parameters); + + HttpOutput* translatedOutput = reinterpret_cast(p.output); + translatedOutput->AnswerBufferWithContentType(p.answer, p.answerSize, p.mimeType); + + return true; + } + + default: + return false; + } + } + } diff -r 7000fc86fe62 -r bb0a51561016 Plugins/Engine/PluginsHttpHandler.h --- a/Plugins/Engine/PluginsHttpHandler.h Wed Jun 18 09:18:28 2014 +0200 +++ b/Plugins/Engine/PluginsHttpHandler.h Wed Jun 18 13:29:09 2014 +0200 @@ -40,7 +40,7 @@ namespace Orthanc { - class PluginsHttpHandler : public HttpHandler + class PluginsHttpHandler : public HttpHandler, public IPluginServiceProvider { private: struct PImpl; @@ -48,7 +48,7 @@ boost::shared_ptr pimpl_; public: - PluginsHttpHandler(const PluginsManager& manager); + PluginsHttpHandler(); virtual ~PluginsHttpHandler(); @@ -60,5 +60,8 @@ const Arguments& headers, const Arguments& getArguments, const std::string& postData); + + virtual bool InvokeService(OrthancPluginService service, + const void* parameters); }; } diff -r 7000fc86fe62 -r bb0a51561016 Plugins/Engine/PluginsManager.cpp --- a/Plugins/Engine/PluginsManager.cpp Wed Jun 18 09:18:28 2014 +0200 +++ b/Plugins/Engine/PluginsManager.cpp Wed Jun 18 13:29:09 2014 +0200 @@ -134,20 +134,20 @@ int32_t PluginsManager::InvokeService(OrthancPluginContext* context, OrthancPluginService service, - const void* parameters) + const void* params) { switch (service) { case OrthancPluginService_LogError: - LOG(ERROR) << reinterpret_cast(parameters); + LOG(ERROR) << reinterpret_cast(params); return 0; case OrthancPluginService_LogWarning: - LOG(WARNING) << reinterpret_cast(parameters); + LOG(WARNING) << reinterpret_cast(params); return 0; case OrthancPluginService_LogInfo: - LOG(INFO) << reinterpret_cast(parameters); + LOG(INFO) << reinterpret_cast(params); return 0; default: @@ -156,10 +156,21 @@ PluginsManager* that = reinterpret_cast(context->pluginsManager); - if (that->HasServiceProvider() && - that->serviceProvider_->Handle(service, parameters)) + for (std::list::iterator + it = that->serviceProviders_.begin(); + it != that->serviceProviders_.end(); it++) { - return 0; + try + { + if ((*it)->InvokeService(service, params)) + { + return 0; + } + } + catch (OrthancException&) + { + // This service provider has failed, go to the next + } } LOG(ERROR) << "Plugin invoking unknown service " << service; @@ -167,36 +178,13 @@ } - void PluginsManager::RegisterRestCallback(const OrthancPluginContext* context, - const char* pathRegularExpression, - OrthancPluginRestCallback callback) - { - LOG(INFO) << "Plugin has registered a REST callback on: " << pathRegularExpression; - PluginsManager* manager = reinterpret_cast(context->pluginsManager); - manager->restCallbacks_.push_back(std::make_pair(pathRegularExpression, callback)); - } - - - static void AnswerBuffer(OrthancPluginRestOutput* output, - const char* answer, - uint32_t answerSize, - const char* mimeType) - { - HttpOutput* translatedOutput = reinterpret_cast(output); - translatedOutput->AnswerBufferWithContentType(answer, answerSize, mimeType); - } - - - PluginsManager::PluginsManager() : - serviceProvider_(NULL) + PluginsManager::PluginsManager() { memset(&context_, 0, sizeof(context_)); context_.pluginsManager = this; context_.orthancVersion = ORTHANC_VERSION; context_.FreeBuffer = ::free; context_.InvokeService = InvokeService; - context_.RegisterRestCallback = RegisterRestCallback; - context_.AnswerBuffer = AnswerBuffer; } PluginsManager::~PluginsManager() @@ -298,17 +286,4 @@ } } } - - - IPluginServiceProvider& PluginsManager::GetServiceProvider() const - { - if (!HasServiceProvider()) - { - throw OrthancException(ErrorCode_BadRequest); - } - else - { - return *serviceProvider_; - } - } } diff -r 7000fc86fe62 -r bb0a51561016 Plugins/Engine/PluginsManager.h --- a/Plugins/Engine/PluginsManager.h Wed Jun 18 09:18:28 2014 +0200 +++ b/Plugins/Engine/PluginsManager.h Wed Jun 18 13:29:09 2014 +0200 @@ -42,25 +42,17 @@ { class PluginsManager : boost::noncopyable { - public: - typedef std::list< std::pair > RestCallbacks; - private: typedef std::map Plugins; OrthancPluginContext context_; Plugins plugins_; - RestCallbacks restCallbacks_; - IPluginServiceProvider *serviceProvider_; + std::list serviceProviders_; static int32_t InvokeService(OrthancPluginContext* context, OrthancPluginService service, const void* parameters); - static void RegisterRestCallback(const OrthancPluginContext* context, - const char* path, - OrthancPluginRestCallback callback); - public: PluginsManager(); @@ -71,21 +63,9 @@ void ScanFolderForPlugins(const std::string& path, bool isRecursive); - void SetServiceProvider(IPluginServiceProvider& provider) - { - serviceProvider_ = &provider; - } - - bool HasServiceProvider() const + void RegisterServiceProvider(IPluginServiceProvider& provider) { - return serviceProvider_ != NULL; - } - - IPluginServiceProvider& GetServiceProvider() const; - - const RestCallbacks& GetRestCallbacks() const - { - return restCallbacks_; + serviceProviders_.push_back(&provider); } }; } diff -r 7000fc86fe62 -r bb0a51561016 Plugins/OrthancCPlugin/OrthancCPlugin.h --- a/Plugins/OrthancCPlugin/OrthancCPlugin.h Wed Jun 18 09:18:28 2014 +0200 +++ b/Plugins/OrthancCPlugin/OrthancCPlugin.h Wed Jun 18 13:29:09 2014 +0200 @@ -110,18 +110,35 @@ typedef enum { + /* Generic services */ OrthancPluginService_LogInfo = 1, OrthancPluginService_LogWarning = 2, - OrthancPluginService_LogError = 3 + OrthancPluginService_LogError = 3, + + /* Registration of callbacks */ + OrthancPluginService_RegisterRestCallback = 1000, + + /* Sending answers to REST calls */ + OrthancPluginService_AnswerBuffer = 2000 } OrthancPluginService; + typedef struct + { + OrthancPluginHttpMethod method; + + /* For GET requests */ + const char* const* getKeys; + const char* const* getValues; + uint32_t getCount; + + /* For POST and PUT requests */ + const char* body; + uint32_t bodySize; + } OrthancPluginHttpRequest; + typedef int32_t (*OrthancPluginRestCallback) (OrthancPluginRestOutput* output, - OrthancPluginHttpMethod method, const char* url, - const char* const* getKeys, - const char* const* getValues, - uint32_t getSize, - const char* body, uint32_t bodySize); + const OrthancPluginHttpRequest* request); typedef struct OrthancPluginContext_t { @@ -131,18 +148,24 @@ void (*FreeBuffer) (void* buffer); int32_t (*InvokeService) (struct OrthancPluginContext_t* context, OrthancPluginService service, - const void* parameters); + const void* params); + } OrthancPluginContext; + - /* REST API */ - void (*RegisterRestCallback) (const struct OrthancPluginContext_t* context, - const char* pathRegularExpression, - OrthancPluginRestCallback callback); + typedef struct + { + const char* pathRegularExpression; + OrthancPluginRestCallback callback; + } OrthancPluginRestCallbackParams; + - void (*AnswerBuffer) (OrthancPluginRestOutput* output, - const char* answer, - uint32_t answerSize, - const char* mimeType); - } OrthancPluginContext; + typedef struct + { + OrthancPluginRestOutput* output; + const char* answer; + uint32_t answerSize; + const char* mimeType; + } OrthancPluginAnswerBufferParams; ORTHANC_PLUGIN_INLINE void OrthancPluginLogError(OrthancPluginContext* context, @@ -166,6 +189,32 @@ } + ORTHANC_PLUGIN_INLINE void OrthancPluginRegisterRestCallback(OrthancPluginContext* context, + const char* pathRegularExpression, + OrthancPluginRestCallback callback) + { + OrthancPluginRestCallbackParams params; + params.pathRegularExpression = pathRegularExpression; + params.callback = callback; + context->InvokeService(context, OrthancPluginService_RegisterRestCallback, ¶ms); + } + + + ORTHANC_PLUGIN_INLINE void OrthancPluginAnswerBuffer(OrthancPluginContext* context, + OrthancPluginRestOutput* output, + const char* answer, + uint32_t answerSize, + const char* mimeType) + { + OrthancPluginAnswerBufferParams params; + params.output = output; + params.answer = answer; + params.answerSize = answerSize; + params.mimeType = mimeType; + context->InvokeService(context, OrthancPluginService_AnswerBuffer, ¶ms); + } + + /** Each plugin must define 4 functions, whose signature are: diff -r 7000fc86fe62 -r bb0a51561016 Resources/Samples/Plugins/Basic/Plugin.c --- a/Resources/Samples/Plugins/Basic/Plugin.c Wed Jun 18 09:18:28 2014 +0200 +++ b/Resources/Samples/Plugins/Basic/Plugin.c Wed Jun 18 13:29:09 2014 +0200 @@ -34,25 +34,20 @@ ORTHANC_PLUGINS_API int32_t Callback(OrthancPluginRestOutput* output, - OrthancPluginHttpMethod method, const char* url, - const char* const* getKeys, - const char* const* getValues, - uint32_t getSize, - const char* body, - uint32_t bodySize) + const OrthancPluginHttpRequest* request) { char buffer[1024]; uint32_t i; - sprintf(buffer, "Callback on URL [%s] with body [%s]", url, body); + sprintf(buffer, "Callback on URL [%s] with body [%s]", url, request->body); OrthancPluginLogInfo(context, buffer); - context->AnswerBuffer(output, buffer, strlen(buffer), "text/plain"); + OrthancPluginAnswerBuffer(context, output, buffer, strlen(buffer), "text/plain"); - for (i = 0; i < getSize; i++) + for (i = 0; i < request->getCount; i++) { - sprintf(buffer, " [%s] = [%s]", getKeys[i], getValues[i]); + sprintf(buffer, " [%s] = [%s]", request->getKeys[i], request->getValues[i]); OrthancPluginLogInfo(context, buffer); } @@ -70,7 +65,7 @@ sprintf(info, "The version of Orthanc is '%s'", context->orthancVersion); OrthancPluginLogInfo(context, info); - context->RegisterRestCallback(c, "/plu.*/hello", Callback); + OrthancPluginRegisterRestCallback(context, "/plu.*/hello", Callback); return 0; }