comparison OrthancServer/OrthancRestApi/OrthancRestModalities.cpp @ 3876:92ecaf877baf transcoding

improved code reuse in OrthancRestModalities, added missing timeout params
author Sebastien Jodogne <s.jodogne@gmail.com>
date Mon, 04 May 2020 15:37:45 +0200
parents ea1d32861cfc
children 8f7ad4989fec
comparison
equal deleted inserted replaced
3875:ea1d32861cfc 3876:92ecaf877baf
52 52
53 53
54 namespace Orthanc 54 namespace Orthanc
55 { 55 {
56 static const char* const KEY_LEVEL = "Level"; 56 static const char* const KEY_LEVEL = "Level";
57 static const char* const KEY_LOCAL_AET = "LocalAet";
58 static const char* const KEY_NORMALIZE = "Normalize";
57 static const char* const KEY_QUERY = "Query"; 59 static const char* const KEY_QUERY = "Query";
58 static const char* const KEY_NORMALIZE = "Normalize";
59 static const char* const KEY_RESOURCES = "Resources"; 60 static const char* const KEY_RESOURCES = "Resources";
61 static const char* const KEY_TARGET_AET = "TargetAet";
62 static const char* const KEY_TIMEOUT = "Timeout";
60 static const char* const SOP_CLASS_UID = "SOPClassUID"; 63 static const char* const SOP_CLASS_UID = "SOPClassUID";
61 static const char* const SOP_INSTANCE_UID = "SOPInstanceUID"; 64 static const char* const SOP_INSTANCE_UID = "SOPInstanceUID";
62
63 65
64 static RemoteModalityParameters MyGetModalityUsingSymbolicName(const std::string& name) 66 static RemoteModalityParameters MyGetModalityUsingSymbolicName(const std::string& name)
65 { 67 {
66 OrthancConfiguration::ReaderLock lock; 68 OrthancConfiguration::ReaderLock lock;
67 return lock.GetConfiguration().GetModalityUsingSymbolicName(name); 69 return lock.GetConfiguration().GetModalityUsingSymbolicName(name);
68 } 70 }
69 71
72
73 static void InjectAssociationTimeout(DicomAssociationParameters& params,
74 const Json::Value& body)
75 {
76 if (body.type() != Json::objectValue)
77 {
78 throw OrthancException(ErrorCode_BadFileFormat, "Must provide a JSON object");
79 }
80 else if (body.isMember(KEY_TIMEOUT))
81 {
82 // New in Orthanc 1.7.0
83 params.SetTimeout(SerializationToolbox::ReadUnsignedInteger(body, KEY_TIMEOUT));
84 }
85 }
86
87 static DicomAssociationParameters GetAssociationParameters(RestApiPostCall& call,
88 const Json::Value& body)
89 {
90 const std::string& localAet =
91 OrthancRestApi::GetContext(call).GetDefaultLocalApplicationEntityTitle();
92 const RemoteModalityParameters remote =
93 MyGetModalityUsingSymbolicName(call.GetUriComponent("id", ""));
94
95 DicomAssociationParameters params(localAet, remote);
96 InjectAssociationTimeout(params, body);
97
98 return params;
99 }
100
101
102 static DicomAssociationParameters GetAssociationParameters(RestApiPostCall& call)
103 {
104 Json::Value body;
105 call.ParseJsonRequest(body);
106 return GetAssociationParameters(call, body);
107 }
108
70 109
71 /*************************************************************************** 110 /***************************************************************************
72 * DICOM C-Echo SCU 111 * DICOM C-Echo SCU
73 ***************************************************************************/ 112 ***************************************************************************/
74 113
75 static void DicomEcho(RestApiPostCall& call) 114 static void DicomEcho(RestApiPostCall& call)
76 { 115 {
77 ServerContext& context = OrthancRestApi::GetContext(call);
78
79 const std::string& localAet = context.GetDefaultLocalApplicationEntityTitle();
80 RemoteModalityParameters remote =
81 MyGetModalityUsingSymbolicName(call.GetUriComponent("id", ""));
82
83 Json::Value request;
84 call.ParseJsonRequest(request);
85 int timeout = Toolbox::GetJsonIntegerField(request, "Timeout", -1);
86
87 try 116 try
88 { 117 {
89 DicomAssociationParameters params(localAet, remote); 118 DicomControlUserConnection connection(GetAssociationParameters(call));
90
91 // New in Orthanc 1.7.0
92 if (timeout >= 0)
93 {
94 params.SetTimeout(static_cast<uint32_t>(timeout));
95 }
96
97 DicomControlUserConnection connection(params);
98 119
99 if (connection.Echo()) 120 if (connection.Echo())
100 { 121 {
101 // Echo has succeeded 122 // Echo has succeeded
102 call.GetOutput().AnswerBuffer("{}", MimeType_Json); 123 call.GetOutput().AnswerBuffer("{}", MimeType_Json);
198 219
199 220
200 static void DicomFindPatient(RestApiPostCall& call) 221 static void DicomFindPatient(RestApiPostCall& call)
201 { 222 {
202 LOG(WARNING) << "This URI is deprecated: " << call.FlattenUri(); 223 LOG(WARNING) << "This URI is deprecated: " << call.FlattenUri();
203 ServerContext& context = OrthancRestApi::GetContext(call);
204 224
205 DicomMap fields; 225 DicomMap fields;
206 DicomMap::SetupFindPatientTemplate(fields); 226 DicomMap::SetupFindPatientTemplate(fields);
207 if (!MergeQueryAndTemplate(fields, call)) 227 if (!MergeQueryAndTemplate(fields, call))
208 { 228 {
209 return; 229 return;
210 } 230 }
211 231
212 const std::string& localAet = context.GetDefaultLocalApplicationEntityTitle();
213 RemoteModalityParameters remote =
214 MyGetModalityUsingSymbolicName(call.GetUriComponent("id", ""));
215
216 DicomFindAnswers answers(false); 232 DicomFindAnswers answers(false);
217 233
218 { 234 {
219 DicomAssociationParameters params(localAet, remote); 235 DicomControlUserConnection connection(GetAssociationParameters(call));
220 DicomControlUserConnection connection(params);
221 FindPatient(answers, connection, fields); 236 FindPatient(answers, connection, fields);
222 } 237 }
223 238
224 Json::Value result; 239 Json::Value result;
225 answers.ToJson(result, true); 240 answers.ToJson(result, true);
227 } 242 }
228 243
229 static void DicomFindStudy(RestApiPostCall& call) 244 static void DicomFindStudy(RestApiPostCall& call)
230 { 245 {
231 LOG(WARNING) << "This URI is deprecated: " << call.FlattenUri(); 246 LOG(WARNING) << "This URI is deprecated: " << call.FlattenUri();
232 ServerContext& context = OrthancRestApi::GetContext(call);
233 247
234 DicomMap fields; 248 DicomMap fields;
235 DicomMap::SetupFindStudyTemplate(fields); 249 DicomMap::SetupFindStudyTemplate(fields);
236 if (!MergeQueryAndTemplate(fields, call)) 250 if (!MergeQueryAndTemplate(fields, call))
237 { 251 {
242 fields.GetValue(DICOM_TAG_PATIENT_ID).GetContent().size() <= 2) 256 fields.GetValue(DICOM_TAG_PATIENT_ID).GetContent().size() <= 2)
243 { 257 {
244 return; 258 return;
245 } 259 }
246 260
247 const std::string& localAet = context.GetDefaultLocalApplicationEntityTitle();
248 RemoteModalityParameters remote =
249 MyGetModalityUsingSymbolicName(call.GetUriComponent("id", ""));
250
251 DicomFindAnswers answers(false); 261 DicomFindAnswers answers(false);
252 262
253 { 263 {
254 DicomAssociationParameters params(localAet, remote); 264 DicomControlUserConnection connection(GetAssociationParameters(call));
255 DicomControlUserConnection connection(params);
256 FindStudy(answers, connection, fields); 265 FindStudy(answers, connection, fields);
257 } 266 }
258 267
259 Json::Value result; 268 Json::Value result;
260 answers.ToJson(result, true); 269 answers.ToJson(result, true);
262 } 271 }
263 272
264 static void DicomFindSeries(RestApiPostCall& call) 273 static void DicomFindSeries(RestApiPostCall& call)
265 { 274 {
266 LOG(WARNING) << "This URI is deprecated: " << call.FlattenUri(); 275 LOG(WARNING) << "This URI is deprecated: " << call.FlattenUri();
267 ServerContext& context = OrthancRestApi::GetContext(call);
268 276
269 DicomMap fields; 277 DicomMap fields;
270 DicomMap::SetupFindSeriesTemplate(fields); 278 DicomMap::SetupFindSeriesTemplate(fields);
271 if (!MergeQueryAndTemplate(fields, call)) 279 if (!MergeQueryAndTemplate(fields, call))
272 { 280 {
278 fields.GetValue(DICOM_TAG_STUDY_INSTANCE_UID).GetContent().size() <= 2) 286 fields.GetValue(DICOM_TAG_STUDY_INSTANCE_UID).GetContent().size() <= 2)
279 { 287 {
280 return; 288 return;
281 } 289 }
282 290
283 const std::string& localAet = context.GetDefaultLocalApplicationEntityTitle();
284 RemoteModalityParameters remote =
285 MyGetModalityUsingSymbolicName(call.GetUriComponent("id", ""));
286
287 DicomFindAnswers answers(false); 291 DicomFindAnswers answers(false);
288 292
289 { 293 {
290 DicomAssociationParameters params(localAet, remote); 294 DicomControlUserConnection connection(GetAssociationParameters(call));
291 DicomControlUserConnection connection(params);
292 FindSeries(answers, connection, fields); 295 FindSeries(answers, connection, fields);
293 } 296 }
294 297
295 Json::Value result; 298 Json::Value result;
296 answers.ToJson(result, true); 299 answers.ToJson(result, true);
298 } 301 }
299 302
300 static void DicomFindInstance(RestApiPostCall& call) 303 static void DicomFindInstance(RestApiPostCall& call)
301 { 304 {
302 LOG(WARNING) << "This URI is deprecated: " << call.FlattenUri(); 305 LOG(WARNING) << "This URI is deprecated: " << call.FlattenUri();
303 ServerContext& context = OrthancRestApi::GetContext(call);
304 306
305 DicomMap fields; 307 DicomMap fields;
306 DicomMap::SetupFindInstanceTemplate(fields); 308 DicomMap::SetupFindInstanceTemplate(fields);
307 if (!MergeQueryAndTemplate(fields, call)) 309 if (!MergeQueryAndTemplate(fields, call))
308 { 310 {
315 fields.GetValue(DICOM_TAG_SERIES_INSTANCE_UID).GetContent().size() <= 2) 317 fields.GetValue(DICOM_TAG_SERIES_INSTANCE_UID).GetContent().size() <= 2)
316 { 318 {
317 return; 319 return;
318 } 320 }
319 321
320 const std::string& localAet = context.GetDefaultLocalApplicationEntityTitle();
321 RemoteModalityParameters remote =
322 MyGetModalityUsingSymbolicName(call.GetUriComponent("id", ""));
323
324 DicomFindAnswers answers(false); 322 DicomFindAnswers answers(false);
325 323
326 { 324 {
327 DicomAssociationParameters params(localAet, remote); 325 DicomControlUserConnection connection(GetAssociationParameters(call));
328 DicomControlUserConnection connection(params);
329 FindInstance(answers, connection, fields); 326 FindInstance(answers, connection, fields);
330 } 327 }
331 328
332 Json::Value result; 329 Json::Value result;
333 answers.ToJson(result, true); 330 answers.ToJson(result, true);
348 345
349 346
350 static void DicomFind(RestApiPostCall& call) 347 static void DicomFind(RestApiPostCall& call)
351 { 348 {
352 LOG(WARNING) << "This URI is deprecated: " << call.FlattenUri(); 349 LOG(WARNING) << "This URI is deprecated: " << call.FlattenUri();
353 ServerContext& context = OrthancRestApi::GetContext(call);
354 350
355 DicomMap m; 351 DicomMap m;
356 DicomMap::SetupFindPatientTemplate(m); 352 DicomMap::SetupFindPatientTemplate(m);
357 if (!MergeQueryAndTemplate(m, call)) 353 if (!MergeQueryAndTemplate(m, call))
358 { 354 {
359 return; 355 return;
360 } 356 }
361 357
362 const std::string& localAet = context.GetDefaultLocalApplicationEntityTitle(); 358 DicomControlUserConnection connection(GetAssociationParameters(call));
363 RemoteModalityParameters remote =
364 MyGetModalityUsingSymbolicName(call.GetUriComponent("id", ""));
365
366 DicomAssociationParameters params(localAet, remote);
367 DicomControlUserConnection connection(params);
368 359
369 DicomFindAnswers patients(false); 360 DicomFindAnswers patients(false);
370 FindPatient(patients, connection, m); 361 FindPatient(patients, connection, m);
371 362
372 // Loop over the found patients 363 // Loop over the found patients
625 int timeout = -1; 616 int timeout = -1;
626 617
627 Json::Value body; 618 Json::Value body;
628 if (call.ParseJsonRequest(body)) 619 if (call.ParseJsonRequest(body))
629 { 620 {
630 targetAet = Toolbox::GetJsonStringField(body, "TargetAet", context.GetDefaultLocalApplicationEntityTitle()); 621 targetAet = Toolbox::GetJsonStringField(body, KEY_TARGET_AET, context.GetDefaultLocalApplicationEntityTitle());
631 timeout = Toolbox::GetJsonIntegerField(body, "Timeout", -1); 622 timeout = Toolbox::GetJsonIntegerField(body, KEY_TIMEOUT, -1);
632 } 623 }
633 else 624 else
634 { 625 {
635 body = Json::objectValue; 626 body = Json::objectValue;
636 if (call.GetBodySize() > 0) 627 if (call.GetBodySize() > 0)
651 job->SetLocalAet(query.GetHandler().GetLocalAet()); 642 job->SetLocalAet(query.GetHandler().GetLocalAet());
652 job->SetRemoteModality(query.GetHandler().GetRemoteModality()); 643 job->SetRemoteModality(query.GetHandler().GetRemoteModality());
653 644
654 if (timeout >= 0) 645 if (timeout >= 0)
655 { 646 {
647 // New in Orthanc 1.7.0
656 job->SetTimeout(static_cast<uint32_t>(timeout)); 648 job->SetTimeout(static_cast<uint32_t>(timeout));
657 } 649 }
658 650
659 LOG(WARNING) << "Driving C-Move SCU on remote modality " 651 LOG(WARNING) << "Driving C-Move SCU on remote modality "
660 << query.GetHandler().GetRemoteModality().GetApplicationEntityTitle() 652 << query.GetHandler().GetRemoteModality().GetApplicationEntityTitle()
977 std::unique_ptr<DicomModalityStoreJob> job(new DicomModalityStoreJob(context)); 969 std::unique_ptr<DicomModalityStoreJob> job(new DicomModalityStoreJob(context));
978 970
979 GetInstancesToExport(request, *job, remote, call); 971 GetInstancesToExport(request, *job, remote, call);
980 972
981 std::string localAet = Toolbox::GetJsonStringField 973 std::string localAet = Toolbox::GetJsonStringField
982 (request, "LocalAet", context.GetDefaultLocalApplicationEntityTitle()); 974 (request, KEY_LOCAL_AET, context.GetDefaultLocalApplicationEntityTitle());
983 std::string moveOriginatorAET = Toolbox::GetJsonStringField 975 std::string moveOriginatorAET = Toolbox::GetJsonStringField
984 (request, "MoveOriginatorAet", context.GetDefaultLocalApplicationEntityTitle()); 976 (request, "MoveOriginatorAet", context.GetDefaultLocalApplicationEntityTitle());
985 int moveOriginatorID = Toolbox::GetJsonIntegerField 977 int moveOriginatorID = Toolbox::GetJsonIntegerField
986 (request, "MoveOriginatorID", 0 /* By default, not a C-MOVE */); 978 (request, "MoveOriginatorID", 0 /* By default, not a C-MOVE */);
987 int timeout = Toolbox::GetJsonIntegerField
988 (request, "Timeout", -1);
989 979
990 job->SetLocalAet(localAet); 980 job->SetLocalAet(localAet);
991 job->SetRemoteModality(MyGetModalityUsingSymbolicName(remote)); 981 job->SetRemoteModality(MyGetModalityUsingSymbolicName(remote));
992 982
993 if (moveOriginatorID != 0) 983 if (moveOriginatorID != 0)
1000 { 990 {
1001 job->EnableStorageCommitment(true); 991 job->EnableStorageCommitment(true);
1002 } 992 }
1003 993
1004 // New in Orthanc 1.7.0 994 // New in Orthanc 1.7.0
1005 if (timeout >= 0) 995 if (request.isMember(KEY_TIMEOUT))
1006 { 996 {
1007 job->SetTimeout(static_cast<uint32_t>(timeout)); 997 job->SetTimeout(SerializationToolbox::ReadUnsignedInteger(request, KEY_TIMEOUT));
1008 } 998 }
1009 999
1010 OrthancRestApi::GetApi(call).SubmitCommandsJob 1000 OrthancRestApi::GetApi(call).SubmitCommandsJob
1011 (call, job.release(), true /* synchronous by default */, request); 1001 (call, job.release(), true /* synchronous by default */, request);
1012 } 1002 }
1013 1003
1014 1004
1015 static void DicomStoreStraight(RestApiPostCall& call) 1005 static void DicomStoreStraight(RestApiPostCall& call)
1016 { 1006 {
1017 ServerContext& context = OrthancRestApi::GetContext(call); 1007 Json::Value body = Json::objectValue; // No body
1018 1008 DicomStoreUserConnection connection(GetAssociationParameters(call, body));
1019 const std::string& localAet = context.GetDefaultLocalApplicationEntityTitle();
1020 RemoteModalityParameters remote =
1021 MyGetModalityUsingSymbolicName(call.GetUriComponent("id", ""));
1022
1023 DicomAssociationParameters params(localAet, remote);
1024 DicomStoreUserConnection connection(params);
1025 1009
1026 std::string sopClassUid, sopInstanceUid; 1010 std::string sopClassUid, sopInstanceUid;
1027 connection.Store(sopClassUid, sopInstanceUid, 1011 connection.Store(sopClassUid, sopInstanceUid,
1028 call.GetBodyData(), call.GetBodySize()); 1012 call.GetBodyData(), call.GetBodySize());
1029 1013
1057 } 1041 }
1058 1042
1059 ResourceType level = StringToResourceType(request[KEY_LEVEL].asCString()); 1043 ResourceType level = StringToResourceType(request[KEY_LEVEL].asCString());
1060 1044
1061 std::string localAet = Toolbox::GetJsonStringField 1045 std::string localAet = Toolbox::GetJsonStringField
1062 (request, "LocalAet", context.GetDefaultLocalApplicationEntityTitle()); 1046 (request, KEY_LOCAL_AET, context.GetDefaultLocalApplicationEntityTitle());
1063 std::string targetAet = Toolbox::GetJsonStringField 1047 std::string targetAet = Toolbox::GetJsonStringField
1064 (request, "TargetAet", context.GetDefaultLocalApplicationEntityTitle()); 1048 (request, KEY_TARGET_AET, context.GetDefaultLocalApplicationEntityTitle());
1065 int timeout = Toolbox::GetJsonIntegerField
1066 (request, "Timeout", -1);
1067 1049
1068 const RemoteModalityParameters source = 1050 const RemoteModalityParameters source =
1069 MyGetModalityUsingSymbolicName(call.GetUriComponent("id", "")); 1051 MyGetModalityUsingSymbolicName(call.GetUriComponent("id", ""));
1070 1052
1071 DicomAssociationParameters params(localAet, source); 1053 DicomAssociationParameters params(localAet, source);
1072 1054 InjectAssociationTimeout(params, request);
1073 // New in Orthanc 1.7.0
1074 if (timeout >= 0)
1075 {
1076 params.SetTimeout(static_cast<uint32_t>(timeout));
1077 }
1078 1055
1079 DicomControlUserConnection connection(params); 1056 DicomControlUserConnection connection(params);
1080 1057
1081 for (Json::Value::ArrayIndex i = 0; i < request[KEY_RESOURCES].size(); i++) 1058 for (Json::Value::ArrayIndex i = 0; i < request[KEY_RESOURCES].size(); i++)
1082 { 1059 {
1341 } 1318 }
1342 1319
1343 1320
1344 static void DicomFindWorklist(RestApiPostCall& call) 1321 static void DicomFindWorklist(RestApiPostCall& call)
1345 { 1322 {
1346 ServerContext& context = OrthancRestApi::GetContext(call);
1347
1348 Json::Value json; 1323 Json::Value json;
1349 if (call.ParseJsonRequest(json)) 1324 if (call.ParseJsonRequest(json))
1350 { 1325 {
1351 const std::string& localAet = context.GetDefaultLocalApplicationEntityTitle();
1352 const RemoteModalityParameters remote =
1353 MyGetModalityUsingSymbolicName(call.GetUriComponent("id", ""));
1354
1355 std::unique_ptr<ParsedDicomFile> query 1326 std::unique_ptr<ParsedDicomFile> query
1356 (ParsedDicomFile::CreateFromJson(json, static_cast<DicomFromJsonFlags>(0), 1327 (ParsedDicomFile::CreateFromJson(json, static_cast<DicomFromJsonFlags>(0),
1357 "" /* no private creator */)); 1328 "" /* no private creator */));
1358 1329
1359 DicomFindAnswers answers(true); 1330 DicomFindAnswers answers(true);
1360 1331
1361 { 1332 {
1362 DicomAssociationParameters params(localAet, remote); 1333 DicomControlUserConnection connection(GetAssociationParameters(call, json));
1363 DicomControlUserConnection connection(params);
1364 connection.FindWorklist(answers, *query); 1334 connection.FindWorklist(answers, *query);
1365 } 1335 }
1366 1336
1367 Json::Value result; 1337 Json::Value result;
1368 answers.ToJson(result, true); 1338 answers.ToJson(result, true);