Mercurial > hg > orthanc
annotate OrthancFramework/Sources/JobsEngine/SetOfCommandsJob.cpp @ 4300:b30a8de92ad9
abi continued
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Thu, 05 Nov 2020 19:33:18 +0100 |
parents | bf7b9edf6b81 |
children | 44b53a2c0a13 |
rev | line source |
---|---|
2860 | 1 /** |
2 * Orthanc - A Lightweight, RESTful DICOM Store | |
3 * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics | |
4 * Department, University Hospital of Liege, Belgium | |
3640
94f4a18a79cc
upgrade to year 2020
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3240
diff
changeset
|
5 * Copyright (C) 2017-2020 Osimis S.A., Belgium |
2860 | 6 * |
7 * This program is free software: you can redistribute it and/or | |
4119
bf7b9edf6b81
re-licensing the OrthancFramework to LGPL, in order to license Stone of Orthanc under LGPL
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4044
diff
changeset
|
8 * modify it under the terms of the GNU Lesser General Public License |
bf7b9edf6b81
re-licensing the OrthancFramework to LGPL, in order to license Stone of Orthanc under LGPL
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4044
diff
changeset
|
9 * as published by the Free Software Foundation, either version 3 of |
bf7b9edf6b81
re-licensing the OrthancFramework to LGPL, in order to license Stone of Orthanc under LGPL
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4044
diff
changeset
|
10 * the License, or (at your option) any later version. |
2860 | 11 * |
12 * This program is distributed in the hope that it will be useful, but | |
13 * WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
4119
bf7b9edf6b81
re-licensing the OrthancFramework to LGPL, in order to license Stone of Orthanc under LGPL
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4044
diff
changeset
|
15 * Lesser General Public License for more details. |
2860 | 16 * |
4119
bf7b9edf6b81
re-licensing the OrthancFramework to LGPL, in order to license Stone of Orthanc under LGPL
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4044
diff
changeset
|
17 * You should have received a copy of the GNU Lesser General Public |
bf7b9edf6b81
re-licensing the OrthancFramework to LGPL, in order to license Stone of Orthanc under LGPL
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4044
diff
changeset
|
18 * License along with this program. If not, see |
bf7b9edf6b81
re-licensing the OrthancFramework to LGPL, in order to license Stone of Orthanc under LGPL
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4044
diff
changeset
|
19 * <http://www.gnu.org/licenses/>. |
2860 | 20 **/ |
21 | |
22 | |
23 #include "../PrecompiledHeaders.h" | |
24 #include "SetOfCommandsJob.h" | |
25 | |
26 #include "../Logging.h" | |
27 #include "../OrthancException.h" | |
28 #include "../SerializationToolbox.h" | |
29 | |
30 #include <cassert> | |
2866 | 31 #include <memory> |
2860 | 32 |
33 namespace Orthanc | |
34 { | |
4300 | 35 SetOfCommandsJob::ICommand::~ICommand() |
36 { | |
37 } | |
38 | |
39 SetOfCommandsJob::ICommandUnserializer::~ICommandUnserializer() | |
40 { | |
41 } | |
42 | |
2860 | 43 SetOfCommandsJob::SetOfCommandsJob() : |
44 started_(false), | |
45 permissive_(false), | |
46 position_(0) | |
47 { | |
48 } | |
49 | |
50 | |
51 SetOfCommandsJob::~SetOfCommandsJob() | |
52 { | |
53 for (size_t i = 0; i < commands_.size(); i++) | |
54 { | |
55 assert(commands_[i] != NULL); | |
56 delete commands_[i]; | |
57 } | |
58 } | |
59 | |
4300 | 60 size_t SetOfCommandsJob::GetPosition() const |
61 { | |
62 return position_; | |
63 } | |
64 | |
65 void SetOfCommandsJob::SetDescription(const std::string &description) | |
66 { | |
67 description_ = description; | |
68 } | |
69 | |
70 | |
2860 | 71 void SetOfCommandsJob::Reserve(size_t size) |
72 { | |
73 if (started_) | |
74 { | |
75 throw OrthancException(ErrorCode_BadSequenceOfCalls); | |
76 } | |
77 else | |
78 { | |
79 commands_.reserve(size); | |
80 } | |
81 } | |
82 | |
4300 | 83 size_t SetOfCommandsJob::GetCommandsCount() const |
84 { | |
85 return commands_.size(); | |
86 } | |
87 | |
88 | |
2860 | 89 void SetOfCommandsJob::AddCommand(ICommand* command) |
90 { | |
91 if (command == NULL) | |
92 { | |
93 throw OrthancException(ErrorCode_NullPointer); | |
94 } | |
95 else if (started_) | |
96 { | |
97 throw OrthancException(ErrorCode_BadSequenceOfCalls); | |
98 } | |
99 else | |
100 { | |
101 commands_.push_back(command); | |
102 } | |
103 } | |
104 | |
4300 | 105 bool SetOfCommandsJob::IsPermissive() const |
106 { | |
107 return permissive_; | |
108 } | |
109 | |
2860 | 110 |
111 void SetOfCommandsJob::SetPermissive(bool permissive) | |
112 { | |
113 if (started_) | |
114 { | |
115 throw OrthancException(ErrorCode_BadSequenceOfCalls); | |
116 } | |
117 else | |
118 { | |
119 permissive_ = permissive; | |
120 } | |
121 } | |
122 | |
123 | |
124 void SetOfCommandsJob::Reset() | |
125 { | |
126 if (started_) | |
127 { | |
128 position_ = 0; | |
129 } | |
130 else | |
131 { | |
132 throw OrthancException(ErrorCode_BadSequenceOfCalls); | |
133 } | |
134 } | |
135 | |
4300 | 136 void SetOfCommandsJob::Start() |
137 { | |
138 started_ = true; | |
139 } | |
140 | |
141 | |
2860 | 142 float SetOfCommandsJob::GetProgress() |
143 { | |
144 if (commands_.empty()) | |
145 { | |
146 return 1; | |
147 } | |
148 else | |
149 { | |
150 return (static_cast<float>(position_) / | |
151 static_cast<float>(commands_.size())); | |
152 } | |
153 } | |
154 | |
4300 | 155 bool SetOfCommandsJob::IsStarted() const |
156 { | |
157 return started_; | |
158 } | |
159 | |
2860 | 160 |
161 const SetOfCommandsJob::ICommand& SetOfCommandsJob::GetCommand(size_t index) const | |
162 { | |
163 if (index >= commands_.size()) | |
164 { | |
165 throw OrthancException(ErrorCode_ParameterOutOfRange); | |
166 } | |
167 else | |
168 { | |
169 assert(commands_[index] != NULL); | |
170 return *commands_[index]; | |
171 } | |
172 } | |
173 | |
174 | |
3658
2d90dd30858c
providing job ID to the IJob::Step() methods
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3640
diff
changeset
|
175 JobStepResult SetOfCommandsJob::Step(const std::string& jobId) |
2860 | 176 { |
177 if (!started_) | |
178 { | |
179 throw OrthancException(ErrorCode_InternalError); | |
180 } | |
181 | |
182 if (commands_.empty() && | |
183 position_ == 0) | |
184 { | |
185 // No command to handle: We're done | |
186 position_ = 1; | |
187 return JobStepResult::Success(); | |
188 } | |
189 | |
190 if (position_ >= commands_.size()) | |
191 { | |
192 // Already done | |
193 throw OrthancException(ErrorCode_BadSequenceOfCalls); | |
194 } | |
195 | |
196 try | |
197 { | |
198 // Not at the trailing step: Handle the current command | |
3658
2d90dd30858c
providing job ID to the IJob::Step() methods
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3640
diff
changeset
|
199 if (!commands_[position_]->Execute(jobId)) |
2860 | 200 { |
201 // Error | |
202 if (!permissive_) | |
203 { | |
3240
e44e0127e553
Fix issue #134 (/patient/modify gives 500, should really be 400)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3060
diff
changeset
|
204 return JobStepResult::Failure(ErrorCode_InternalError, NULL); |
2860 | 205 } |
206 } | |
207 } | |
208 catch (OrthancException& e) | |
209 { | |
210 if (permissive_) | |
211 { | |
212 LOG(WARNING) << "Ignoring an error in a permissive job: " << e.What(); | |
213 } | |
214 else | |
215 { | |
3240
e44e0127e553
Fix issue #134 (/patient/modify gives 500, should really be 400)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3060
diff
changeset
|
216 return JobStepResult::Failure(e); |
2860 | 217 } |
218 } | |
219 | |
220 position_ += 1; | |
221 | |
222 if (position_ == commands_.size()) | |
223 { | |
224 // We're done | |
225 return JobStepResult::Success(); | |
226 } | |
227 else | |
228 { | |
229 return JobStepResult::Continue(); | |
230 } | |
231 } | |
232 | |
233 | |
234 | |
235 static const char* KEY_DESCRIPTION = "Description"; | |
236 static const char* KEY_PERMISSIVE = "Permissive"; | |
237 static const char* KEY_POSITION = "Position"; | |
238 static const char* KEY_TYPE = "Type"; | |
239 static const char* KEY_COMMANDS = "Commands"; | |
240 | |
241 | |
242 void SetOfCommandsJob::GetPublicContent(Json::Value& value) | |
243 { | |
244 value[KEY_DESCRIPTION] = GetDescription(); | |
245 } | |
246 | |
247 | |
248 bool SetOfCommandsJob::Serialize(Json::Value& target) | |
249 { | |
250 target = Json::objectValue; | |
251 | |
252 std::string type; | |
253 GetJobType(type); | |
254 target[KEY_TYPE] = type; | |
255 | |
256 target[KEY_PERMISSIVE] = permissive_; | |
257 target[KEY_POSITION] = static_cast<unsigned int>(position_); | |
258 target[KEY_DESCRIPTION] = description_; | |
259 | |
260 target[KEY_COMMANDS] = Json::arrayValue; | |
261 Json::Value& tmp = target[KEY_COMMANDS]; | |
262 | |
263 for (size_t i = 0; i < commands_.size(); i++) | |
264 { | |
265 assert(commands_[i] != NULL); | |
266 | |
267 Json::Value command; | |
268 commands_[i]->Serialize(command); | |
269 tmp.append(command); | |
270 } | |
271 | |
272 return true; | |
273 } | |
274 | |
4300 | 275 bool SetOfCommandsJob::GetOutput(std::string &output, |
276 MimeType &mime, | |
277 const std::string &key) | |
278 { | |
279 return false; | |
280 } | |
281 | |
2860 | 282 |
283 SetOfCommandsJob::SetOfCommandsJob(ICommandUnserializer* unserializer, | |
284 const Json::Value& source) : | |
285 started_(false) | |
286 { | |
3712
2a170a8f1faf
replacing std::auto_ptr by std::unique_ptr
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3640
diff
changeset
|
287 std::unique_ptr<ICommandUnserializer> raii(unserializer); |
2860 | 288 |
289 permissive_ = SerializationToolbox::ReadBoolean(source, KEY_PERMISSIVE); | |
290 position_ = SerializationToolbox::ReadUnsignedInteger(source, KEY_POSITION); | |
291 description_ = SerializationToolbox::ReadString(source, KEY_DESCRIPTION); | |
292 | |
293 if (!source.isMember(KEY_COMMANDS) || | |
294 source[KEY_COMMANDS].type() != Json::arrayValue) | |
295 { | |
296 throw OrthancException(ErrorCode_BadFileFormat); | |
297 } | |
298 else | |
299 { | |
300 const Json::Value& tmp = source[KEY_COMMANDS]; | |
301 commands_.resize(tmp.size()); | |
302 | |
303 for (Json::Value::ArrayIndex i = 0; i < tmp.size(); i++) | |
304 { | |
305 try | |
306 { | |
307 commands_[i] = unserializer->Unserialize(tmp[i]); | |
308 } | |
309 catch (OrthancException&) | |
310 { | |
311 } | |
312 | |
313 if (commands_[i] == NULL) | |
314 { | |
315 for (size_t j = 0; j < i; j++) | |
316 { | |
317 delete commands_[j]; | |
318 } | |
319 | |
320 throw OrthancException(ErrorCode_BadFileFormat); | |
321 } | |
322 } | |
323 } | |
324 | |
325 if (commands_.empty()) | |
326 { | |
327 if (position_ > 1) | |
328 { | |
329 throw OrthancException(ErrorCode_BadFileFormat); | |
330 } | |
331 } | |
332 else if (position_ > commands_.size()) | |
333 { | |
334 throw OrthancException(ErrorCode_BadFileFormat); | |
335 } | |
336 } | |
337 } |