Mercurial > hg > orthanc
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); |