# HG changeset patch # User Sebastien Jodogne # Date 1403271734 -7200 # Node ID 3e43de893d88e70d468448c2c2757bb9b0551b6b # Parent dcb2469f00f4e31bd43c3e55ba71a5fa0c9d7989 POST, DELETE, PUT from Orthanc plugins diff -r dcb2469f00f4 -r 3e43de893d88 Plugins/Engine/PluginsHttpHandler.cpp --- a/Plugins/Engine/PluginsHttpHandler.cpp Fri Jun 20 14:55:24 2014 +0200 +++ b/Plugins/Engine/PluginsHttpHandler.cpp Fri Jun 20 15:42:14 2014 +0200 @@ -358,7 +358,7 @@ StringHttpOutput stream; HttpOutput http(stream); - LOG(INFO) << "Plugin making REST call on URI " << p.uri; + LOG(INFO) << "Plugin making REST GET call on URI " << p.uri; if (pimpl_->restApi_ != NULL && pimpl_->restApi_->Handle(http, HttpMethod_Get, uri, headers, getArguments, body)) @@ -374,40 +374,100 @@ } + void PluginsHttpHandler::RestApiPostPut(bool isPost, const void* parameters) + { + const _OrthancPluginRestApiPostPut& p = + *reinterpret_cast(parameters); + + HttpHandler::Arguments headers; // No HTTP header + HttpHandler::Arguments getArguments; // No GET argument for POST/PUT + + UriComponents uri; + Toolbox::SplitUriComponents(uri, p.uri); + + // TODO Avoid unecessary memcpy + std::string body(p.body, p.bodySize); + + StringHttpOutput stream; + HttpOutput http(stream); + + HttpMethod method = (isPost ? HttpMethod_Post : HttpMethod_Put); + LOG(INFO) << "Plugin making REST " << EnumerationToString(method) << " call on URI " << p.uri; + + if (pimpl_->restApi_ != NULL && + pimpl_->restApi_->Handle(http, method, uri, headers, getArguments, body)) + { + std::string result; + stream.GetOutput(result); + CopyToMemoryBuffer(*p.target, result); + } + else + { + throw OrthancException(ErrorCode_BadRequest); + } + } + + + void PluginsHttpHandler::RestApiDelete(const void* parameters) + { + // The "parameters" point to the URI + UriComponents uri; + Toolbox::SplitUriComponents(uri, reinterpret_cast(parameters)); + + HttpHandler::Arguments headers; // No HTTP header + HttpHandler::Arguments getArguments; // No GET argument for POST/PUT + std::string body; // No body for DELETE + + StringHttpOutput stream; + HttpOutput http(stream); + + LOG(INFO) << "Plugin making REST DELETE call on URI " + << reinterpret_cast(parameters); + + if (pimpl_->restApi_ == NULL || + !pimpl_->restApi_->Handle(http, HttpMethod_Delete, uri, headers, getArguments, body)) + { + throw OrthancException(ErrorCode_BadRequest); + } + } + + bool PluginsHttpHandler::InvokeService(_OrthancPluginService service, const void* parameters) { switch (service) { case _OrthancPluginService_RegisterRestCallback: - { RegisterRestCallback(parameters); return true; - } case _OrthancPluginService_AnswerBuffer: - { AnswerBuffer(parameters); return true; - } case _OrthancPluginService_CompressAndAnswerPngImage: - { CompressAndAnswerPngImage(parameters); return true; - } case _OrthancPluginService_GetDicomForInstance: - { GetDicomForInstance(parameters); return true; - } case _OrthancPluginService_RestApiGet: - { RestApiGet(parameters); return true; - } + + case _OrthancPluginService_RestApiPost: + RestApiPostPut(true, parameters); + return true; + + case _OrthancPluginService_RestApiDelete: + RestApiDelete(parameters); + return true; + + case _OrthancPluginService_RestApiPut: + RestApiPostPut(false, parameters); + return true; default: return false; diff -r dcb2469f00f4 -r 3e43de893d88 Plugins/Engine/PluginsHttpHandler.h --- a/Plugins/Engine/PluginsHttpHandler.h Fri Jun 20 14:55:24 2014 +0200 +++ b/Plugins/Engine/PluginsHttpHandler.h Fri Jun 20 15:42:14 2014 +0200 @@ -60,6 +60,10 @@ void RestApiGet(const void* parameters); + void RestApiPostPut(bool isPost, const void* parameters); + + void RestApiDelete(const void* parameters); + public: PluginsHttpHandler(ServerContext& context); diff -r dcb2469f00f4 -r 3e43de893d88 Plugins/OrthancCPlugin/OrthancCPlugin.h --- a/Plugins/OrthancCPlugin/OrthancCPlugin.h Fri Jun 20 14:55:24 2014 +0200 +++ b/Plugins/OrthancCPlugin/OrthancCPlugin.h Fri Jun 20 15:42:14 2014 +0200 @@ -404,13 +404,13 @@ } + typedef struct { const char* pathRegularExpression; OrthancPluginRestCallback callback; } _OrthancPluginRestCallback; - /** * @brief Register a REST callback. * @@ -435,6 +435,7 @@ } + typedef struct { OrthancPluginRestOutput* output; @@ -443,7 +444,6 @@ const char* mimeType; } _OrthancPluginAnswerBuffer; - /** * @brief Answer to a REST request. * @@ -518,13 +518,13 @@ } + typedef struct { OrthancPluginMemoryBuffer* target; const char* instanceId; } _OrthancPluginGetDicomForInstance; - /** * @brief Retrieve a DICOM instance using its Orthanc identifier. * @@ -555,6 +555,17 @@ const char* uri; } _OrthancPluginRestApiGet; + /** + * @brief Make a GET call to the built-in Orthanc REST API. + * + * Make a GET call to the built-in Orthanc REST API. The result to + * the query is stored into a newly allocated memory buffer. + * + * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). + * @param target The target memory buffer. + * @param uri The URI in the built-in Orthanc API. + * @return 0 if success, other value if error. + **/ ORTHANC_PLUGIN_INLINE int OrthancPluginRestApiGet( OrthancPluginContext* context, OrthancPluginMemoryBuffer* target, @@ -567,6 +578,92 @@ } + + typedef struct + { + OrthancPluginMemoryBuffer* target; + const char* uri; + const char* body; + uint32_t bodySize; + } _OrthancPluginRestApiPostPut; + + /** + * @brief Make a POST call to the built-in Orthanc REST API. + * + * Make a POST call to the built-in Orthanc REST API. The result to + * the query is stored into a newly allocated memory buffer. + * + * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). + * @param target The target memory buffer. + * @param uri The URI in the built-in Orthanc API. + * @param body The body of the POST request. + * @param bodySize The size of the body. + * @return 0 if success, other value if error. + **/ + ORTHANC_PLUGIN_INLINE int OrthancPluginRestApiPost( + OrthancPluginContext* context, + OrthancPluginMemoryBuffer* target, + const char* uri, + const char* body, + uint32_t bodySize) + { + _OrthancPluginRestApiPostPut params; + params.target = target; + params.uri = uri; + params.body = body; + params.bodySize = bodySize; + return context->InvokeService(context, _OrthancPluginService_RestApiPost, ¶ms); + } + + + + /** + * @brief Make a DELETE call to the built-in Orthanc REST API. + * + * Make a DELETE call to the built-in Orthanc REST API. + * + * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). + * @param uri The URI to delete in the built-in Orthanc API. + * @return 0 if success, other value if error. + **/ + ORTHANC_PLUGIN_INLINE int OrthancPluginRestApiDelete( + OrthancPluginContext* context, + const char* uri) + { + return context->InvokeService(context, _OrthancPluginService_RestApiDelete, uri); + } + + + + /** + * @brief Make a PUT call to the built-in Orthanc REST API. + * + * Make a PUT call to the built-in Orthanc REST API. The result to + * the query is stored into a newly allocated memory buffer. + * + * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). + * @param target The target memory buffer. + * @param uri The URI in the built-in Orthanc API. + * @param body The body of the PUT request. + * @param bodySize The size of the body. + * @return 0 if success, other value if error. + **/ + ORTHANC_PLUGIN_INLINE int OrthancPluginRestApiPut( + OrthancPluginContext* context, + OrthancPluginMemoryBuffer* target, + const char* uri, + const char* body, + uint32_t bodySize) + { + _OrthancPluginRestApiPostPut params; + params.target = target; + params.uri = uri; + params.body = body; + params.bodySize = bodySize; + return context->InvokeService(context, _OrthancPluginService_RestApiPut, ¶ms); + } + + #ifdef __cplusplus } #endif diff -r dcb2469f00f4 -r 3e43de893d88 Plugins/Samples/Basic/Plugin.c --- a/Plugins/Samples/Basic/Plugin.c Fri Jun 20 14:55:24 2014 +0200 +++ b/Plugins/Samples/Basic/Plugin.c Fri Jun 20 15:42:14 2014 +0200 @@ -129,8 +129,10 @@ ORTHANC_PLUGINS_API int32_t OrthancPluginInitialize(OrthancPluginContext* c) { + const char* pathLocator = "\"Path\" : \""; OrthancPluginMemoryBuffer tmp; char info[1024]; + char *id, *eos; context = c; OrthancPluginLogWarning(context, "Sample plugin is initializing"); @@ -144,10 +146,31 @@ OrthancPluginRegisterRestCallback(context, "/instances/([^/]+)/preview", Callback4); - - printf(">> %d\n", OrthancPluginRestApiGet(context, &tmp, "/instances")); - printf(">> [%s]\n", (const char*) tmp.data); + /* Make REST requests to the built-in Orthanc API */ + OrthancPluginRestApiGet(context, &tmp, "/changes"); + OrthancPluginFreeMemoryBuffer(context, &tmp); + OrthancPluginRestApiGet(context, &tmp, "/changes?limit=1"); OrthancPluginFreeMemoryBuffer(context, &tmp); + + /* Make POST request to create a new DICOM instance */ + sprintf(info, "{\"PatientName\":\"Test\"}"); + OrthancPluginRestApiPost(context, &tmp, "/tools/create-dicom", info, strlen(info)); + + /** + * Recover he ID of the created instance is constructed by a + * quick-and-dirty parsing of a JSON string. + **/ + id = strstr((char*) tmp.data, pathLocator) + strlen(pathLocator); + eos = strchr(id, '\"'); + eos[0] = '\0'; + + /* Delete the newly created DICOM instance. */ + OrthancPluginRestApiDelete(context, id); + OrthancPluginFreeMemoryBuffer(context, &tmp); + + /* Play with PUT by defining a new target modality. */ + sprintf(info, "[ \"STORESCP\", \"localhost\", 2000 ]"); + OrthancPluginRestApiPut(context, &tmp, "/modalities/demo", info, strlen(info)); return 0; }