comparison OrthancServer/OrthancRestApi/OrthancRestModalities.cpp @ 2584:38b5045f2bff jobs

refactoring
author Sebastien Jodogne <s.jodogne@gmail.com>
date Mon, 14 May 2018 21:15:28 +0200
parents 1b6a6d80b6f2
children 4c809711149e
comparison
equal deleted inserted replaced
2583:1b6a6d80b6f2 2584:38b5045f2bff
202 bool ok; 202 bool ok;
203 203
204 try 204 try
205 { 205 {
206 ok = HandleInstance(GetCurrentInstance()); 206 ok = HandleInstance(GetCurrentInstance());
207
208 if (!ok && !permissive_)
209 {
210 throw OrthancException(ErrorCode_InternalError);
211 }
207 } 212 }
208 catch (OrthancException& e) 213 catch (OrthancException& e)
209 {
210 ok = false;
211 }
212
213 if (!ok)
214 { 214 {
215 if (permissive_) 215 if (permissive_)
216 { 216 {
217 failedInstances_.insert(GetCurrentInstance()); 217 ok = false;
218 } 218 }
219 else 219 else
220 { 220 {
221 return new JobStepResult(JobStepCode_Failure); 221 throw;
222 } 222 }
223 }
224
225 if (!ok)
226 {
227 failedInstances_.insert(GetCurrentInstance());
223 } 228 }
224 229
225 Next(); 230 Next();
226 231
227 if (IsDone()) 232 if (IsDone())
429 std::auto_ptr<HttpClient> client_; 434 std::auto_ptr<HttpClient> client_;
430 435
431 protected: 436 protected:
432 virtual bool HandleInstance(const std::string& instance) 437 virtual bool HandleInstance(const std::string& instance)
433 { 438 {
439 boost::this_thread::sleep(boost::posix_time::milliseconds(500));
440
434 if (client_.get() == NULL) 441 if (client_.get() == NULL)
435 { 442 {
436 client_.reset(new HttpClient(peer_, "instances")); 443 client_.reset(new HttpClient(peer_, "instances"));
437 client_->SetMethod(HttpMethod_Post); 444 client_->SetMethod(HttpMethod_Post);
438 } 445 }
441 << peer_.GetUrl() << "\""; 448 << peer_.GetUrl() << "\"";
442 449
443 context_.ReadDicom(client_->GetBody(), GetCurrentInstance()); 450 context_.ReadDicom(client_->GetBody(), GetCurrentInstance());
444 451
445 std::string answer; 452 std::string answer;
446 return client_->Apply(answer); 453 if (client_->Apply(answer))
454 {
455 return true;
456 }
457 else
458 {
459 throw OrthancException(ErrorCode_NetworkProtocol);
460 }
447 } 461 }
448 462
449 public: 463 public:
450 OrthancPeerStoreJob(ServerContext& context) : 464 OrthancPeerStoreJob(ServerContext& context) :
451 context_(context) 465 context_(context)
452 { 466 {
467 }
468
469 void SetPeer(const WebServiceParameters& peer)
470 {
471 if (IsStarted())
472 {
473 throw OrthancException(ErrorCode_BadSequenceOfCalls);
474 }
475 else
476 {
477 peer_ = peer;
478 }
453 } 479 }
454 480
455 const WebServiceParameters& GetPeer() const 481 const WebServiceParameters& GetPeer() const
456 { 482 {
457 return peer_; 483 return peer_;
1107 1133
1108 return true; 1134 return true;
1109 } 1135 }
1110 1136
1111 1137
1138 static void SubmitJob(RestApiPostCall& call,
1139 const Json::Value& request,
1140 const std::list<std::string>& instances,
1141 SetOfInstancesJob* jobRaw)
1142 {
1143 std::auto_ptr<SetOfInstancesJob> job(jobRaw);
1144
1145 if (job.get() == NULL)
1146 {
1147 throw OrthancException(ErrorCode_NullPointer);
1148 }
1149
1150 ServerContext& context = OrthancRestApi::GetContext(call);
1151
1152 bool permissive = Toolbox::GetJsonBooleanField(request, "Permissive", false);
1153 bool asynchronous = Toolbox::GetJsonBooleanField(request, "Asynchronous", false);
1154 int priority = Toolbox::GetJsonIntegerField(request, "Priority", 0);
1155
1156 job->SetPermissive(permissive);
1157 job->Reserve(instances.size());
1158
1159 for (std::list<std::string>::const_iterator
1160 it = instances.begin(); it != instances.end(); ++it)
1161 {
1162 job->AddInstance(*it);
1163 }
1164
1165 if (asynchronous)
1166 {
1167 // Asynchronous mode: Submit the job, but don't wait for its completion
1168 std::string id;
1169 context.GetJobsEngine().GetRegistry().Submit(id, job.release(), priority);
1170
1171 Json::Value v;
1172 v["ID"] = id;
1173 call.GetOutput().AnswerJson(v);
1174 }
1175 else if (context.GetJobsEngine().GetRegistry().SubmitAndWait(job.release(), priority))
1176 {
1177 // Synchronous mode: We have submitted and waited for completion
1178 call.GetOutput().AnswerBuffer("{}", "application/json");
1179 }
1180 else
1181 {
1182 call.GetOutput().SignalError(HttpStatus_500_InternalServerError);
1183 }
1184 }
1185
1186
1112 static void DicomStore(RestApiPostCall& call) 1187 static void DicomStore(RestApiPostCall& call)
1113 { 1188 {
1114 ServerContext& context = OrthancRestApi::GetContext(call); 1189 ServerContext& context = OrthancRestApi::GetContext(call);
1115 1190
1116 std::string remote = call.GetUriComponent("id", ""); 1191 std::string remote = call.GetUriComponent("id", "");
1120 if (!GetInstancesToExport(request, instances, remote, call)) 1195 if (!GetInstancesToExport(request, instances, remote, call))
1121 { 1196 {
1122 return; 1197 return;
1123 } 1198 }
1124 1199
1125 std::string localAet = Toolbox::GetJsonStringField(request, "LocalAet", context.GetDefaultLocalApplicationEntityTitle()); 1200 std::string localAet = Toolbox::GetJsonStringField
1126 bool permissive = Toolbox::GetJsonBooleanField(request, "Permissive", false); 1201 (request, "LocalAet", context.GetDefaultLocalApplicationEntityTitle());
1127 bool asynchronous = Toolbox::GetJsonBooleanField(request, "Asynchronous", false); 1202 std::string moveOriginatorAET = Toolbox::GetJsonStringField
1128 std::string moveOriginatorAET = Toolbox::GetJsonStringField(request, "MoveOriginatorAet", context.GetDefaultLocalApplicationEntityTitle()); 1203 (request, "MoveOriginatorAet", context.GetDefaultLocalApplicationEntityTitle());
1129 int moveOriginatorID = Toolbox::GetJsonIntegerField(request, "MoveOriginatorID", 0 /* By default, not a C-MOVE */); 1204 int moveOriginatorID = Toolbox::GetJsonIntegerField
1130 int priority = Toolbox::GetJsonIntegerField(request, "Priority", 0); 1205 (request, "MoveOriginatorID", 0 /* By default, not a C-MOVE */);
1131 1206
1132 RemoteModalityParameters p = Configuration::GetModalityUsingSymbolicName(remote); 1207 RemoteModalityParameters p = Configuration::GetModalityUsingSymbolicName(remote);
1133 1208
1134 std::auto_ptr<DicomStoreJob> job(new DicomStoreJob(context)); 1209 std::auto_ptr<DicomStoreJob> job(new DicomStoreJob(context));
1135 job->SetLocalAet(localAet); 1210 job->SetLocalAet(localAet);
1136 job->SetRemoteModality(p); 1211 job->SetRemoteModality(p);
1137 job->SetPermissive(permissive);
1138 1212
1139 if (moveOriginatorID != 0) 1213 if (moveOriginatorID != 0)
1140 { 1214 {
1141 job->SetMoveOriginator(moveOriginatorAET, moveOriginatorID); 1215 job->SetMoveOriginator(moveOriginatorAET, moveOriginatorID);
1142 } 1216 }
1143 1217
1144 job->Reserve(instances.size()); 1218 SubmitJob(call, request, instances, job.release());
1145
1146 for (std::list<std::string>::const_iterator
1147 it = instances.begin(); it != instances.end(); ++it)
1148 {
1149 job->AddInstance(*it);
1150 }
1151
1152 if (asynchronous)
1153 {
1154 // Asynchronous mode: Submit the job, but don't wait for its completion
1155 std::string id;
1156 context.GetJobsEngine().GetRegistry().Submit(id, job.release(), priority);
1157
1158 Json::Value v;
1159 v["ID"] = id;
1160 call.GetOutput().AnswerJson(v);
1161 }
1162 else if (context.GetJobsEngine().GetRegistry().SubmitAndWait(job.release(), priority))
1163 {
1164 // Synchronous mode: We have submitted and waited for completion
1165 call.GetOutput().AnswerBuffer("{}", "application/json");
1166 }
1167 else
1168 {
1169 call.GetOutput().SignalError(HttpStatus_500_InternalServerError);
1170 }
1171 } 1219 }
1172 1220
1173 1221
1174 /*************************************************************************** 1222 /***************************************************************************
1175 * DICOM C-Move SCU 1223 * DICOM C-Move SCU
1194 throw OrthancException(ErrorCode_BadFileFormat); 1242 throw OrthancException(ErrorCode_BadFileFormat);
1195 } 1243 }
1196 1244
1197 ResourceType level = StringToResourceType(request["Level"].asCString()); 1245 ResourceType level = StringToResourceType(request["Level"].asCString());
1198 1246
1199 std::string localAet = Toolbox::GetJsonStringField(request, "LocalAet", context.GetDefaultLocalApplicationEntityTitle()); 1247 std::string localAet = Toolbox::GetJsonStringField
1200 std::string targetAet = Toolbox::GetJsonStringField(request, "TargetAet", context.GetDefaultLocalApplicationEntityTitle()); 1248 (request, "LocalAet", context.GetDefaultLocalApplicationEntityTitle());
1249 std::string targetAet = Toolbox::GetJsonStringField
1250 (request, "TargetAet", context.GetDefaultLocalApplicationEntityTitle());
1201 1251
1202 const RemoteModalityParameters source = Configuration::GetModalityUsingSymbolicName(call.GetUriComponent("id", "")); 1252 const RemoteModalityParameters source = Configuration::GetModalityUsingSymbolicName(call.GetUriComponent("id", ""));
1203 1253
1204 for (Json::Value::ArrayIndex i = 0; i < request[RESOURCES].size(); i++) 1254 for (Json::Value::ArrayIndex i = 0; i < request[RESOURCES].size(); i++)
1205 { 1255 {
1287 if (!GetInstancesToExport(request, instances, remote, call)) 1337 if (!GetInstancesToExport(request, instances, remote, call))
1288 { 1338 {
1289 return; 1339 return;
1290 } 1340 }
1291 1341
1292 bool asynchronous = Toolbox::GetJsonBooleanField(request, "Asynchronous", false);
1293
1294 WebServiceParameters peer; 1342 WebServiceParameters peer;
1295 Configuration::GetOrthancPeer(peer, remote); 1343 Configuration::GetOrthancPeer(peer, remote);
1296 1344
1297 ServerJob job; 1345 std::auto_ptr<OrthancPeerStoreJob> job(new OrthancPeerStoreJob(context));
1298 for (std::list<std::string>::const_iterator 1346 job->SetPeer(peer);
1299 it = instances.begin(); it != instances.end(); ++it) 1347
1300 { 1348 SubmitJob(call, request, instances, job.release());
1301 job.AddCommand(new StorePeerCommand(context, peer, false)).AddInput(*it);
1302 }
1303
1304 job.SetDescription("HTTP request: POST to peer \"" + remote + "\"");
1305
1306 if (asynchronous)
1307 {
1308 // Asynchronous mode: Submit the job, but don't wait for its completion
1309 context.GetScheduler().Submit(job);
1310 call.GetOutput().AnswerBuffer("{}", "application/json");
1311 }
1312 else if (context.GetScheduler().SubmitAndWait(job))
1313 {
1314 // Synchronous mode: We have submitted and waited for completion
1315 call.GetOutput().AnswerBuffer("{}", "application/json");
1316 }
1317 else
1318 {
1319 call.GetOutput().SignalError(HttpStatus_500_InternalServerError);
1320 }
1321 } 1349 }
1322 1350
1323 1351
1324 // DICOM bridge ------------------------------------------------------------- 1352 // DICOM bridge -------------------------------------------------------------
1325 1353