diff Framework/Toolbox/OrthancApiClient.cpp @ 270:2d64f4d39610 am-2

backup (work in progress)
author am@osimis.io
date Thu, 23 Aug 2018 14:45:04 +0200
parents
children 46c5296d867e
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Framework/Toolbox/OrthancApiClient.cpp	Thu Aug 23 14:45:04 2018 +0200
@@ -0,0 +1,204 @@
+/**
+ * Stone of Orthanc
+ * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
+ * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017-2018 Osimis S.A., Belgium
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation, either version 3 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+#include "OrthancApiClient.h"
+
+#include "MessagingToolbox.h"
+#include <Core/OrthancException.h>
+
+namespace OrthancStone {
+
+  struct OrthancApiClient::InternalGetJsonResponseReadyMessage :
+      public IMessage
+  {
+    OrthancApiClient::BaseRequest*  request_;
+    Json::Value   response_;
+
+    InternalGetJsonResponseReadyMessage(OrthancApiClient::BaseRequest*  request,
+                             const Json::Value& response)
+      : IMessage(MessageType_OrthancApi_InternalGetJsonResponseReady),
+        request_(request),
+        response_(response)
+    {
+    }
+
+  };
+
+  struct OrthancApiClient::InternalGetJsonResponseErrorMessage :
+      public IMessage
+  {
+    OrthancApiClient::BaseRequest*  request_;
+
+    InternalGetJsonResponseErrorMessage(OrthancApiClient::BaseRequest* request)
+      : IMessage(MessageType_OrthancApi_InternalGetJsonResponseError),
+        request_(request)
+    {
+    }
+  };
+
+
+  // this class handles a single request to the OrthancApiClient.
+  // Once the response is ready, it will emit a message to the responseObserver
+  // the responseObserver must handle only that message (and not all messages from the OrthancApiClient)
+  class OrthancApiClient::BaseRequest:
+      public IObserver,
+      public IObservable,
+      public Orthanc::IDynamicObject
+  {
+  public:
+    std::string               uri_;
+    OrthancApiClient&         orthanc_;
+    MessageType               messageToEmitWhenResponseReady_;
+    OrthancApiClient::Mode    mode_;
+
+  public:
+    BaseRequest(
+        OrthancApiClient& orthanc,
+                   IObserver& responseObserver,
+                   const std::string& uri,
+                   MessageType messageToEmitWhenResponseReady,
+                   OrthancApiClient::Mode mode)
+      : IObserver(orthanc.broker_),
+        IObservable(orthanc.broker_),
+        uri_(uri),
+        orthanc_(orthanc),
+        messageToEmitWhenResponseReady_(messageToEmitWhenResponseReady),
+        mode_(mode)
+    {
+      // this object will emit only a single message, the one the final responseObserver is expecting
+      DeclareEmittableMessage(messageToEmitWhenResponseReady);
+
+      // this object is observing the OrthancApi so it must handle all messages
+      DeclareHandledMessage(MessageType_OrthancApi_InternalGetJsonResponseReady);
+      DeclareIgnoredMessage(MessageType_OrthancApi_InternalGetJsonResponseError);
+
+      orthanc_.RegisterObserver(*this);
+      this->RegisterObserver(responseObserver);
+    }
+    virtual ~BaseRequest() {}
+
+    // mainly maps OrthancApi internal messages to a message that is expected by the responseObserver
+    virtual void HandleMessage(IObservable& from, const IMessage& message)
+    {
+      switch (message.GetType())
+      {
+        case MessageType_OrthancApi_InternalGetJsonResponseReady:
+      {
+        const OrthancApiClient::InternalGetJsonResponseReadyMessage& messageReceived = dynamic_cast<const OrthancApiClient::InternalGetJsonResponseReadyMessage&>(message);
+        EmitMessage(OrthancApiClient::GetJsonResponseReadyMessage(messageToEmitWhenResponseReady_, messageReceived.request_->uri_, messageReceived.response_));
+        orthanc_.ReleaseRequest(messageReceived.request_);
+      }; break;
+      default:
+        throw MessageNotDeclaredException(message.GetType());
+      }
+    }
+
+  };
+
+
+  class OrthancApiClient::WebCallback : public IWebService::ICallback
+  {
+  private:
+    OrthancApiClient&  that_;
+
+  public:
+    WebCallback(MessageBroker& broker, OrthancApiClient&  that) :
+      IWebService::ICallback(broker),
+      that_(that)
+    {
+    }
+
+    virtual void OnHttpRequestSuccess(const std::string& uri,
+                                      const void* answer,
+                                      size_t answerSize,
+                                      Orthanc::IDynamicObject* payload)
+    {
+      OrthancApiClient::BaseRequest* request = dynamic_cast<OrthancApiClient::BaseRequest*>(payload);  // the BaseRequests objects belongs to the OrthancApiClient and is deleted in ReleaseRequest when it has been "consumed"
+
+      switch (request->mode_)
+      {
+      case OrthancApiClient::Mode_GetJson:
+      {
+        Json::Value response;
+        if (MessagingToolbox::ParseJson(response, answer, answerSize))
+        {
+          OrthancApiClient::InternalGetJsonResponseReadyMessage msg(request, response);
+          that_.EmitMessage(msg);
+        }
+        else
+        {
+          OrthancApiClient::InternalGetJsonResponseErrorMessage msg(request);
+          that_.EmitMessage(msg);
+        }
+      };  break;
+
+      default:
+        that_.ReleaseRequest(request);
+        throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
+      }
+    }
+
+    virtual void OnHttpRequestError(const std::string& uri,
+                                    Orthanc::IDynamicObject* payload)
+    {
+      OrthancApiClient::BaseRequest* request = dynamic_cast<OrthancApiClient::BaseRequest*>(payload);  // the BaseRequests objects belongs to the OrthancApiClient and is deleted in ReleaseRequest when it has been "consumed"
+
+      switch (request->mode_)
+      {
+      case OrthancApiClient::Mode_GetJson:
+      {
+        OrthancApiClient::InternalGetJsonResponseErrorMessage msg(request);
+        that_.EmitMessage(msg);
+      };  break;
+
+      default:
+        that_.ReleaseRequest(request);
+        throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
+      }
+    }
+  };
+
+  OrthancApiClient::OrthancApiClient(MessageBroker &broker, IWebService &orthanc)
+    : IObservable(broker),
+      orthanc_(orthanc),
+      webCallback_(new OrthancApiClient::WebCallback(broker, *this))
+  {
+    DeclareEmittableMessage(MessageType_OrthancApi_InternalGetJsonResponseReady);
+    DeclareEmittableMessage(MessageType_OrthancApi_InternalGetJsonResponseError);
+  }
+
+  void OrthancApiClient::ScheduleGetJsonRequest(IObserver &responseObserver, const std::string &uri, MessageType messageToEmitWhenResponseReady)
+  {
+    OrthancApiClient::BaseRequest* request = new OrthancApiClient::BaseRequest(*this,
+                                                                               responseObserver,
+                                                                               uri,
+                                                                               messageToEmitWhenResponseReady,
+                                                                               OrthancApiClient::Mode_GetJson);
+    orthanc_.ScheduleGetRequest(*webCallback_, uri, IWebService::Headers(), request);
+    requestsInProgress_.insert(request);
+  }
+
+  void OrthancApiClient::ReleaseRequest(BaseRequest* request)
+  {
+    requestsInProgress_.erase(request);
+    delete request;
+  }
+
+}