Medical Imaging Interaction Toolkit  2018.4.99-389bf124
Medical Imaging Interaction Toolkit
mitkRESTManager.cpp
Go to the documentation of this file.
1 /*============================================================================
2 
3 The Medical Imaging Interaction Toolkit (MITK)
4 
5 Copyright (c) German Cancer Research Center (DKFZ)
6 All rights reserved.
7 
8 Use of this source code is governed by a 3-clause BSD license that can be
9 found in the LICENSE file.
10 
11 ============================================================================*/
12 
13 #include <mitkIRESTObserver.h>
14 #include <mitkRESTClient.h>
15 #include <mitkRESTManager.h>
16 #include <mitkRESTServer.h>
17 
18 #include <mitkExceptionMacro.h>
19 #include <mitkLogMacros.h>
20 
22 
24 
25 pplx::task<web::json::value> mitk::RESTManager::SendRequest(
26  const web::uri &uri, const RequestType &type, const std::map<utility::string_t, utility::string_t> headers)
27 {
28  pplx::task<web::json::value> answer;
29  auto client = new RESTClient;
30 
31  switch (type)
32  {
33  case RequestType::Get:
34  answer = client->Get(uri, headers);
35  break;
36 
37  default:
38  mitkThrow() << "Request Type not supported";
39  }
40 
41  return answer;
42 }
43 
44 pplx::task<web::json::value> mitk::RESTManager::SendBinaryRequest(
45  const web::uri &uri,
46  const RequestType &type,
47  const std::vector<unsigned char> *content,
48  const std::map<utility::string_t, utility::string_t> headers)
49 {
50  pplx::task<web::json::value> answer;
51  auto client = new RESTClient;
52 
53  switch (type)
54  {
55  case RequestType::Post:
56  if (nullptr == content)
57  MITK_WARN << "Content for post is empty, this will create an empty resource";
58 
59  answer = client->Post(uri, content, headers);
60  break;
61 
62  default:
63  mitkThrow() << "Request Type not supported for binary data";
64  }
65 
66  return answer;
67 }
68 
69 pplx::task<web::json::value> mitk::RESTManager::SendJSONRequest(
70  const web::uri &uri,
71  const RequestType &type,
72  const web::json::value *content,
73  const std::map<utility::string_t, utility::string_t> headers,
74  const utility::string_t &filePath)
75 {
76  pplx::task<web::json::value> answer;
77  auto client = new RESTClient;
78 
79  switch (type)
80  {
81  case RequestType::Get:
82  answer = !filePath.empty() ? client->Get(uri, filePath, headers) : client->Get(uri, headers);
83  break;
84 
85  case RequestType::Post:
86  if (nullptr == content)
87  MITK_WARN << "Content for post is empty, this will create an empty resource";
88 
89  answer = client->Post(uri, content, headers);
90  break;
91 
92  case RequestType::Put:
93 
94  if (nullptr == content)
95  MITK_WARN << "Content for put is empty, this will empty the ressource";
96 
97  answer = client->Put(uri, content);
98  break;
99 
100  default:
101  mitkThrow() << "Request Type not supported";
102  }
103 
104  return answer;
105 }
106 
107 void mitk::RESTManager::ReceiveRequest(const web::uri &uri, mitk::IRESTObserver *observer)
108 {
109  // New instance of RESTServer in m_ServerMap, key is port of the request
110  auto port = uri.port();
111 
112  // Checking if port is free to add a new Server
113  if (0 == m_ServerMap.count(port))
114  {
115  this->AddObserver(uri, observer);
116  // creating server instance
117  auto server = new RESTServer(uri.authority());
118  // add reference to server instance to map
119  m_ServerMap[port] = server;
120  // start Server
121  server->OpenListener();
122  }
123  // If there is already a server under this port
124  else
125  {
126  this->RequestForATakenPort(uri, observer);
127  }
128 }
129 
131  const web::json::value &body,
132  const web::http::method &method,
133  const mitk::RESTUtil::ParamMap &headers)
134 {
135  // Checking if there is an observer for the port and path
136  auto key = std::make_pair(uri.port(), uri.path());
137  if (0 != m_Observers.count(key))
138  {
139  return m_Observers[key]->Notify(uri, body, method, headers);
140  }
141  // No observer under this port, return null which results in status code 404 (s. RESTServer)
142  else
143  {
144  MITK_WARN << "No Observer can handle the data";
145  web::http::http_response response(web::http::status_codes::BadGateway);
146  response.set_body(U("No one can handle the request under the given port."));
147  return response;
148  }
149 }
150 
151 void mitk::RESTManager::HandleDeleteObserver(IRESTObserver *observer, const web::uri &uri)
152 {
153  for (auto it = m_Observers.begin(); it != m_Observers.end();)
154  {
155  mitk::IRESTObserver *obsMap = it->second;
156  // Check wether observer is at this place in map
157  if (observer == obsMap)
158  {
159  // Check wether it is the right uri to be deleted
160  if (uri.is_empty() || uri.path() == it->first.second)
161  {
162  int port = it->first.first;
163  bool noObserverForPort = this->DeleteObserver(it);
164  if (noObserverForPort)
165  {
166  // there isn't an observer at this port, delete m_ServerMap entry for this port
167  // close listener
168  m_ServerMap[port]->CloseListener();
169  delete m_ServerMap[port];
170  // delete server from map
171  m_ServerMap.erase(port);
172  }
173  }
174  else
175  {
176  ++it;
177  }
178  }
179  else
180  {
181  ++it;
182  }
183  }
184 }
185 
186 const std::map<int, mitk::RESTServer *> &mitk::RESTManager::GetServerMap()
187 {
188  return m_ServerMap;
189 }
190 
191 std::map<std::pair<int, utility::string_t>, mitk::IRESTObserver *> &mitk::RESTManager::GetObservers()
192 {
193  return m_Observers;
194 }
195 
196 void mitk::RESTManager::AddObserver(const web::uri &uri, IRESTObserver *observer)
197 {
198  // new observer has to be added
199  std::pair<int, utility::string_t> key(uri.port(), uri.path());
200  m_Observers[key] = observer;
201 }
202 
203 void mitk::RESTManager::RequestForATakenPort(const web::uri &uri, IRESTObserver *observer)
204 {
205  // Same host, means new observer but not a new server instance
206  if (uri.authority() == m_ServerMap[uri.port()]->GetUri())
207  {
208  // new observer has to be added
209  std::pair<int, utility::string_t> key(uri.port(), uri.path());
210  // only add a new observer if there isn't already an observer for this uri
211  if (0 == m_Observers.count(key))
212  {
213  this->AddObserver(uri, observer);
214  }
215  else
216  {
217  MITK_ERROR << "Threre is already a observer handeling this data";
218  }
219  }
220  // Error, since another server can't be added under this port
221  else
222  {
223  MITK_ERROR << "There is already another server listening under this port";
224  }
225 }
226 
227 bool mitk::RESTManager::DeleteObserver(std::map<std::pair<int, utility::string_t>, IRESTObserver *>::iterator &it)
228 {
229  int port = it->first.first;
230 
231  it = m_Observers.erase(it);
232 
233  for (auto observer : m_Observers)
234  {
235  if (port == observer.first.first)
236  {
237  // there still exists an observer for this port
238  return false;
239  }
240  }
241 
242  return true;
243 }
244 
245 void mitk::RESTManager::SetServerMap(const int port, RESTServer *server)
246 {
247  m_ServerMap[port] = server;
248 }
249 
250 void mitk::RESTManager::DeleteFromServerMap(const int port)
251 {
252  m_ServerMap.erase(port);
253 }
254 
255 void mitk::RESTManager::SetObservers(const std::pair<int, utility::string_t> key, IRESTObserver *observer)
256 {
257  m_Observers[key] = observer;
258 }
pplx::task< web::json::value > SendJSONRequest(const web::uri &uri, const RequestType &type=RequestType::Get, const web::json::value *body=nullptr, const std::map< utility::string_t, utility::string_t > headers={}, const utility::string_t &filePath={}) override
Executes a HTTP request in the mitkRESTClient class.
#define MITK_ERROR
Definition: mitkLogMacros.h:20
pplx::task< web::json::value > SendBinaryRequest(const web::uri &uri, const RequestType &type=RequestType::Get, const std::vector< unsigned char > *={}, const std::map< utility::string_t, utility::string_t > headers={}) override
Executes a HTTP request in the mitkRESTClient class.
pplx::task< web::json::value > SendRequest(const web::uri &uri, const RequestType &type=RequestType::Get, const std::map< utility::string_t, utility::string_t > headers={}) override
Executes a HTTP request in the mitkRESTClient class.
const std::map< int, RESTServer * > & GetServerMap() override
internal use only
web::http::http_response Handle(const web::uri &uri, const web::json::value &body, const web::http::method &method, const mitk::RESTUtil::ParamMap &headers) override
Handles incoming requests by notifying the observer which should receive it.
#define MITK_WARN
Definition: mitkLogMacros.h:19
#define mitkThrow()
RequestType
request type for client requests by calling SendRequest
web::http::http_response http_response
MITKMATCHPOINTREGISTRATION_EXPORT ResultImageType::Pointer map(const InputImageType *input, const RegistrationType *registration, bool throwOnOutOfInputAreaError=false, const double &paddingValue=0, const ResultImageGeometryType *resultGeometry=nullptr, bool throwOnMappingError=true, const double &errorValue=0, mitk::ImageMappingInterpolator::Type interpolatorType=mitk::ImageMappingInterpolator::Linear)
std::map< utility::string_t, utility::string_t > ParamMap
Definition: mitkRESTUtil.h:27
void HandleDeleteObserver(IRESTObserver *observer, const web::uri &uri={}) override
Handles the deletion of an observer for all or a specific uri.
void ReceiveRequest(const web::uri &uri, IRESTObserver *observer) override
starts listening for requests if there isn&#39;t another observer listening and the port is free ...
std::map< std::pair< int, utility::string_t >, IRESTObserver * > & GetObservers() override