Mercurial > hg > orthanc
comparison OrthancServer/OrthancRestApi/OrthancRestModalities.cpp @ 1368:b22ba8c5edbe query-retrieve
query retrieve
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Tue, 26 May 2015 17:54:34 +0200 |
parents | 6e7e5ed91c2d |
children | d710ea64f0fd |
comparison
equal
deleted
inserted
replaced
1367:fe6e5a9f1ea2 | 1368:b22ba8c5edbe |
---|---|
37 #include "../../Core/HttpClient.h" | 37 #include "../../Core/HttpClient.h" |
38 #include "../FromDcmtkBridge.h" | 38 #include "../FromDcmtkBridge.h" |
39 #include "../Scheduler/ServerJob.h" | 39 #include "../Scheduler/ServerJob.h" |
40 #include "../Scheduler/StoreScuCommand.h" | 40 #include "../Scheduler/StoreScuCommand.h" |
41 #include "../Scheduler/StorePeerCommand.h" | 41 #include "../Scheduler/StorePeerCommand.h" |
42 #include "../QueryRetrieveHandler.h" | |
43 #include "../ServerToolbox.h" | |
42 | 44 |
43 #include <glog/logging.h> | 45 #include <glog/logging.h> |
44 | 46 |
45 namespace Orthanc | 47 namespace Orthanc |
46 { | 48 { |
47 // DICOM SCU ---------------------------------------------------------------- | 49 /*************************************************************************** |
48 | 50 * DICOM C-Echo SCU |
49 static bool MergeQueryAndTemplate(DicomMap& result, | 51 ***************************************************************************/ |
50 const std::string& postData) | |
51 { | |
52 Json::Value query; | |
53 Json::Reader reader; | |
54 | |
55 if (!reader.parse(postData, query) || | |
56 query.type() != Json::objectValue) | |
57 { | |
58 return false; | |
59 } | |
60 | |
61 Json::Value::Members members = query.getMemberNames(); | |
62 for (size_t i = 0; i < members.size(); i++) | |
63 { | |
64 DicomTag t = FromDcmtkBridge::ParseTag(members[i]); | |
65 result.SetValue(t, query[members[i]].asString()); | |
66 } | |
67 | |
68 return true; | |
69 } | |
70 | |
71 | 52 |
72 static void DicomEcho(RestApiPostCall& call) | 53 static void DicomEcho(RestApiPostCall& call) |
73 { | 54 { |
74 ServerContext& context = OrthancRestApi::GetContext(call); | 55 ServerContext& context = OrthancRestApi::GetContext(call); |
75 | 56 |
92 // Echo has failed | 73 // Echo has failed |
93 call.GetOutput().SignalError(HttpStatus_500_InternalServerError); | 74 call.GetOutput().SignalError(HttpStatus_500_InternalServerError); |
94 } | 75 } |
95 | 76 |
96 | 77 |
78 | |
79 /*************************************************************************** | |
80 * DICOM C-Find SCU => DEPRECATED! | |
81 ***************************************************************************/ | |
82 | |
83 static bool MergeQueryAndTemplate(DicomMap& result, | |
84 const std::string& postData) | |
85 { | |
86 Json::Value query; | |
87 Json::Reader reader; | |
88 | |
89 if (!reader.parse(postData, query) || | |
90 query.type() != Json::objectValue) | |
91 { | |
92 return false; | |
93 } | |
94 | |
95 Json::Value::Members members = query.getMemberNames(); | |
96 for (size_t i = 0; i < members.size(); i++) | |
97 { | |
98 DicomTag t = FromDcmtkBridge::ParseTag(members[i]); | |
99 result.SetValue(t, query[members[i]].asString()); | |
100 } | |
101 | |
102 return true; | |
103 } | |
104 | |
105 | |
106 static void FindPatient(DicomFindAnswers& result, | |
107 DicomUserConnection& connection, | |
108 const DicomMap& fields) | |
109 { | |
110 // Only keep the filters from "fields" that are related to the patient | |
111 DicomMap s; | |
112 fields.ExtractPatientInformation(s); | |
113 connection.Find(result, ResourceType_Patient, s); | |
114 } | |
115 | |
116 | |
117 static void FindStudy(DicomFindAnswers& result, | |
118 DicomUserConnection& connection, | |
119 const DicomMap& fields) | |
120 { | |
121 // Only keep the filters from "fields" that are related to the study | |
122 DicomMap s; | |
123 fields.ExtractStudyInformation(s); | |
124 | |
125 s.CopyTagIfExists(fields, DICOM_TAG_PATIENT_ID); | |
126 s.CopyTagIfExists(fields, DICOM_TAG_ACCESSION_NUMBER); | |
127 s.CopyTagIfExists(fields, DICOM_TAG_MODALITIES_IN_STUDY); | |
128 | |
129 connection.Find(result, ResourceType_Study, s); | |
130 } | |
131 | |
132 static void FindSeries(DicomFindAnswers& result, | |
133 DicomUserConnection& connection, | |
134 const DicomMap& fields) | |
135 { | |
136 // Only keep the filters from "fields" that are related to the series | |
137 DicomMap s; | |
138 fields.ExtractSeriesInformation(s); | |
139 | |
140 s.CopyTagIfExists(fields, DICOM_TAG_PATIENT_ID); | |
141 s.CopyTagIfExists(fields, DICOM_TAG_ACCESSION_NUMBER); | |
142 s.CopyTagIfExists(fields, DICOM_TAG_STUDY_INSTANCE_UID); | |
143 | |
144 connection.Find(result, ResourceType_Series, s); | |
145 } | |
146 | |
147 static void FindInstance(DicomFindAnswers& result, | |
148 DicomUserConnection& connection, | |
149 const DicomMap& fields) | |
150 { | |
151 // Only keep the filters from "fields" that are related to the instance | |
152 DicomMap s; | |
153 fields.ExtractInstanceInformation(s); | |
154 | |
155 s.CopyTagIfExists(fields, DICOM_TAG_PATIENT_ID); | |
156 s.CopyTagIfExists(fields, DICOM_TAG_ACCESSION_NUMBER); | |
157 s.CopyTagIfExists(fields, DICOM_TAG_STUDY_INSTANCE_UID); | |
158 s.CopyTagIfExists(fields, DICOM_TAG_SERIES_INSTANCE_UID); | |
159 | |
160 connection.Find(result, ResourceType_Instance, s); | |
161 } | |
162 | |
163 | |
97 static void DicomFindPatient(RestApiPostCall& call) | 164 static void DicomFindPatient(RestApiPostCall& call) |
98 { | 165 { |
99 ServerContext& context = OrthancRestApi::GetContext(call); | 166 LOG(WARNING) << "This URI is deprecated: " << call.FlattenUri(); |
100 | 167 ServerContext& context = OrthancRestApi::GetContext(call); |
101 DicomMap m; | 168 |
102 DicomMap::SetupFindPatientTemplate(m); | 169 DicomMap fields; |
103 if (!MergeQueryAndTemplate(m, call.GetPostBody())) | 170 DicomMap::SetupFindPatientTemplate(fields); |
171 if (!MergeQueryAndTemplate(fields, call.GetPostBody())) | |
104 { | 172 { |
105 return; | 173 return; |
106 } | 174 } |
107 | 175 |
108 RemoteModalityParameters remote = Configuration::GetModalityUsingSymbolicName(call.GetUriComponent("id", "")); | 176 RemoteModalityParameters remote = Configuration::GetModalityUsingSymbolicName(call.GetUriComponent("id", "")); |
109 ReusableDicomUserConnection::Locker locker(context.GetReusableDicomUserConnection(), remote); | 177 ReusableDicomUserConnection::Locker locker(context.GetReusableDicomUserConnection(), remote); |
110 | 178 |
111 DicomFindAnswers answers; | 179 DicomFindAnswers answers; |
112 locker.GetConnection().FindPatient(answers, m); | 180 FindPatient(answers, locker.GetConnection(), fields); |
113 | 181 |
114 Json::Value result; | 182 Json::Value result; |
115 answers.ToJson(result); | 183 answers.ToJson(result, true); |
116 call.GetOutput().AnswerJson(result); | 184 call.GetOutput().AnswerJson(result); |
117 } | 185 } |
118 | 186 |
119 static void DicomFindStudy(RestApiPostCall& call) | 187 static void DicomFindStudy(RestApiPostCall& call) |
120 { | 188 { |
121 ServerContext& context = OrthancRestApi::GetContext(call); | 189 LOG(WARNING) << "This URI is deprecated: " << call.FlattenUri(); |
122 | 190 ServerContext& context = OrthancRestApi::GetContext(call); |
123 DicomMap m; | 191 |
124 DicomMap::SetupFindStudyTemplate(m); | 192 DicomMap fields; |
125 if (!MergeQueryAndTemplate(m, call.GetPostBody())) | 193 DicomMap::SetupFindStudyTemplate(fields); |
126 { | 194 if (!MergeQueryAndTemplate(fields, call.GetPostBody())) |
127 return; | 195 { |
128 } | 196 return; |
129 | 197 } |
130 if (m.GetValue(DICOM_TAG_ACCESSION_NUMBER).AsString().size() <= 2 && | 198 |
131 m.GetValue(DICOM_TAG_PATIENT_ID).AsString().size() <= 2) | 199 if (fields.GetValue(DICOM_TAG_ACCESSION_NUMBER).AsString().size() <= 2 && |
200 fields.GetValue(DICOM_TAG_PATIENT_ID).AsString().size() <= 2) | |
132 { | 201 { |
133 return; | 202 return; |
134 } | 203 } |
135 | 204 |
136 RemoteModalityParameters remote = Configuration::GetModalityUsingSymbolicName(call.GetUriComponent("id", "")); | 205 RemoteModalityParameters remote = Configuration::GetModalityUsingSymbolicName(call.GetUriComponent("id", "")); |
137 ReusableDicomUserConnection::Locker locker(context.GetReusableDicomUserConnection(), remote); | 206 ReusableDicomUserConnection::Locker locker(context.GetReusableDicomUserConnection(), remote); |
138 | 207 |
139 DicomFindAnswers answers; | 208 DicomFindAnswers answers; |
140 locker.GetConnection().FindStudy(answers, m); | 209 FindStudy(answers, locker.GetConnection(), fields); |
141 | 210 |
142 Json::Value result; | 211 Json::Value result; |
143 answers.ToJson(result); | 212 answers.ToJson(result, true); |
144 call.GetOutput().AnswerJson(result); | 213 call.GetOutput().AnswerJson(result); |
145 } | 214 } |
146 | 215 |
147 static void DicomFindSeries(RestApiPostCall& call) | 216 static void DicomFindSeries(RestApiPostCall& call) |
148 { | 217 { |
149 ServerContext& context = OrthancRestApi::GetContext(call); | 218 LOG(WARNING) << "This URI is deprecated: " << call.FlattenUri(); |
150 | 219 ServerContext& context = OrthancRestApi::GetContext(call); |
151 DicomMap m; | 220 |
152 DicomMap::SetupFindSeriesTemplate(m); | 221 DicomMap fields; |
153 if (!MergeQueryAndTemplate(m, call.GetPostBody())) | 222 DicomMap::SetupFindSeriesTemplate(fields); |
154 { | 223 if (!MergeQueryAndTemplate(fields, call.GetPostBody())) |
155 return; | 224 { |
156 } | 225 return; |
157 | 226 } |
158 if ((m.GetValue(DICOM_TAG_ACCESSION_NUMBER).AsString().size() <= 2 && | 227 |
159 m.GetValue(DICOM_TAG_PATIENT_ID).AsString().size() <= 2) || | 228 if ((fields.GetValue(DICOM_TAG_ACCESSION_NUMBER).AsString().size() <= 2 && |
160 m.GetValue(DICOM_TAG_STUDY_INSTANCE_UID).AsString().size() <= 2) | 229 fields.GetValue(DICOM_TAG_PATIENT_ID).AsString().size() <= 2) || |
230 fields.GetValue(DICOM_TAG_STUDY_INSTANCE_UID).AsString().size() <= 2) | |
161 { | 231 { |
162 return; | 232 return; |
163 } | 233 } |
164 | 234 |
165 RemoteModalityParameters remote = Configuration::GetModalityUsingSymbolicName(call.GetUriComponent("id", "")); | 235 RemoteModalityParameters remote = Configuration::GetModalityUsingSymbolicName(call.GetUriComponent("id", "")); |
166 ReusableDicomUserConnection::Locker locker(context.GetReusableDicomUserConnection(), remote); | 236 ReusableDicomUserConnection::Locker locker(context.GetReusableDicomUserConnection(), remote); |
167 | 237 |
168 DicomFindAnswers answers; | 238 DicomFindAnswers answers; |
169 locker.GetConnection().FindSeries(answers, m); | 239 FindSeries(answers, locker.GetConnection(), fields); |
170 | 240 |
171 Json::Value result; | 241 Json::Value result; |
172 answers.ToJson(result); | 242 answers.ToJson(result, true); |
173 call.GetOutput().AnswerJson(result); | 243 call.GetOutput().AnswerJson(result); |
174 } | 244 } |
175 | 245 |
176 static void DicomFindInstance(RestApiPostCall& call) | 246 static void DicomFindInstance(RestApiPostCall& call) |
177 { | 247 { |
178 ServerContext& context = OrthancRestApi::GetContext(call); | 248 LOG(WARNING) << "This URI is deprecated: " << call.FlattenUri(); |
179 | 249 ServerContext& context = OrthancRestApi::GetContext(call); |
180 DicomMap m; | 250 |
181 DicomMap::SetupFindInstanceTemplate(m); | 251 DicomMap fields; |
182 if (!MergeQueryAndTemplate(m, call.GetPostBody())) | 252 DicomMap::SetupFindInstanceTemplate(fields); |
183 { | 253 if (!MergeQueryAndTemplate(fields, call.GetPostBody())) |
184 return; | 254 { |
185 } | 255 return; |
186 | 256 } |
187 if ((m.GetValue(DICOM_TAG_ACCESSION_NUMBER).AsString().size() <= 2 && | 257 |
188 m.GetValue(DICOM_TAG_PATIENT_ID).AsString().size() <= 2) || | 258 if ((fields.GetValue(DICOM_TAG_ACCESSION_NUMBER).AsString().size() <= 2 && |
189 m.GetValue(DICOM_TAG_STUDY_INSTANCE_UID).AsString().size() <= 2 || | 259 fields.GetValue(DICOM_TAG_PATIENT_ID).AsString().size() <= 2) || |
190 m.GetValue(DICOM_TAG_SERIES_INSTANCE_UID).AsString().size() <= 2) | 260 fields.GetValue(DICOM_TAG_STUDY_INSTANCE_UID).AsString().size() <= 2 || |
261 fields.GetValue(DICOM_TAG_SERIES_INSTANCE_UID).AsString().size() <= 2) | |
191 { | 262 { |
192 return; | 263 return; |
193 } | 264 } |
194 | 265 |
195 RemoteModalityParameters remote = Configuration::GetModalityUsingSymbolicName(call.GetUriComponent("id", "")); | 266 RemoteModalityParameters remote = Configuration::GetModalityUsingSymbolicName(call.GetUriComponent("id", "")); |
196 ReusableDicomUserConnection::Locker locker(context.GetReusableDicomUserConnection(), remote); | 267 ReusableDicomUserConnection::Locker locker(context.GetReusableDicomUserConnection(), remote); |
197 | 268 |
198 DicomFindAnswers answers; | 269 DicomFindAnswers answers; |
199 locker.GetConnection().FindInstance(answers, m); | 270 FindInstance(answers, locker.GetConnection(), fields); |
200 | 271 |
201 Json::Value result; | 272 Json::Value result; |
202 answers.ToJson(result); | 273 answers.ToJson(result, true); |
203 call.GetOutput().AnswerJson(result); | 274 call.GetOutput().AnswerJson(result); |
204 } | 275 } |
205 | 276 |
277 | |
206 static void DicomFind(RestApiPostCall& call) | 278 static void DicomFind(RestApiPostCall& call) |
207 { | 279 { |
280 LOG(WARNING) << "This URI is deprecated: " << call.FlattenUri(); | |
208 ServerContext& context = OrthancRestApi::GetContext(call); | 281 ServerContext& context = OrthancRestApi::GetContext(call); |
209 | 282 |
210 DicomMap m; | 283 DicomMap m; |
211 DicomMap::SetupFindPatientTemplate(m); | 284 DicomMap::SetupFindPatientTemplate(m); |
212 if (!MergeQueryAndTemplate(m, call.GetPostBody())) | 285 if (!MergeQueryAndTemplate(m, call.GetPostBody())) |
216 | 289 |
217 RemoteModalityParameters remote = Configuration::GetModalityUsingSymbolicName(call.GetUriComponent("id", "")); | 290 RemoteModalityParameters remote = Configuration::GetModalityUsingSymbolicName(call.GetUriComponent("id", "")); |
218 ReusableDicomUserConnection::Locker locker(context.GetReusableDicomUserConnection(), remote); | 291 ReusableDicomUserConnection::Locker locker(context.GetReusableDicomUserConnection(), remote); |
219 | 292 |
220 DicomFindAnswers patients; | 293 DicomFindAnswers patients; |
221 locker.GetConnection().FindPatient(patients, m); | 294 FindPatient(patients, locker.GetConnection(), m); |
222 | 295 |
223 // Loop over the found patients | 296 // Loop over the found patients |
224 Json::Value result = Json::arrayValue; | 297 Json::Value result = Json::arrayValue; |
225 for (size_t i = 0; i < patients.GetSize(); i++) | 298 for (size_t i = 0; i < patients.GetSize(); i++) |
226 { | 299 { |
227 Json::Value patient(Json::objectValue); | 300 Json::Value patient(Json::objectValue); |
228 FromDcmtkBridge::ToJson(patient, patients.GetAnswer(i)); | 301 FromDcmtkBridge::ToJson(patient, patients.GetAnswer(i), true); |
229 | 302 |
230 DicomMap::SetupFindStudyTemplate(m); | 303 DicomMap::SetupFindStudyTemplate(m); |
231 if (!MergeQueryAndTemplate(m, call.GetPostBody())) | 304 if (!MergeQueryAndTemplate(m, call.GetPostBody())) |
232 { | 305 { |
233 return; | 306 return; |
234 } | 307 } |
235 m.CopyTagIfExists(patients.GetAnswer(i), DICOM_TAG_PATIENT_ID); | 308 m.CopyTagIfExists(patients.GetAnswer(i), DICOM_TAG_PATIENT_ID); |
236 | 309 |
237 DicomFindAnswers studies; | 310 DicomFindAnswers studies; |
238 locker.GetConnection().FindStudy(studies, m); | 311 FindStudy(studies, locker.GetConnection(), m); |
239 | 312 |
240 patient["Studies"] = Json::arrayValue; | 313 patient["Studies"] = Json::arrayValue; |
241 | 314 |
242 // Loop over the found studies | 315 // Loop over the found studies |
243 for (size_t j = 0; j < studies.GetSize(); j++) | 316 for (size_t j = 0; j < studies.GetSize(); j++) |
244 { | 317 { |
245 Json::Value study(Json::objectValue); | 318 Json::Value study(Json::objectValue); |
246 FromDcmtkBridge::ToJson(study, studies.GetAnswer(j)); | 319 FromDcmtkBridge::ToJson(study, studies.GetAnswer(j), true); |
247 | 320 |
248 DicomMap::SetupFindSeriesTemplate(m); | 321 DicomMap::SetupFindSeriesTemplate(m); |
249 if (!MergeQueryAndTemplate(m, call.GetPostBody())) | 322 if (!MergeQueryAndTemplate(m, call.GetPostBody())) |
250 { | 323 { |
251 return; | 324 return; |
252 } | 325 } |
253 m.CopyTagIfExists(studies.GetAnswer(j), DICOM_TAG_PATIENT_ID); | 326 m.CopyTagIfExists(studies.GetAnswer(j), DICOM_TAG_PATIENT_ID); |
254 m.CopyTagIfExists(studies.GetAnswer(j), DICOM_TAG_STUDY_INSTANCE_UID); | 327 m.CopyTagIfExists(studies.GetAnswer(j), DICOM_TAG_STUDY_INSTANCE_UID); |
255 | 328 |
256 DicomFindAnswers series; | 329 DicomFindAnswers series; |
257 locker.GetConnection().FindSeries(series, m); | 330 FindSeries(series, locker.GetConnection(), m); |
258 | 331 |
259 // Loop over the found series | 332 // Loop over the found series |
260 study["Series"] = Json::arrayValue; | 333 study["Series"] = Json::arrayValue; |
261 for (size_t k = 0; k < series.GetSize(); k++) | 334 for (size_t k = 0; k < series.GetSize(); k++) |
262 { | 335 { |
263 Json::Value series2(Json::objectValue); | 336 Json::Value series2(Json::objectValue); |
264 FromDcmtkBridge::ToJson(series2, series.GetAnswer(k)); | 337 FromDcmtkBridge::ToJson(series2, series.GetAnswer(k), true); |
265 study["Series"].append(series2); | 338 study["Series"].append(series2); |
266 } | 339 } |
267 | 340 |
268 patient["Studies"].append(study); | 341 patient["Studies"].append(study); |
269 } | 342 } |
272 } | 345 } |
273 | 346 |
274 call.GetOutput().AnswerJson(result); | 347 call.GetOutput().AnswerJson(result); |
275 } | 348 } |
276 | 349 |
350 | |
351 | |
352 /*************************************************************************** | |
353 * DICOM C-Find and C-Move SCU => Recommended since Orthanc 0.9.0 | |
354 ***************************************************************************/ | |
355 | |
356 static void DicomQuery(RestApiPostCall& call) | |
357 { | |
358 ServerContext& context = OrthancRestApi::GetContext(call); | |
359 Json::Value request; | |
360 | |
361 if (call.ParseJsonRequest(request) && | |
362 request.type() == Json::objectValue && | |
363 request.isMember("Level") && request["Level"].type() == Json::stringValue && | |
364 (!request.isMember("Query") || request["Query"].type() == Json::objectValue)) | |
365 { | |
366 std::auto_ptr<QueryRetrieveHandler> handler(new QueryRetrieveHandler(context)); | |
367 | |
368 handler->SetModality(call.GetUriComponent("id", "")); | |
369 handler->SetLevel(StringToResourceType(request["Level"].asString().c_str())); | |
370 | |
371 if (request.isMember("Query")) | |
372 { | |
373 Json::Value::Members tags = request["Query"].getMemberNames(); | |
374 for (size_t i = 0; i < tags.size(); i++) | |
375 { | |
376 handler->SetQuery(FromDcmtkBridge::ParseTag(tags[i].c_str()), | |
377 request["Query"][tags[i]].asString()); | |
378 } | |
379 } | |
380 | |
381 handler->Run(); | |
382 | |
383 std::string s = context.GetQueryRetrieveArchive().Add(handler.release()); | |
384 Json::Value result = Json::objectValue; | |
385 result["ID"] = s; | |
386 result["Path"] = "/queries/" + s; | |
387 call.GetOutput().AnswerJson(result); | |
388 } | |
389 } | |
390 | |
391 | |
392 static void ListQueries(RestApiGetCall& call) | |
393 { | |
394 ServerContext& context = OrthancRestApi::GetContext(call); | |
395 | |
396 std::list<std::string> queries; | |
397 context.GetQueryRetrieveArchive().List(queries); | |
398 | |
399 Json::Value result = Json::arrayValue; | |
400 for (std::list<std::string>::const_iterator | |
401 it = queries.begin(); it != queries.end(); ++it) | |
402 { | |
403 result.append(*it); | |
404 } | |
405 | |
406 call.GetOutput().AnswerJson(result); | |
407 } | |
408 | |
409 | |
410 namespace | |
411 { | |
412 class QueryAccessor | |
413 { | |
414 private: | |
415 ServerContext& context_; | |
416 SharedArchive::Accessor accessor_; | |
417 QueryRetrieveHandler& handler_; | |
418 | |
419 public: | |
420 QueryAccessor(RestApiCall& call) : | |
421 context_(OrthancRestApi::GetContext(call)), | |
422 accessor_(context_.GetQueryRetrieveArchive(), call.GetUriComponent("id", "")), | |
423 handler_(dynamic_cast<QueryRetrieveHandler&>(accessor_.GetItem())) | |
424 { | |
425 } | |
426 | |
427 QueryRetrieveHandler* operator->() | |
428 { | |
429 return &handler_; | |
430 } | |
431 }; | |
432 | |
433 static void AnswerDicomMap(RestApiCall& call, | |
434 const DicomMap& value, | |
435 bool simplify) | |
436 { | |
437 Json::Value full = Json::objectValue; | |
438 FromDcmtkBridge::ToJson(full, value, simplify); | |
439 call.GetOutput().AnswerJson(full); | |
440 } | |
441 } | |
442 | |
443 | |
444 static void ListQueryAnswers(RestApiGetCall& call) | |
445 { | |
446 QueryAccessor query(call); | |
447 size_t count = query->GetAnswerCount(); | |
448 | |
449 Json::Value result = Json::arrayValue; | |
450 for (size_t i = 0; i < count; i++) | |
451 { | |
452 result.append(boost::lexical_cast<std::string>(i)); | |
453 } | |
454 | |
455 call.GetOutput().AnswerJson(result); | |
456 } | |
457 | |
458 | |
459 static void GetQueryOneAnswer(RestApiGetCall& call) | |
460 { | |
461 size_t index = boost::lexical_cast<size_t>(call.GetUriComponent("index", "")); | |
462 QueryAccessor query(call); | |
463 AnswerDicomMap(call, query->GetAnswer(index), call.HasArgument("simplify")); | |
464 } | |
465 | |
466 | |
467 static void RetrieveOneAnswer(RestApiPostCall& call) | |
468 { | |
469 size_t index = boost::lexical_cast<size_t>(call.GetUriComponent("index", "")); | |
470 | |
471 LOG(WARNING) << "Driving C-Move SCU on modality: " << call.GetPostBody(); | |
472 | |
473 QueryAccessor query(call); | |
474 query->Retrieve(call.GetPostBody(), index); | |
475 | |
476 // Retrieve has succeeded | |
477 call.GetOutput().AnswerBuffer("{}", "application/json"); | |
478 } | |
479 | |
480 | |
481 static void RetrieveAllAnswers(RestApiPostCall& call) | |
482 { | |
483 LOG(WARNING) << "Driving C-Move SCU on modality: " << call.GetPostBody(); | |
484 | |
485 QueryAccessor query(call); | |
486 query->Retrieve(call.GetPostBody()); | |
487 | |
488 // Retrieve has succeeded | |
489 call.GetOutput().AnswerBuffer("{}", "application/json"); | |
490 } | |
491 | |
492 | |
493 static void GetQueryArguments(RestApiGetCall& call) | |
494 { | |
495 QueryAccessor query(call); | |
496 AnswerDicomMap(call, query->GetQuery(), call.HasArgument("simplify")); | |
497 } | |
498 | |
499 | |
500 static void GetQueryLevel(RestApiGetCall& call) | |
501 { | |
502 QueryAccessor query(call); | |
503 call.GetOutput().AnswerBuffer(EnumerationToString(query->GetLevel()), "text/plain"); | |
504 } | |
505 | |
506 | |
507 static void GetQueryModality(RestApiGetCall& call) | |
508 { | |
509 QueryAccessor query(call); | |
510 call.GetOutput().AnswerBuffer(query->GetModalitySymbolicName(), "text/plain"); | |
511 } | |
512 | |
513 | |
514 static void DeleteQuery(RestApiDeleteCall& call) | |
515 { | |
516 ServerContext& context = OrthancRestApi::GetContext(call); | |
517 context.GetQueryRetrieveArchive().Remove(call.GetUriComponent("id", "")); | |
518 call.GetOutput().AnswerBuffer("", "text/plain"); | |
519 } | |
520 | |
521 | |
522 static void ListQueryOperations(RestApiGetCall& call) | |
523 { | |
524 // Ensure that the query of interest does exist | |
525 QueryAccessor query(call); | |
526 | |
527 RestApi::AutoListChildren(call); | |
528 } | |
529 | |
530 | |
531 static void ListQueryAnswerOperations(RestApiGetCall& call) | |
532 { | |
533 // Ensure that the query of interest does exist | |
534 QueryAccessor query(call); | |
535 | |
536 // Ensure that the answer of interest does exist | |
537 size_t index = boost::lexical_cast<size_t>(call.GetUriComponent("index", "")); | |
538 query->GetAnswer(index); | |
539 | |
540 RestApi::AutoListChildren(call); | |
541 } | |
542 | |
543 | |
544 | |
545 | |
546 /*************************************************************************** | |
547 * DICOM C-Store SCU | |
548 ***************************************************************************/ | |
277 | 549 |
278 static bool GetInstancesToExport(std::list<std::string>& instances, | 550 static bool GetInstancesToExport(std::list<std::string>& instances, |
279 const std::string& remote, | 551 const std::string& remote, |
280 RestApiPostCall& call) | 552 RestApiPostCall& call) |
281 { | 553 { |
377 call.GetOutput().SignalError(HttpStatus_500_InternalServerError); | 649 call.GetOutput().SignalError(HttpStatus_500_InternalServerError); |
378 } | 650 } |
379 } | 651 } |
380 | 652 |
381 | 653 |
382 // Orthanc Peers ------------------------------------------------------------ | 654 /*************************************************************************** |
655 * Orthanc Peers => Store client | |
656 ***************************************************************************/ | |
383 | 657 |
384 static bool IsExistingPeer(const OrthancRestApi::SetOfStrings& peers, | 658 static bool IsExistingPeer(const OrthancRestApi::SetOfStrings& peers, |
385 const std::string& id) | 659 const std::string& id) |
386 { | 660 { |
387 return peers.find(id) != peers.end(); | 661 return peers.find(id) != peers.end(); |
541 Register("/modalities/{id}/find-series", DicomFindSeries); | 815 Register("/modalities/{id}/find-series", DicomFindSeries); |
542 Register("/modalities/{id}/find-instance", DicomFindInstance); | 816 Register("/modalities/{id}/find-instance", DicomFindInstance); |
543 Register("/modalities/{id}/find", DicomFind); | 817 Register("/modalities/{id}/find", DicomFind); |
544 Register("/modalities/{id}/store", DicomStore); | 818 Register("/modalities/{id}/store", DicomStore); |
545 | 819 |
820 // For Query/Retrieve | |
821 Register("/modalities/{id}/query", DicomQuery); | |
822 Register("/queries", ListQueries); | |
823 Register("/queries/{id}", DeleteQuery); | |
824 Register("/queries/{id}", ListQueryOperations); | |
825 Register("/queries/{id}/answers", ListQueryAnswers); | |
826 Register("/queries/{id}/answers/{index}", ListQueryAnswerOperations); | |
827 Register("/queries/{id}/answers/{index}/content", GetQueryOneAnswer); | |
828 Register("/queries/{id}/answers/{index}/retrieve", RetrieveOneAnswer); | |
829 Register("/queries/{id}/level", GetQueryLevel); | |
830 Register("/queries/{id}/modality", GetQueryModality); | |
831 Register("/queries/{id}/query", GetQueryArguments); | |
832 Register("/queries/{id}/retrieve", RetrieveAllAnswers); | |
833 | |
546 Register("/peers", ListPeers); | 834 Register("/peers", ListPeers); |
547 Register("/peers/{id}", ListPeerOperations); | 835 Register("/peers/{id}", ListPeerOperations); |
548 Register("/peers/{id}", UpdatePeer); | 836 Register("/peers/{id}", UpdatePeer); |
549 Register("/peers/{id}", DeletePeer); | 837 Register("/peers/{id}", DeletePeer); |
550 Register("/peers/{id}/store", PeerStore); | 838 Register("/peers/{id}/store", PeerStore); |