comparison OrthancServer/ServerJobs/StorageCommitmentScpJob.cpp @ 3660:f159b731c47d storage-commitment

IStorageCommitmentFactory
author Sebastien Jodogne <s.jodogne@gmail.com>
date Mon, 10 Feb 2020 17:39:53 +0100
parents 08eb0f93c491
children 25117919a36b
comparison
equal deleted inserted replaced
3659:08eb0f93c491 3660:f159b731c47d
64 64
65 65
66 class StorageCommitmentScpJob::SetupCommand : public StorageCommitmentCommand 66 class StorageCommitmentScpJob::SetupCommand : public StorageCommitmentCommand
67 { 67 {
68 private: 68 private:
69 ServerContext& context_; 69 StorageCommitmentScpJob& that_;
70 70
71 public: 71 public:
72 SetupCommand(ServerContext& context) : 72 SetupCommand(StorageCommitmentScpJob& that) :
73 context_(context) 73 that_(that)
74 { 74 {
75 } 75 }
76 76
77 virtual CommandType GetType() const 77 virtual CommandType GetType() const
78 { 78 {
79 return CommandType_Setup; 79 return CommandType_Setup;
80 } 80 }
81 81
82 virtual bool Execute(const std::string& jobId) ORTHANC_OVERRIDE 82 virtual bool Execute(const std::string& jobId) ORTHANC_OVERRIDE
83 { 83 {
84 that_.Setup(jobId);
84 return true; 85 return true;
85 } 86 }
86 87
87 virtual void Serialize(Json::Value& target) const 88 virtual void Serialize(Json::Value& target) const
88 { 89 {
93 94
94 95
95 class StorageCommitmentScpJob::LookupCommand : public StorageCommitmentCommand 96 class StorageCommitmentScpJob::LookupCommand : public StorageCommitmentCommand
96 { 97 {
97 private: 98 private:
98 ServerContext& context_; 99 StorageCommitmentScpJob& that_;
99 bool hasFailureReason_; 100 bool hasFailureReason_;
100 std::string sopClassUid_; 101 std::string sopClassUid_;
101 std::string sopInstanceUid_; 102 std::string sopInstanceUid_;
102 StorageCommitmentFailureReason failureReason_; 103 StorageCommitmentFailureReason failureReason_;
103 104
104 public: 105 public:
105 LookupCommand(ServerContext& context, 106 LookupCommand(StorageCommitmentScpJob& that,
106 const std::string& sopClassUid, 107 const std::string& sopClassUid,
107 const std::string& sopInstanceUid) : 108 const std::string& sopInstanceUid) :
108 context_(context), 109 that_(that),
109 hasFailureReason_(false), 110 hasFailureReason_(false),
110 sopClassUid_(sopClassUid), 111 sopClassUid_(sopClassUid),
111 sopInstanceUid_(sopInstanceUid) 112 sopInstanceUid_(sopInstanceUid)
112 { 113 {
113 } 114 }
121 { 122 {
122 if (hasFailureReason_) 123 if (hasFailureReason_)
123 { 124 {
124 throw OrthancException(ErrorCode_BadSequenceOfCalls); 125 throw OrthancException(ErrorCode_BadSequenceOfCalls);
125 } 126 }
126 127 else
128 {
129 failureReason_ = that_.Lookup(sopClassUid_, sopInstanceUid_);
130 hasFailureReason_ = true;
131 return true;
132 }
133 }
134
135 const std::string& GetSopClassUid() const
136 {
137 return sopClassUid_;
138 }
139
140 const std::string& GetSopInstanceUid() const
141 {
142 return sopInstanceUid_;
143 }
144
145 StorageCommitmentFailureReason GetFailureReason() const
146 {
147 if (hasFailureReason_)
148 {
149 return failureReason_;
150 }
151 else
152 {
153 throw OrthancException(ErrorCode_BadSequenceOfCalls);
154 }
155 }
156
157 virtual void Serialize(Json::Value& target) const
158 {
159 target = Json::objectValue;
160 target[TYPE] = LOOKUP;
161 target[SOP_CLASS_UID] = sopClassUid_;
162 target[SOP_INSTANCE_UID] = sopInstanceUid_;
163 }
164 };
165
166
167 class StorageCommitmentScpJob::AnswerCommand : public StorageCommitmentCommand
168 {
169 private:
170 StorageCommitmentScpJob& that_;
171
172 public:
173 AnswerCommand(StorageCommitmentScpJob& that) :
174 that_(that)
175 {
176 if (that_.ready_)
177 {
178 throw OrthancException(ErrorCode_BadSequenceOfCalls);
179 }
180 else
181 {
182 that_.ready_ = true;
183 }
184 }
185
186 virtual CommandType GetType() const
187 {
188 return CommandType_Answer;
189 }
190
191 virtual bool Execute(const std::string& jobId) ORTHANC_OVERRIDE
192 {
193 that_.Answer();
194 return true;
195 }
196
197 virtual void Serialize(Json::Value& target) const
198 {
199 target = Json::objectValue;
200 target[TYPE] = ANSWER;
201 }
202 };
203
204
205 class StorageCommitmentScpJob::Unserializer : public SetOfCommandsJob::ICommandUnserializer
206 {
207 private:
208 StorageCommitmentScpJob& that_;
209
210 public:
211 Unserializer(StorageCommitmentScpJob& that) :
212 that_(that)
213 {
214 that_.ready_ = false;
215 }
216
217 virtual ICommand* Unserialize(const Json::Value& source) const
218 {
219 const std::string type = SerializationToolbox::ReadString(source, TYPE);
220
221 if (type == SETUP)
222 {
223 return new SetupCommand(that_);
224 }
225 else if (type == LOOKUP)
226 {
227 return new LookupCommand(that_,
228 SerializationToolbox::ReadString(source, SOP_CLASS_UID),
229 SerializationToolbox::ReadString(source, SOP_INSTANCE_UID));
230 }
231 else if (type == ANSWER)
232 {
233 return new AnswerCommand(that_);
234 }
235 else
236 {
237 throw OrthancException(ErrorCode_BadFileFormat);
238 }
239 }
240 };
241
242
243 void StorageCommitmentScpJob::Setup(const std::string& jobId)
244 {
245 const size_t n = GetCommandsCount();
246
247 if (n <= 1)
248 {
249 throw OrthancException(ErrorCode_InternalError);
250 }
251
252 std::vector<std::string> sopClassUids, sopInstanceUids;
253
254 sopClassUids.reserve(n);
255 sopInstanceUids.reserve(n);
256
257 for (size_t i = 0; i < n; i++)
258 {
259 const CommandType type = dynamic_cast<const StorageCommitmentCommand&>(GetCommand(i)).GetType();
260
261 if ((i == 0 && type != CommandType_Setup) ||
262 (i >= 1 && i < n - 1 && type != CommandType_Lookup) ||
263 (i == n - 1 && type != CommandType_Answer))
264 {
265 throw OrthancException(ErrorCode_InternalError);
266 }
267
268 if (type == CommandType_Lookup)
269 {
270 const LookupCommand& lookup = dynamic_cast<const LookupCommand&>(GetCommand(i));
271 sopClassUids.push_back(lookup.GetSopClassUid());
272 sopInstanceUids.push_back(lookup.GetSopInstanceUid());
273 }
274 }
275
276 lookupHandler_.reset(context_.CreateStorageCommitment(jobId, transactionUid_, sopClassUids, sopInstanceUids));
277 }
278
279
280 StorageCommitmentFailureReason StorageCommitmentScpJob::Lookup(const std::string& sopClassUid,
281 const std::string& sopInstanceUid)
282 {
283 if (lookupHandler_.get() != NULL)
284 {
285 return lookupHandler_->Lookup(sopClassUid, sopInstanceUid);
286 }
287 else
288 {
289 // This is the default implementation of Orthanc (if no storage
290 // commitment plugin is installed)
127 bool success = false; 291 bool success = false;
128 292
129 try 293 try
130 { 294 {
131 std::vector<std::string> orthancId; 295 std::vector<std::string> orthancId;
132 context_.GetIndex().LookupIdentifierExact(orthancId, ResourceType_Instance, DICOM_TAG_SOP_INSTANCE_UID, sopInstanceUid_); 296 context_.GetIndex().LookupIdentifierExact(orthancId, ResourceType_Instance, DICOM_TAG_SOP_INSTANCE_UID, sopInstanceUid);
133 297
134 if (orthancId.size() == 1) 298 if (orthancId.size() == 1)
135 { 299 {
136 std::string a, b; 300 std::string a, b;
137 301
139 // from the file storage, and that the actual SOP 303 // from the file storage, and that the actual SOP
140 // class/instance UIDs do match 304 // class/instance UIDs do match
141 ServerContext::DicomCacheLocker locker(context_, orthancId[0]); 305 ServerContext::DicomCacheLocker locker(context_, orthancId[0]);
142 if (locker.GetDicom().GetTagValue(a, DICOM_TAG_SOP_CLASS_UID) && 306 if (locker.GetDicom().GetTagValue(a, DICOM_TAG_SOP_CLASS_UID) &&
143 locker.GetDicom().GetTagValue(b, DICOM_TAG_SOP_INSTANCE_UID) && 307 locker.GetDicom().GetTagValue(b, DICOM_TAG_SOP_INSTANCE_UID) &&
144 a == sopClassUid_ && 308 a == sopClassUid &&
145 b == sopInstanceUid_) 309 b == sopInstanceUid)
146 { 310 {
147 success = true; 311 success = true;
148 } 312 }
149 } 313 }
150 } 314 }
151 catch (OrthancException&) 315 catch (OrthancException&)
152 { 316 {
153 } 317 }
154 318
155 LOG(INFO) << " Storage commitment SCP job: " << (success ? "Success" : "Failure") 319 LOG(INFO) << " Storage commitment SCP job: " << (success ? "Success" : "Failure")
156 << " while looking for " << sopClassUid_ << " / " << sopInstanceUid_; 320 << " while looking for " << sopClassUid << " / " << sopInstanceUid;
157 321
158 failureReason_ = (success ? 322 return (success ?
159 StorageCommitmentFailureReason_Success : 323 StorageCommitmentFailureReason_Success :
160 StorageCommitmentFailureReason_NoSuchObjectInstance /* 0x0112 == 274 */); 324 StorageCommitmentFailureReason_NoSuchObjectInstance /* 0x0112 == 274 */);
161 hasFailureReason_ = true; 325 }
162 326 }
163 return true;
164 }
165
166 const std::string& GetSopClassUid() const
167 {
168 return sopClassUid_;
169 }
170
171 const std::string& GetSopInstanceUid() const
172 {
173 return sopInstanceUid_;
174 }
175
176 StorageCommitmentFailureReason GetFailureReason() const
177 {
178 if (hasFailureReason_)
179 {
180 return failureReason_;
181 }
182 else
183 {
184 throw OrthancException(ErrorCode_BadSequenceOfCalls);
185 }
186 }
187
188 virtual void Serialize(Json::Value& target) const
189 {
190 target = Json::objectValue;
191 target[TYPE] = LOOKUP;
192 target[SOP_CLASS_UID] = sopClassUid_;
193 target[SOP_INSTANCE_UID] = sopInstanceUid_;
194 }
195 };
196
197 327
198 class StorageCommitmentScpJob::AnswerCommand : public StorageCommitmentCommand
199 {
200 private:
201 StorageCommitmentScpJob& that_;
202
203 public:
204 AnswerCommand(StorageCommitmentScpJob& that) :
205 that_(that)
206 {
207 if (that_.ready_)
208 {
209 throw OrthancException(ErrorCode_BadSequenceOfCalls);
210 }
211 else
212 {
213 that_.ready_ = true;
214 }
215 }
216
217 virtual CommandType GetType() const
218 {
219 return CommandType_Answer;
220 }
221
222 virtual bool Execute(const std::string& jobId) ORTHANC_OVERRIDE
223 {
224 that_.Answer();
225 return true;
226 }
227
228 virtual void Serialize(Json::Value& target) const
229 {
230 target = Json::objectValue;
231 target[TYPE] = ANSWER;
232 }
233 };
234
235
236 class StorageCommitmentScpJob::Unserializer : public SetOfCommandsJob::ICommandUnserializer
237 {
238 private:
239 StorageCommitmentScpJob& that_;
240 ServerContext& context_;
241
242 public:
243 Unserializer(StorageCommitmentScpJob& that,
244 ServerContext& context) :
245 that_(that),
246 context_(context)
247 {
248 that_.ready_ = false;
249 }
250
251 virtual ICommand* Unserialize(const Json::Value& source) const
252 {
253 const std::string type = SerializationToolbox::ReadString(source, TYPE);
254
255 if (type == SETUP)
256 {
257 return new SetupCommand(context_);
258 }
259 else if (type == LOOKUP)
260 {
261 return new LookupCommand(context_,
262 SerializationToolbox::ReadString(source, SOP_CLASS_UID),
263 SerializationToolbox::ReadString(source, SOP_INSTANCE_UID));
264 }
265 else if (type == ANSWER)
266 {
267 return new AnswerCommand(that_);
268 }
269 else
270 {
271 throw OrthancException(ErrorCode_BadFileFormat);
272 }
273 }
274 };
275
276 328
277 void StorageCommitmentScpJob::Answer() 329 void StorageCommitmentScpJob::Answer()
278 { 330 {
279 LOG(INFO) << " Storage commitment SCP job: Sending answer"; 331 LOG(INFO) << " Storage commitment SCP job: Sending answer";
280 332
333 throw OrthancException(ErrorCode_InexistentItem, 385 throw OrthancException(ErrorCode_InexistentItem,
334 "Unknown remote modality for storage commitment SCP: " + remoteAet); 386 "Unknown remote modality for storage commitment SCP: " + remoteAet);
335 } 387 }
336 } 388 }
337 389
338 AddCommand(new SetupCommand(context)); 390 AddCommand(new SetupCommand(*this));
339 } 391 }
340 392
341 393
342 void StorageCommitmentScpJob::AddInstance(const std::string& sopClassUid, 394 void StorageCommitmentScpJob::AddInstance(const std::string& sopClassUid,
343 const std::string& sopInstanceUid) 395 const std::string& sopInstanceUid)
346 { 398 {
347 throw OrthancException(ErrorCode_BadSequenceOfCalls); 399 throw OrthancException(ErrorCode_BadSequenceOfCalls);
348 } 400 }
349 else 401 else
350 { 402 {
351 AddCommand(new LookupCommand(context_, sopClassUid, sopInstanceUid)); 403 AddCommand(new LookupCommand(*this, sopClassUid, sopInstanceUid));
352 } 404 }
353 } 405 }
354 406
355 407
356 void StorageCommitmentScpJob::MarkAsReady() 408 void StorageCommitmentScpJob::MarkAsReady()
369 } 421 }
370 422
371 423
372 StorageCommitmentScpJob::StorageCommitmentScpJob(ServerContext& context, 424 StorageCommitmentScpJob::StorageCommitmentScpJob(ServerContext& context,
373 const Json::Value& serialized) : 425 const Json::Value& serialized) :
374 SetOfCommandsJob(new Unserializer(*this, context), serialized), 426 SetOfCommandsJob(new Unserializer(*this), serialized),
375 context_(context) 427 context_(context)
376 { 428 {
377 transactionUid_ = SerializationToolbox::ReadString(serialized, TRANSACTION_UID); 429 transactionUid_ = SerializationToolbox::ReadString(serialized, TRANSACTION_UID);
378 remoteModality_ = RemoteModalityParameters(serialized[REMOTE_MODALITY]); 430 remoteModality_ = RemoteModalityParameters(serialized[REMOTE_MODALITY]);
379 calledAet_ = SerializationToolbox::ReadString(serialized, CALLED_AET); 431 calledAet_ = SerializationToolbox::ReadString(serialized, CALLED_AET);