Mercurial > hg > orthanc
comparison OrthancServer/main.cpp @ 3636:bce6ee64f2a4 storage-commitment
reorganization
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Fri, 31 Jan 2020 14:29:35 +0100 |
parents | 8c0ef729d5a8 |
children | f6a73611ec5c |
comparison
equal
deleted
inserted
replaced
3635:8c0ef729d5a8 | 3636:bce6ee64f2a4 |
---|---|
48 #include "OrthancConfiguration.h" | 48 #include "OrthancConfiguration.h" |
49 #include "OrthancFindRequestHandler.h" | 49 #include "OrthancFindRequestHandler.h" |
50 #include "OrthancInitialization.h" | 50 #include "OrthancInitialization.h" |
51 #include "OrthancMoveRequestHandler.h" | 51 #include "OrthancMoveRequestHandler.h" |
52 #include "ServerContext.h" | 52 #include "ServerContext.h" |
53 #include "ServerJobs/StorageCommitmentScpJob.h" | |
53 #include "ServerToolbox.h" | 54 #include "ServerToolbox.h" |
54 | 55 |
55 using namespace Orthanc; | 56 using namespace Orthanc; |
56 | 57 |
57 | 58 |
87 context_.Store(id, toStore); | 88 context_.Store(id, toStore); |
88 } | 89 } |
89 } | 90 } |
90 }; | 91 }; |
91 | 92 |
92 | |
93 | |
94 namespace Orthanc | |
95 { | |
96 class StorageCommitmentScpJob : public SetOfCommandsJob | |
97 { | |
98 private: | |
99 class LookupCommand : public SetOfCommandsJob::ICommand | |
100 { | |
101 private: | |
102 StorageCommitmentScpJob& that_; | |
103 std::string sopClassUid_; | |
104 std::string sopInstanceUid_; | |
105 | |
106 public: | |
107 LookupCommand(StorageCommitmentScpJob& that, | |
108 const std::string& sopClassUid, | |
109 const std::string& sopInstanceUid) : | |
110 that_(that), | |
111 sopClassUid_(sopClassUid), | |
112 sopInstanceUid_(sopInstanceUid) | |
113 { | |
114 } | |
115 | |
116 virtual bool Execute() | |
117 { | |
118 that_.LookupInstance(sopClassUid_, sopInstanceUid_); | |
119 return true; | |
120 } | |
121 | |
122 virtual void Serialize(Json::Value& target) const | |
123 { | |
124 target = Json::objectValue; | |
125 target["Type"] = "Lookup"; | |
126 target["SopClassUid"] = sopClassUid_; | |
127 target["SopInstanceUid"] = sopInstanceUid_; | |
128 } | |
129 }; | |
130 | |
131 class AnswerCommand : public SetOfCommandsJob::ICommand | |
132 { | |
133 private: | |
134 StorageCommitmentScpJob& that_; | |
135 | |
136 public: | |
137 AnswerCommand(StorageCommitmentScpJob& that) : | |
138 that_(that) | |
139 { | |
140 } | |
141 | |
142 virtual bool Execute() | |
143 { | |
144 that_.Answer(); | |
145 return true; | |
146 } | |
147 | |
148 virtual void Serialize(Json::Value& target) const | |
149 { | |
150 target = Json::objectValue; | |
151 target["Type"] = "Answer"; | |
152 } | |
153 }; | |
154 | |
155 class Unserializer : public SetOfCommandsJob::ICommandUnserializer | |
156 { | |
157 private: | |
158 StorageCommitmentScpJob& that_; | |
159 | |
160 public: | |
161 Unserializer(StorageCommitmentScpJob& that) : | |
162 that_(that) | |
163 { | |
164 } | |
165 | |
166 virtual ICommand* Unserialize(const Json::Value& source) const | |
167 { | |
168 std::cout << "===================================\n"; | |
169 std::cout << source.toStyledString(); | |
170 | |
171 /*DicomMap findAnswer; | |
172 findAnswer.Unserialize(source); | |
173 return new Command(that_, findAnswer);*/ | |
174 | |
175 throw OrthancException(ErrorCode_NotImplemented); | |
176 } | |
177 }; | |
178 | |
179 ServerContext& context_; | |
180 bool ready_; | |
181 std::string transactionUid_; | |
182 RemoteModalityParameters remoteModality_; | |
183 std::string calledAet_; | |
184 std::list<std::string> successSopClassUids_; | |
185 std::list<std::string> successSopInstanceUids_; | |
186 std::list<std::string> failedSopClassUids_; | |
187 std::list<std::string> failedSopInstanceUids_; | |
188 | |
189 void LookupInstance(const std::string& sopClassUid, | |
190 const std::string& sopInstanceUid) | |
191 { | |
192 bool success = false; | |
193 | |
194 try | |
195 { | |
196 std::vector<std::string> orthancId; | |
197 context_.GetIndex().LookupIdentifierExact(orthancId, ResourceType_Instance, DICOM_TAG_SOP_INSTANCE_UID, sopInstanceUid); | |
198 | |
199 if (orthancId.size() == 1) | |
200 { | |
201 std::string a, b; | |
202 | |
203 ServerContext::DicomCacheLocker locker(context_, orthancId[0]); | |
204 if (locker.GetDicom().GetTagValue(a, DICOM_TAG_SOP_CLASS_UID) && | |
205 locker.GetDicom().GetTagValue(b, DICOM_TAG_SOP_INSTANCE_UID) && | |
206 a == sopClassUid && | |
207 b == sopInstanceUid) | |
208 { | |
209 success = true; | |
210 } | |
211 } | |
212 } | |
213 catch (OrthancException&) | |
214 { | |
215 } | |
216 | |
217 LOG(INFO) << " Storage commitment SCP job: " << (success ? "Success" : "Failure") | |
218 << " while looking for " << sopClassUid << " / " << sopInstanceUid; | |
219 | |
220 if (success) | |
221 { | |
222 successSopClassUids_.push_back(sopClassUid); | |
223 successSopInstanceUids_.push_back(sopInstanceUid); | |
224 } | |
225 else | |
226 { | |
227 failedSopClassUids_.push_back(sopClassUid); | |
228 failedSopInstanceUids_.push_back(sopInstanceUid); | |
229 } | |
230 } | |
231 | |
232 void Answer() | |
233 { | |
234 LOG(INFO) << " Storage commitment SCP job: Sending answer"; | |
235 | |
236 DicomUserConnection scu(calledAet_, remoteModality_); | |
237 scu.ReportStorageCommitment(transactionUid_, successSopClassUids_, successSopInstanceUids_, | |
238 failedSopClassUids_, failedSopInstanceUids_); | |
239 | |
240 /** | |
241 * "After the N-EVENT-REPORT has been sent, the Transaction UID is | |
242 * no longer active and shall not be reused for other | |
243 * transactions." | |
244 * http://dicom.nema.org/medical/dicom/2019a/output/chtml/part04/sect_J.3.3.html | |
245 **/ | |
246 } | |
247 | |
248 public: | |
249 StorageCommitmentScpJob(ServerContext& context, | |
250 const std::string& transactionUid, | |
251 const std::string& remoteAet, | |
252 const std::string& calledAet) : | |
253 context_(context), | |
254 ready_(false), | |
255 transactionUid_(transactionUid), | |
256 calledAet_(calledAet) | |
257 { | |
258 { | |
259 OrthancConfiguration::ReaderLock lock; | |
260 if (!lock.GetConfiguration().LookupDicomModalityUsingAETitle(remoteModality_, remoteAet)) | |
261 { | |
262 throw OrthancException(ErrorCode_InexistentItem, | |
263 "Unknown remote modality for storage commitment SCP: " + remoteAet); | |
264 } | |
265 } | |
266 } | |
267 | |
268 void AddInstance(const std::string& sopClassUid, | |
269 const std::string& sopInstanceUid) | |
270 { | |
271 if (ready_) | |
272 { | |
273 throw OrthancException(ErrorCode_BadSequenceOfCalls); | |
274 } | |
275 else | |
276 { | |
277 AddCommand(new LookupCommand(*this, sopClassUid, sopInstanceUid)); | |
278 } | |
279 } | |
280 | |
281 void MarkAsReady() | |
282 { | |
283 if (ready_) | |
284 { | |
285 throw OrthancException(ErrorCode_BadSequenceOfCalls); | |
286 } | |
287 else | |
288 { | |
289 AddCommand(new AnswerCommand(*this)); | |
290 ready_ = true; | |
291 } | |
292 } | |
293 | |
294 virtual void Stop(JobStopReason reason) | |
295 { | |
296 } | |
297 | |
298 virtual void GetJobType(std::string& target) | |
299 { | |
300 target = "StorageCommitmentScp"; | |
301 } | |
302 | |
303 virtual void GetPublicContent(Json::Value& value) | |
304 { | |
305 SetOfCommandsJob::GetPublicContent(value); | |
306 | |
307 value["LocalAet"] = calledAet_; | |
308 value["RemoteAet"] = remoteModality_.GetApplicationEntityTitle(); | |
309 value["TransactionUid"] = transactionUid_; | |
310 } | |
311 }; | |
312 } | |
313 | 93 |
314 | 94 |
315 class OrthancStorageCommitmentRequestHandler : public IStorageCommitmentRequestHandler | 95 class OrthancStorageCommitmentRequestHandler : public IStorageCommitmentRequestHandler |
316 { | 96 { |
317 private: | 97 private: |
356 const std::string& remoteIp, | 136 const std::string& remoteIp, |
357 const std::string& remoteAet, | 137 const std::string& remoteAet, |
358 const std::string& calledAet) | 138 const std::string& calledAet) |
359 { | 139 { |
360 printf("HANDLE REPORT\n"); | 140 printf("HANDLE REPORT\n"); |
141 | |
142 /** | |
143 * "After the N-EVENT-REPORT has been sent, the Transaction UID is | |
144 * no longer active and shall not be reused for other | |
145 * transactions." | |
146 * http://dicom.nema.org/medical/dicom/2019a/output/chtml/part04/sect_J.3.3.html | |
147 **/ | |
361 } | 148 } |
362 }; | 149 }; |
363 | 150 |
364 | 151 |
365 | 152 |