comparison OrthancServer/Sources/ServerJobs/DicomMoveScuJob.cpp @ 4044:d25f4c0fa160 framework

splitting code into OrthancFramework and OrthancServer
author Sebastien Jodogne <s.jodogne@gmail.com>
date Wed, 10 Jun 2020 20:30:34 +0200
parents OrthancServer/ServerJobs/DicomMoveScuJob.cpp@4b4f387c6bb8
children 05b8fd21089c
comparison
equal deleted inserted replaced
4043:6c6239aec462 4044:d25f4c0fa160
1 /**
2 * Orthanc - A Lightweight, RESTful DICOM Store
3 * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
4 * Department, University Hospital of Liege, Belgium
5 * Copyright (C) 2017-2020 Osimis S.A., Belgium
6 *
7 * This program is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation, either version 3 of the
10 * License, or (at your option) any later version.
11 *
12 * In addition, as a special exception, the copyright holders of this
13 * program give permission to link the code of its release with the
14 * OpenSSL project's "OpenSSL" library (or with modified versions of it
15 * that use the same license as the "OpenSSL" library), and distribute
16 * the linked executables. You must obey the GNU General Public License
17 * in all respects for all of the code used other than "OpenSSL". If you
18 * modify file(s) with this exception, you may extend this exception to
19 * your version of the file(s), but you are not obligated to do so. If
20 * you do not wish to do so, delete this exception statement from your
21 * version. If you delete this exception statement from all source files
22 * in the program, then also delete it here.
23 *
24 * This program is distributed in the hope that it will be useful, but
25 * WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
27 * General Public License for more details.
28 *
29 * You should have received a copy of the GNU General Public License
30 * along with this program. If not, see <http://www.gnu.org/licenses/>.
31 **/
32
33
34 #include "DicomMoveScuJob.h"
35
36 #include "../../Core/SerializationToolbox.h"
37 #include "../ServerContext.h"
38
39 static const char* const LOCAL_AET = "LocalAet";
40 static const char* const TARGET_AET = "TargetAet";
41 static const char* const REMOTE = "Remote";
42 static const char* const QUERY = "Query";
43 static const char* const TIMEOUT = "Timeout";
44
45 namespace Orthanc
46 {
47 class DicomMoveScuJob::Command : public SetOfCommandsJob::ICommand
48 {
49 private:
50 DicomMoveScuJob& that_;
51 std::unique_ptr<DicomMap> findAnswer_;
52
53 public:
54 Command(DicomMoveScuJob& that,
55 const DicomMap& findAnswer) :
56 that_(that),
57 findAnswer_(findAnswer.Clone())
58 {
59 }
60
61 virtual bool Execute(const std::string& jobId) ORTHANC_OVERRIDE
62 {
63 that_.Retrieve(*findAnswer_);
64 return true;
65 }
66
67 virtual void Serialize(Json::Value& target) const ORTHANC_OVERRIDE
68 {
69 findAnswer_->Serialize(target);
70 }
71 };
72
73
74 class DicomMoveScuJob::Unserializer :
75 public SetOfCommandsJob::ICommandUnserializer
76 {
77 private:
78 DicomMoveScuJob& that_;
79
80 public:
81 Unserializer(DicomMoveScuJob& that) :
82 that_(that)
83 {
84 }
85
86 virtual ICommand* Unserialize(const Json::Value& source) const
87 {
88 DicomMap findAnswer;
89 findAnswer.Unserialize(source);
90 return new Command(that_, findAnswer);
91 }
92 };
93
94
95
96 void DicomMoveScuJob::Retrieve(const DicomMap& findAnswer)
97 {
98 if (connection_.get() == NULL)
99 {
100 connection_.reset(new DicomControlUserConnection(parameters_));
101 }
102
103 connection_->Move(targetAet_, findAnswer);
104 }
105
106
107 static void AddTagIfString(Json::Value& target,
108 const DicomMap& answer,
109 const DicomTag& tag)
110 {
111 const DicomValue* value = answer.TestAndGetValue(tag);
112 if (value != NULL &&
113 !value->IsNull() &&
114 !value->IsBinary())
115 {
116 target[tag.Format()] = value->GetContent();
117 }
118 }
119
120
121 void DicomMoveScuJob::AddFindAnswer(const DicomMap& answer)
122 {
123 assert(query_.type() == Json::arrayValue);
124
125 // Copy the identifiers tags, if they exist
126 Json::Value item = Json::objectValue;
127 AddTagIfString(item, answer, DICOM_TAG_QUERY_RETRIEVE_LEVEL);
128 AddTagIfString(item, answer, DICOM_TAG_PATIENT_ID);
129 AddTagIfString(item, answer, DICOM_TAG_STUDY_INSTANCE_UID);
130 AddTagIfString(item, answer, DICOM_TAG_SERIES_INSTANCE_UID);
131 AddTagIfString(item, answer, DICOM_TAG_SOP_INSTANCE_UID);
132 AddTagIfString(item, answer, DICOM_TAG_ACCESSION_NUMBER);
133 query_.append(item);
134
135 AddCommand(new Command(*this, answer));
136 }
137
138
139 void DicomMoveScuJob::AddFindAnswer(QueryRetrieveHandler& query,
140 size_t i)
141 {
142 DicomMap answer;
143 query.GetAnswer(answer, i);
144 AddFindAnswer(answer);
145 }
146
147
148 void DicomMoveScuJob::SetLocalAet(const std::string& aet)
149 {
150 if (IsStarted())
151 {
152 throw OrthancException(ErrorCode_BadSequenceOfCalls);
153 }
154 else
155 {
156 parameters_.SetLocalApplicationEntityTitle(aet);
157 }
158 }
159
160
161 void DicomMoveScuJob::SetTargetAet(const std::string& aet)
162 {
163 if (IsStarted())
164 {
165 throw OrthancException(ErrorCode_BadSequenceOfCalls);
166 }
167 else
168 {
169 targetAet_ = aet;
170 }
171 }
172
173
174 void DicomMoveScuJob::SetRemoteModality(const RemoteModalityParameters& remote)
175 {
176 if (IsStarted())
177 {
178 throw OrthancException(ErrorCode_BadSequenceOfCalls);
179 }
180 else
181 {
182 parameters_.SetRemoteModality(remote);
183 }
184 }
185
186
187 void DicomMoveScuJob::SetTimeout(uint32_t seconds)
188 {
189 if (IsStarted())
190 {
191 throw OrthancException(ErrorCode_BadSequenceOfCalls);
192 }
193 else
194 {
195 parameters_.SetTimeout(seconds);
196 }
197 }
198
199
200 void DicomMoveScuJob::Stop(JobStopReason reason)
201 {
202 connection_.reset();
203 }
204
205
206 void DicomMoveScuJob::GetPublicContent(Json::Value& value)
207 {
208 SetOfCommandsJob::GetPublicContent(value);
209
210 value["LocalAet"] = parameters_.GetLocalApplicationEntityTitle();
211 value["RemoteAet"] = parameters_.GetRemoteModality().GetApplicationEntityTitle();
212 value["Query"] = query_;
213 }
214
215
216 DicomMoveScuJob::DicomMoveScuJob(ServerContext& context,
217 const Json::Value& serialized) :
218 SetOfCommandsJob(new Unserializer(*this), serialized),
219 context_(context),
220 query_(Json::arrayValue)
221 {
222 parameters_ = DicomAssociationParameters::UnserializeJob(serialized);
223 targetAet_ = SerializationToolbox::ReadString(serialized, TARGET_AET);
224
225 if (serialized.isMember(QUERY) &&
226 serialized[QUERY].type() == Json::arrayValue)
227 {
228 query_ = serialized[QUERY];
229 }
230 }
231
232
233 bool DicomMoveScuJob::Serialize(Json::Value& target)
234 {
235 if (!SetOfCommandsJob::Serialize(target))
236 {
237 return false;
238 }
239 else
240 {
241 parameters_.SerializeJob(target);
242 target[TARGET_AET] = targetAet_;
243 target[QUERY] = query_;
244 return true;
245 }
246 }
247 }