comparison OrthancServer/Sources/OrthancRestApi/OrthancRestResources.cpp @ 5554:12d8a1a266e9 find-refactoring

introduction of FindRequest and FindResponse
author Sebastien Jodogne <s.jodogne@gmail.com>
date Mon, 15 Apr 2024 16:13:24 +0200
parents 48b8dae6dc77
children def06a42e5ef
comparison
equal deleted inserted replaced
5549:dcbf0c776945 5554:12d8a1a266e9
124 } 124 }
125 125
126 126
127 // List all the patients, studies, series or instances ---------------------- 127 // List all the patients, studies, series or instances ----------------------
128 128
129 static void AnswerListOfResources(RestApiOutput& output, 129 static void AnswerListOfResources1(RestApiOutput& output,
130 ServerContext& context, 130 ServerContext& context,
131 const std::list<std::string>& resources, 131 const std::list<std::string>& resources,
132 const std::map<std::string, std::string>& instancesIds, // optional: the id of an instance for each found resource. 132 const std::map<std::string, std::string>& instancesIds, // optional: the id of an instance for each found resource.
133 const std::map<std::string, boost::shared_ptr<DicomMap> >& resourcesMainDicomTags, // optional: all tags read from DB for a resource (current level and upper levels) 133 const std::map<std::string, boost::shared_ptr<DicomMap> >& resourcesMainDicomTags, // optional: all tags read from DB for a resource (current level and upper levels)
134 const std::map<std::string, boost::shared_ptr<Json::Value> >& resourcesDicomAsJson, // optional: the dicom-as-json for each resource 134 const std::map<std::string, boost::shared_ptr<Json::Value> >& resourcesDicomAsJson, // optional: the dicom-as-json for each resource
178 178
179 output.AnswerJson(answer); 179 output.AnswerJson(answer);
180 } 180 }
181 181
182 182
183 static void AnswerListOfResources(RestApiOutput& output, 183 static void AnswerListOfResources2(RestApiOutput& output,
184 ServerContext& context, 184 ServerContext& context,
185 const std::list<std::string>& resources, 185 const std::list<std::string>& resources,
186 ResourceType level, 186 ResourceType level,
187 bool expand, 187 bool expand,
188 DicomToJsonFormat format, 188 DicomToJsonFormat format,
191 { 191 {
192 std::map<std::string, std::string> unusedInstancesIds; 192 std::map<std::string, std::string> unusedInstancesIds;
193 std::map<std::string, boost::shared_ptr<DicomMap> > unusedResourcesMainDicomTags; 193 std::map<std::string, boost::shared_ptr<DicomMap> > unusedResourcesMainDicomTags;
194 std::map<std::string, boost::shared_ptr<Json::Value> > unusedResourcesDicomAsJson; 194 std::map<std::string, boost::shared_ptr<Json::Value> > unusedResourcesDicomAsJson;
195 195
196 AnswerListOfResources(output, context, resources, unusedInstancesIds, unusedResourcesMainDicomTags, unusedResourcesDicomAsJson, level, expand, format, requestedTags, allowStorageAccess); 196 AnswerListOfResources1(output, context, resources, unusedInstancesIds, unusedResourcesMainDicomTags, unusedResourcesDicomAsJson, level, expand, format, requestedTags, allowStorageAccess);
197 } 197 }
198 198
199 199
200 template <enum ResourceType resourceType> 200 template <enum ResourceType resourceType>
201 static void ListResources(RestApiGetCall& call) 201 static void ListResources(RestApiGetCall& call)
221 } 221 }
222 222
223 ServerIndex& index = OrthancRestApi::GetIndex(call); 223 ServerIndex& index = OrthancRestApi::GetIndex(call);
224 ServerContext& context = OrthancRestApi::GetContext(call); 224 ServerContext& context = OrthancRestApi::GetContext(call);
225 225
226 std::list<std::string> result; 226 if (true)
227 227 {
228 std::set<DicomTag> requestedTags; 228 /**
229 OrthancRestApi::GetRequestedTags(requestedTags, call); 229 * EXPERIMENTAL VERSION
230 230 **/
231 if (call.HasArgument("limit") || 231
232 call.HasArgument("since")) 232 const bool expand = (call.HasArgument("expand") &&
233 { 233 call.GetBooleanArgument("expand", true));
234 if (!call.HasArgument("limit")) 234
235 { 235 FindRequest request(resourceType);
236 throw OrthancException(ErrorCode_BadRequest, 236
237 "Missing \"limit\" argument for GET request against: " + 237 #if 0
238 call.FlattenUri()); 238 // TODO - This version should be executed if no disk access is needed
239 } 239 if (expand)
240 240 {
241 if (!call.HasArgument("since")) 241 request.SetResponseType(FindRequest::ResponseType_DicomMap);
242 { 242 request.SetMetadataMode(FindRequest::MetadataMode_Retrieve);
243 throw OrthancException(ErrorCode_BadRequest, 243 request.SetRetrieveTagsAtLevel(resourceType, true);
244 "Missing \"since\" argument for GET request against: " + 244
245 call.FlattenUri()); 245 if (resourceType == ResourceType_Study)
246 } 246 {
247 247 request.SetRetrieveTagsAtLevel(ResourceType_Patient, true);
248 size_t since = boost::lexical_cast<size_t>(call.GetArgument("since", "")); 248 }
249 size_t limit = boost::lexical_cast<size_t>(call.GetArgument("limit", "")); 249 }
250 index.GetAllUuids(result, resourceType, since, limit); 250 else
251 {
252 request.SetResponseType(FindRequest::ResponseType_OrthancIdentifiers);
253 request.SetMetadataMode(FindRequest::MetadataMode_None);
254 }
255 #else
256 request.SetResponseType(FindRequest::ResponseType_OrthancIdentifiers);
257 request.SetMetadataMode(FindRequest::MetadataMode_None);
258 #endif
259
260 if (call.HasArgument("limit") ||
261 call.HasArgument("since"))
262 {
263 if (!call.HasArgument("limit"))
264 {
265 throw OrthancException(ErrorCode_BadRequest,
266 "Missing \"limit\" argument for GET request against: " +
267 call.FlattenUri());
268 }
269
270 if (!call.HasArgument("since"))
271 {
272 throw OrthancException(ErrorCode_BadRequest,
273 "Missing \"since\" argument for GET request against: " +
274 call.FlattenUri());
275 }
276
277 uint64_t since = boost::lexical_cast<uint64_t>(call.GetArgument("since", ""));
278 uint64_t limit = boost::lexical_cast<uint64_t>(call.GetArgument("limit", ""));
279 request.SetLimits(since, limit);
280 }
281
282 FindResponse response;
283 index.ExecuteFind(response, request);
284
285 std::set<DicomTag> requestedTags;
286 OrthancRestApi::GetRequestedTags(requestedTags, call);
287
288 const DicomToJsonFormat format = OrthancRestApi::GetDicomFormat(call, DicomToJsonFormat_Human);
289
290 Json::Value answer = Json::arrayValue;
291
292 for (size_t i = 0; i < response.GetSize(); i++)
293 {
294 std::string resourceId = response.GetItem(i).GetIdentifiers().GetLevel(resourceType);
295
296 if (expand)
297 {
298 Json::Value expanded;
299
300 context.ExpandResource(expanded, resourceId, resourceType, format, requestedTags, true /* allowStorageAccess */);
301
302 if (expanded.type() == Json::objectValue)
303 {
304 answer.append(expanded);
305 }
306 else
307 {
308 throw OrthancException(ErrorCode_InternalError);
309 }
310 }
311 else
312 {
313 answer.append(resourceId);
314 }
315 }
316
317 call.GetOutput().AnswerJson(answer);
251 } 318 }
252 else 319 else
253 { 320 {
254 index.GetAllUuids(result, resourceType); 321 /**
255 } 322 * VERSION IN ORTHANC <= 1.12.3
256 323 **/
257 AnswerListOfResources(call.GetOutput(), context, result, resourceType, call.HasArgument("expand") && call.GetBooleanArgument("expand", true), 324
258 OrthancRestApi::GetDicomFormat(call, DicomToJsonFormat_Human), 325 std::list<std::string> result;
259 requestedTags, 326
260 true /* allowStorageAccess */); 327 std::set<DicomTag> requestedTags;
328 OrthancRestApi::GetRequestedTags(requestedTags, call);
329
330 if (call.HasArgument("limit") ||
331 call.HasArgument("since"))
332 {
333 if (!call.HasArgument("limit"))
334 {
335 throw OrthancException(ErrorCode_BadRequest,
336 "Missing \"limit\" argument for GET request against: " +
337 call.FlattenUri());
338 }
339
340 if (!call.HasArgument("since"))
341 {
342 throw OrthancException(ErrorCode_BadRequest,
343 "Missing \"since\" argument for GET request against: " +
344 call.FlattenUri());
345 }
346
347 size_t since = boost::lexical_cast<size_t>(call.GetArgument("since", ""));
348 size_t limit = boost::lexical_cast<size_t>(call.GetArgument("limit", ""));
349 index.GetAllUuids(result, resourceType, since, limit);
350 }
351 else
352 {
353 index.GetAllUuids(result, resourceType);
354 }
355
356 AnswerListOfResources2(call.GetOutput(), context, result, resourceType, call.HasArgument("expand") && call.GetBooleanArgument("expand", true),
357 OrthancRestApi::GetDicomFormat(call, DicomToJsonFormat_Human),
358 requestedTags,
359 true /* allowStorageAccess */);
360 }
261 } 361 }
262 362
263 363
264 364
265 template <enum ResourceType resourceType> 365 template <enum ResourceType resourceType>
3104 ServerContext& context, 3204 ServerContext& context,
3105 ResourceType level, 3205 ResourceType level,
3106 bool expand, 3206 bool expand,
3107 const std::set<DicomTag>& requestedTags) const 3207 const std::set<DicomTag>& requestedTags) const
3108 { 3208 {
3109 AnswerListOfResources(output, context, resources_, instancesIds_, resourcesMainDicomTags_, resourcesDicomAsJson_, level, expand, format_, requestedTags, IsStorageAccessAllowedForAnswers(findStorageAccessMode_)); 3209 AnswerListOfResources1(output, context, resources_, instancesIds_, resourcesMainDicomTags_, resourcesDicomAsJson_, level, expand, format_, requestedTags, IsStorageAccessAllowedForAnswers(findStorageAccessMode_));
3110 } 3210 }
3111 }; 3211 };
3112 } 3212 }
3113 3213
3114 3214
3384 3484
3385 a.clear(); 3485 a.clear();
3386 a.splice(a.begin(), b); 3486 a.splice(a.begin(), b);
3387 } 3487 }
3388 3488
3389 AnswerListOfResources(call.GetOutput(), context, a, type, !call.HasArgument("expand") || call.GetBooleanArgument("expand", false), // this "expand" is the only one to have a false default value to keep backward compatibility 3489 AnswerListOfResources2(call.GetOutput(), context, a, type, !call.HasArgument("expand") || call.GetBooleanArgument("expand", false), // this "expand" is the only one to have a false default value to keep backward compatibility
3390 OrthancRestApi::GetDicomFormat(call, DicomToJsonFormat_Human), 3490 OrthancRestApi::GetDicomFormat(call, DicomToJsonFormat_Human),
3391 requestedTags, 3491 requestedTags,
3392 true /* allowStorageAccess */); 3492 true /* allowStorageAccess */);
3393 } 3493 }
3394 3494