comparison Framework/Toolbox/OrthancApiClient.cpp @ 422:4fe42ae3653a am-vsol-upgrade

introduced a basic cache at OrthancApiClient level so it can be used with the RadiographyScene
author am@osimis.io
date Tue, 20 Nov 2018 21:44:48 +0100
parents c23df8b3433b
children bb573a52fc63
comparison
equal deleted inserted replaced
420:8bf717c4e497 422:4fe42ae3653a
152 } 152 }
153 else 153 else
154 { 154 {
155 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); 155 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
156 } 156 }
157 } 157 }
158 158
159 void HandleFailure(const IWebService::HttpRequestErrorMessage& message) const 159 void HandleFailure(const IWebService::HttpRequestErrorMessage& message) const
160 { 160 {
161 if (failureHandler_.get() != NULL) 161 if (failureHandler_.get() != NULL)
162 { 162 {
163 failureHandler_->Apply(IWebService::HttpRequestErrorMessage 163 failureHandler_->Apply(IWebService::HttpRequestErrorMessage
164 (message.GetUri(), userPayload_.get())); 164 (message.GetUri(), userPayload_.get()));
165 } 165 }
166 } 166 }
167 };
168
169
170 class OrthancApiClient::CachedHttpRequestSuccessMessage
171 {
172 protected:
173 const std::string& uri_;
174 void* answer_;
175 size_t answerSize_;
176 IWebService::HttpHeaders answerHeaders_;
177
178 public:
179 CachedHttpRequestSuccessMessage(const IWebService::HttpRequestSuccessMessage& message) :
180 uri_(message.GetUri()),
181 answerSize_(message.GetAnswerSize()),
182 answerHeaders_(message.GetAnswerHttpHeaders())
183 {
184 answer_ = malloc(answerSize_);
185 memcpy(answer_, message.GetAnswer(), answerSize_);
186 }
187
188 ~CachedHttpRequestSuccessMessage()
189 {
190 free(answer_);
191 }
192
193 const std::string& GetUri() const
194 {
195 return uri_;
196 }
197
198 const void* GetAnswer() const
199 {
200 return answer_;
201 }
202
203 size_t GetAnswerSize() const
204 {
205 return answerSize_;
206 }
207
208 const IWebService::HttpHeaders& GetAnswerHttpHeaders() const
209 {
210 return answerHeaders_;
211 }
212
167 }; 213 };
168 214
169 215
170 OrthancApiClient::OrthancApiClient(MessageBroker& broker, 216 OrthancApiClient::OrthancApiClient(MessageBroker& broker,
171 IWebService& web, 217 IWebService& web,
172 const std::string& baseUrl) : 218 const std::string& baseUrl) :
173 IObservable(broker), 219 IObservable(broker),
174 IObserver(broker), 220 IObserver(broker),
175 web_(web), 221 web_(web),
176 baseUrl_(baseUrl) 222 baseUrl_(baseUrl),
223 cacheEnabled_(true)
177 { 224 {
178 } 225 }
179 226
180 227
181 void OrthancApiClient::GetJsonAsync( 228 void OrthancApiClient::GetJsonAsync(
182 const std::string& uri, 229 const std::string& uri,
183 MessageHandler<JsonResponseReadyMessage>* successCallback, 230 MessageHandler<JsonResponseReadyMessage>* successCallback,
184 MessageHandler<IWebService::HttpRequestErrorMessage>* failureCallback, 231 MessageHandler<IWebService::HttpRequestErrorMessage>* failureCallback,
185 Orthanc::IDynamicObject* payload) 232 Orthanc::IDynamicObject* payload)
186 { 233 {
187 web_.GetAsync(baseUrl_ + uri, 234 IWebService::HttpHeaders emptyHeaders;
188 IWebService::HttpHeaders(), 235 if (cacheEnabled_)
189 new WebServicePayload(successCallback, failureCallback, payload), 236 {
190 new Callable<OrthancApiClient, IWebService::HttpRequestSuccessMessage> 237 HandleFromCache(baseUrl_ + uri,
191 (*this, &OrthancApiClient::NotifyHttpSuccess), 238 emptyHeaders,
192 new Callable<OrthancApiClient, IWebService::HttpRequestErrorMessage> 239 new WebServicePayload(successCallback, failureCallback, payload));
193 (*this, &OrthancApiClient::NotifyHttpError)); 240 }
241 else
242 {
243 web_.GetAsync(baseUrl_ + uri,
244 emptyHeaders,
245 new WebServicePayload(successCallback, failureCallback, payload),
246 new Callable<OrthancApiClient, IWebService::HttpRequestSuccessMessage>
247 (*this, &OrthancApiClient::NotifyHttpSuccess),
248 new Callable<OrthancApiClient, IWebService::HttpRequestErrorMessage>
249 (*this, &OrthancApiClient::NotifyHttpError));
250 }
194 } 251 }
195 252
196 253
197 void OrthancApiClient::GetBinaryAsync( 254 void OrthancApiClient::GetBinaryAsync(
198 const std::string& uri, 255 const std::string& uri,
199 const std::string& contentType, 256 const std::string& contentType,
200 MessageHandler<BinaryResponseReadyMessage>* successCallback, 257 MessageHandler<BinaryResponseReadyMessage>* successCallback,
201 MessageHandler<IWebService::HttpRequestErrorMessage>* failureCallback, 258 MessageHandler<IWebService::HttpRequestErrorMessage>* failureCallback,
202 Orthanc::IDynamicObject* payload) 259 Orthanc::IDynamicObject* payload)
203 { 260 {
204 IWebService::HttpHeaders headers; 261 IWebService::HttpHeaders headers;
205 headers["Accept"] = contentType; 262 headers["Accept"] = contentType;
206 GetBinaryAsync(uri, headers, successCallback, failureCallback, payload); 263 GetBinaryAsync(uri, headers, successCallback, failureCallback, payload);
207 } 264 }
208 265
209 266
267 void OrthancApiClient::HandleFromCache(const std::string& uri,
268 const IWebService::HttpHeaders& headers,
269 Orthanc::IDynamicObject* payload // takes ownership
270 )
271 {
272 if (cache_.find(uri) == cache_.end())
273 {
274 web_.GetAsync(uri, headers,
275 payload, // ownership is transfered
276 new Callable<OrthancApiClient, IWebService::HttpRequestSuccessMessage>
277 (*this, &OrthancApiClient::CacheAndNotifyHttpSuccess),
278 new Callable<OrthancApiClient, IWebService::HttpRequestErrorMessage>
279 (*this, &OrthancApiClient::NotifyHttpError));
280 }
281 else
282 {
283 std::auto_ptr<Orthanc::IDynamicObject> payloadRaii(payload); // make sure payload is deleted whatever happens
284
285 const OrthancApiClient::CachedHttpRequestSuccessMessage& cachedMessage = *(cache_[uri]);
286 IWebService::HttpRequestSuccessMessage successMessage(cachedMessage.GetUri(),
287 cachedMessage.GetAnswer(),
288 cachedMessage.GetAnswerSize(),
289 cachedMessage.GetAnswerHttpHeaders(),
290 payloadRaii.get());
291 NotifyHttpSuccess(successMessage);
292 }
293
294 }
295
296
210 void OrthancApiClient::GetBinaryAsync( 297 void OrthancApiClient::GetBinaryAsync(
211 const std::string& uri, 298 const std::string& uri,
212 const IWebService::HttpHeaders& headers, 299 const IWebService::HttpHeaders& headers,
213 MessageHandler<BinaryResponseReadyMessage>* successCallback, 300 MessageHandler<BinaryResponseReadyMessage>* successCallback,
214 MessageHandler<IWebService::HttpRequestErrorMessage>* failureCallback, 301 MessageHandler<IWebService::HttpRequestErrorMessage>* failureCallback,
215 Orthanc::IDynamicObject* payload) 302 Orthanc::IDynamicObject* payload)
216 { 303 {
217 printf("GET [%s] [%s]\n", baseUrl_.c_str(), uri.c_str()); 304 // printf("GET [%s] [%s]\n", baseUrl_.c_str(), uri.c_str());
218 305
219 web_.GetAsync(baseUrl_ + uri, headers, 306 if (cacheEnabled_)
220 new WebServicePayload(successCallback, failureCallback, payload), 307 {
221 new Callable<OrthancApiClient, IWebService::HttpRequestSuccessMessage> 308 HandleFromCache(baseUrl_ + uri,
222 (*this, &OrthancApiClient::NotifyHttpSuccess), 309 headers,
223 new Callable<OrthancApiClient, IWebService::HttpRequestErrorMessage> 310 new WebServicePayload(successCallback, failureCallback, payload));
224 (*this, &OrthancApiClient::NotifyHttpError)); 311 }
312 else
313 {
314 web_.GetAsync(baseUrl_ + uri, headers,
315 new WebServicePayload(successCallback, failureCallback, payload),
316 new Callable<OrthancApiClient, IWebService::HttpRequestSuccessMessage>
317 (*this, &OrthancApiClient::NotifyHttpSuccess),
318 new Callable<OrthancApiClient, IWebService::HttpRequestErrorMessage>
319 (*this, &OrthancApiClient::NotifyHttpError));
320 }
225 } 321 }
226 322
227 323
228 void OrthancApiClient::PostBinaryAsyncExpectJson( 324 void OrthancApiClient::PostBinaryAsyncExpectJson(
229 const std::string& uri, 325 const std::string& uri,
230 const std::string& body, 326 const std::string& body,
231 MessageHandler<JsonResponseReadyMessage>* successCallback, 327 MessageHandler<JsonResponseReadyMessage>* successCallback,
232 MessageHandler<IWebService::HttpRequestErrorMessage>* failureCallback, 328 MessageHandler<IWebService::HttpRequestErrorMessage>* failureCallback,
233 Orthanc::IDynamicObject* payload) 329 Orthanc::IDynamicObject* payload)
234 { 330 {
235 web_.PostAsync(baseUrl_ + uri, IWebService::HttpHeaders(), body, 331 web_.PostAsync(baseUrl_ + uri, IWebService::HttpHeaders(), body,
236 new WebServicePayload(successCallback, failureCallback, payload), 332 new WebServicePayload(successCallback, failureCallback, payload),
237 new Callable<OrthancApiClient, IWebService::HttpRequestSuccessMessage> 333 new Callable<OrthancApiClient, IWebService::HttpRequestSuccessMessage>
238 (*this, &OrthancApiClient::NotifyHttpSuccess), 334 (*this, &OrthancApiClient::NotifyHttpSuccess),
241 337
242 } 338 }
243 339
244 340
245 void OrthancApiClient::PostJsonAsyncExpectJson( 341 void OrthancApiClient::PostJsonAsyncExpectJson(
246 const std::string& uri, 342 const std::string& uri,
247 const Json::Value& data, 343 const Json::Value& data,
248 MessageHandler<JsonResponseReadyMessage>* successCallback, 344 MessageHandler<JsonResponseReadyMessage>* successCallback,
249 MessageHandler<IWebService::HttpRequestErrorMessage>* failureCallback, 345 MessageHandler<IWebService::HttpRequestErrorMessage>* failureCallback,
250 Orthanc::IDynamicObject* payload) 346 Orthanc::IDynamicObject* payload)
251 { 347 {
252 std::string body; 348 std::string body;
253 MessagingToolbox::JsonToString(body, data); 349 MessagingToolbox::JsonToString(body, data);
254 return PostBinaryAsyncExpectJson(uri, body, successCallback, failureCallback, payload); 350 return PostBinaryAsyncExpectJson(uri, body, successCallback, failureCallback, payload);
255 } 351 }
256 352
257 353
258 void OrthancApiClient::DeleteAsync( 354 void OrthancApiClient::DeleteAsync(
259 const std::string& uri, 355 const std::string& uri,
260 MessageHandler<EmptyResponseReadyMessage>* successCallback, 356 MessageHandler<EmptyResponseReadyMessage>* successCallback,
261 MessageHandler<IWebService::HttpRequestErrorMessage>* failureCallback, 357 MessageHandler<IWebService::HttpRequestErrorMessage>* failureCallback,
262 Orthanc::IDynamicObject* payload) 358 Orthanc::IDynamicObject* payload)
263 { 359 {
264 web_.DeleteAsync(baseUrl_ + uri, IWebService::HttpHeaders(), 360 web_.DeleteAsync(baseUrl_ + uri, IWebService::HttpHeaders(),
265 new WebServicePayload(successCallback, failureCallback, payload), 361 new WebServicePayload(successCallback, failureCallback, payload),
266 new Callable<OrthancApiClient, IWebService::HttpRequestSuccessMessage> 362 new Callable<OrthancApiClient, IWebService::HttpRequestSuccessMessage>
267 (*this, &OrthancApiClient::NotifyHttpSuccess), 363 (*this, &OrthancApiClient::NotifyHttpSuccess),
280 { 376 {
281 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); 377 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
282 } 378 }
283 } 379 }
284 380
285 381 void OrthancApiClient::CacheAndNotifyHttpSuccess(const IWebService::HttpRequestSuccessMessage& message)
382 {
383 cache_[message.GetUri()] = boost::shared_ptr<CachedHttpRequestSuccessMessage>(new CachedHttpRequestSuccessMessage(message));
384 NotifyHttpSuccess(message);
385 }
386
286 void OrthancApiClient::NotifyHttpError(const IWebService::HttpRequestErrorMessage& message) 387 void OrthancApiClient::NotifyHttpError(const IWebService::HttpRequestErrorMessage& message)
287 { 388 {
288 if (message.HasPayload()) 389 if (message.HasPayload())
289 { 390 {
290 dynamic_cast<const WebServicePayload&>(message.GetPayload()).HandleFailure(message); 391 dynamic_cast<const WebServicePayload&>(message.GetPayload()).HandleFailure(message);
291 } 392 }
292 else 393 else
293 { 394 {
294 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); 395 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
295 } 396 }
296 } 397 }
297 } 398 }