comparison OrthancServer/OrthancRestApi.cpp @ 485:bdbde1fbfab3

send resources through HTTP
author Sebastien Jodogne <s.jodogne@gmail.com>
date Tue, 16 Jul 2013 13:48:33 +0200
parents b8ace6fc1d1f
children 7db04aa5104f
comparison
equal deleted inserted replaced
484:b8ace6fc1d1f 485:bdbde1fbfab3
30 **/ 30 **/
31 31
32 32
33 #include "OrthancRestApi.h" 33 #include "OrthancRestApi.h"
34 34
35 #include "../Core/Compression/HierarchicalZipWriter.h"
36 #include "../Core/HttpClient.h"
35 #include "../Core/HttpServer/FilesystemHttpSender.h" 37 #include "../Core/HttpServer/FilesystemHttpSender.h"
36 #include "../Core/Uuid.h" 38 #include "../Core/Uuid.h"
37 #include "../Core/Compression/HierarchicalZipWriter.h"
38 #include "DicomProtocol/DicomUserConnection.h" 39 #include "DicomProtocol/DicomUserConnection.h"
39 #include "FromDcmtkBridge.h" 40 #include "FromDcmtkBridge.h"
40 #include "OrthancInitialization.h" 41 #include "OrthancInitialization.h"
41 #include "ServerToolbox.h" 42 #include "ServerToolbox.h"
42 43
246 247
247 call.GetOutput().AnswerJson(result); 248 call.GetOutput().AnswerJson(result);
248 } 249 }
249 250
250 251
251 static void DicomStore(RestApi::PostCall& call) 252 static bool GetInstancesToExport(std::list<std::string>& instances,
252 { 253 const std::string& remote,
253 RETRIEVE_CONTEXT(call); 254 RestApi::PostCall& call)
254 255 {
255 std::string remote = call.GetUriComponent("id", ""); 256 RETRIEVE_CONTEXT(call);
257
256 std::string stripped = Toolbox::StripSpaces(call.GetPostBody()); 258 std::string stripped = Toolbox::StripSpaces(call.GetPostBody());
257 259
258 Json::Value request; 260 Json::Value request;
259 if (Toolbox::IsSHA1(stripped)) 261 if (Toolbox::IsSHA1(stripped))
260 { 262 {
262 request = stripped; 264 request = stripped;
263 } 265 }
264 else if (!call.ParseJsonRequest(request)) 266 else if (!call.ParseJsonRequest(request))
265 { 267 {
266 // Bad JSON request 268 // Bad JSON request
267 return; 269 return false;
268 } 270 }
269 271
270 std::list<std::string> instances;
271 if (request.isString()) 272 if (request.isString())
272 { 273 {
273 LOG(INFO) << "Sending resource " << request.asString() << " to modality " << remote;
274 context.GetIndex().LogExportedResource(request.asString(), remote); 274 context.GetIndex().LogExportedResource(request.asString(), remote);
275 context.GetIndex().GetChildInstances(instances, request.asString()); 275 context.GetIndex().GetChildInstances(instances, request.asString());
276 } 276 }
277 else if (request.isArray()) 277 else if (request.isArray())
278 { 278 {
279 for (Json::Value::ArrayIndex i = 0; i < request.size(); i++) 279 for (Json::Value::ArrayIndex i = 0; i < request.size(); i++)
280 { 280 {
281 if (!request[i].isString()) 281 if (!request[i].isString())
282 { 282 {
283 return; 283 return false;
284 } 284 }
285 285
286 std::string stripped = Toolbox::StripSpaces(request[i].asString()); 286 std::string stripped = Toolbox::StripSpaces(request[i].asString());
287 if (!Toolbox::IsSHA1(stripped)) 287 if (!Toolbox::IsSHA1(stripped))
288 { 288 {
289 return; 289 return false;
290 } 290 }
291 291
292 LOG(INFO) << "Sending resource " << stripped << " to modality " << remote;
293 context.GetIndex().LogExportedResource(stripped, remote); 292 context.GetIndex().LogExportedResource(stripped, remote);
294 293
295 std::list<std::string> tmp; 294 std::list<std::string> tmp;
296 context.GetIndex().GetChildInstances(tmp, stripped); 295 context.GetIndex().GetChildInstances(tmp, stripped);
297 instances.merge(tmp); 296 instances.merge(tmp);
299 } 298 }
300 } 299 }
301 else 300 else
302 { 301 {
303 // Neither a string, nor a list of strings. Bad request. 302 // Neither a string, nor a list of strings. Bad request.
303 return false;
304 }
305
306 return true;
307 }
308
309
310 static void DicomStore(RestApi::PostCall& call)
311 {
312 RETRIEVE_CONTEXT(call);
313
314 std::string remote = call.GetUriComponent("id", "");
315
316 std::list<std::string> instances;
317 if (!GetInstancesToExport(instances, remote, call))
318 {
304 return; 319 return;
305 } 320 }
306 321
307 DicomUserConnection connection; 322 DicomUserConnection connection;
308 ConnectToModality(connection, remote); 323 ConnectToModality(connection, remote);
309 324
310 for (std::list<std::string>::const_iterator 325 for (std::list<std::string>::const_iterator
311 it = instances.begin(); it != instances.end(); it++) 326 it = instances.begin(); it != instances.end(); it++)
312 { 327 {
328 LOG(INFO) << "Sending resource " << *it << " to modality \"" << remote << "\"";
329
313 std::string dicom; 330 std::string dicom;
314 context.ReadFile(dicom, *it, FileContentType_Dicom); 331 context.ReadFile(dicom, *it, FileContentType_Dicom);
315 connection.Store(dicom); 332 connection.Store(dicom);
316 } 333 }
317 334
1647 result.append("store"); 1664 result.append("store");
1648 call.GetOutput().AnswerJson(result); 1665 call.GetOutput().AnswerJson(result);
1649 } 1666 }
1650 } 1667 }
1651 1668
1669 static void PeerStore(RestApi::PostCall& call)
1670 {
1671 RETRIEVE_CONTEXT(call);
1672
1673 std::string remote = call.GetUriComponent("id", "");
1674
1675 std::list<std::string> instances;
1676 if (!GetInstancesToExport(instances, remote, call))
1677 {
1678 return;
1679 }
1680
1681 std::string url, username, password;
1682 GetOrthancPeer(remote, url, username, password);
1683
1684 // Configure the HTTP client
1685 HttpClient client;
1686 if (username.size() != 0 && password.size() != 0)
1687 {
1688 client.SetCredentials(username.c_str(), password.c_str());
1689 }
1690
1691 client.SetUrl(url + "instances");
1692 client.SetMethod(HttpMethod_Post);
1693
1694 // Loop over the instances that are to be sent
1695 for (std::list<std::string>::const_iterator
1696 it = instances.begin(); it != instances.end(); it++)
1697 {
1698 LOG(INFO) << "Sending resource " << *it << " to peer \"" << remote << "\"";
1699
1700 context.ReadFile(client.AccessPostData(), *it, FileContentType_Dicom);
1701
1702 std::string answer;
1703 if (!client.Apply(answer))
1704 {
1705 LOG(ERROR) << "Unable to send resource " << *it << " to peer \"" << remote << "\"";
1706 return;
1707 }
1708 }
1709
1710 call.GetOutput().AnswerBuffer("{}", "application/json");
1711 }
1712
1713
1652 1714
1653 1715
1654 1716
1655 // Registration of the various REST handlers -------------------------------- 1717 // Registration of the various REST handlers --------------------------------
1656 1718
1735 Register("/modalities/{id}/find", DicomFind); 1797 Register("/modalities/{id}/find", DicomFind);
1736 Register("/modalities/{id}/store", DicomStore); 1798 Register("/modalities/{id}/store", DicomStore);
1737 1799
1738 Register("/peers", ListPeers); 1800 Register("/peers", ListPeers);
1739 Register("/peers/{id}", ListPeerOperations); 1801 Register("/peers/{id}", ListPeerOperations);
1802 Register("/peers/{id}/store", PeerStore);
1740 1803
1741 Register("/instances/{id}/modify", ModifyInstance); 1804 Register("/instances/{id}/modify", ModifyInstance);
1742 Register("/series/{id}/modify", ModifySeriesInplace); 1805 Register("/series/{id}/modify", ModifySeriesInplace);
1743 Register("/studies/{id}/modify", ModifyStudyInplace); 1806 Register("/studies/{id}/modify", ModifyStudyInplace);
1744 Register("/patients/{id}/modify", ModifyPatientInplace); 1807 Register("/patients/{id}/modify", ModifyPatientInplace);