Mercurial > hg > orthanc-stone
annotate Framework/Oracle/GenericOracleRunner.cpp @ 1104:98cdfe5768a4 broker
ReadFileCommand
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Sat, 26 Oct 2019 16:43:08 +0200 |
parents | 17660df24c36 |
children | b82b74d13830 |
rev | line source |
---|---|
1077 | 1 /** |
2 * Stone of Orthanc | |
3 * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics | |
4 * Department, University Hospital of Liege, Belgium | |
5 * Copyright (C) 2017-2019 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 Affero General Public License | |
9 * as published by the Free Software Foundation, either version 3 of | |
10 * the License, or (at your option) any later version. | |
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 | |
15 * Affero General Public License for more details. | |
16 * | |
17 * You should have received a copy of the GNU Affero General Public License | |
18 * along with this program. If not, see <http://www.gnu.org/licenses/>. | |
19 **/ | |
20 | |
21 | |
22 #include "GenericOracleRunner.h" | |
23 | |
24 #include "CustomOracleCommand.h" | |
25 #include "GetOrthancImageCommand.h" | |
26 #include "GetOrthancWebViewerJpegCommand.h" | |
27 #include "HttpCommand.h" | |
28 #include "OracleCommandExceptionMessage.h" | |
29 #include "OrthancRestApiCommand.h" | |
1104 | 30 #include "ReadFileCommand.h" |
1077 | 31 |
32 #include <Core/Compression/GzipCompressor.h> | |
33 #include <Core/HttpClient.h> | |
34 #include <Core/OrthancException.h> | |
35 #include <Core/Toolbox.h> | |
1104 | 36 #include <Core/SystemToolbox.h> |
37 | |
38 #include <boost/filesystem.hpp> | |
1077 | 39 |
40 namespace OrthancStone | |
41 { | |
42 static void CopyHttpHeaders(Orthanc::HttpClient& client, | |
43 const Orthanc::HttpClient::HttpHeaders& headers) | |
44 { | |
45 for (Orthanc::HttpClient::HttpHeaders::const_iterator | |
46 it = headers.begin(); it != headers.end(); it++ ) | |
47 { | |
48 client.AddHeader(it->first, it->second); | |
49 } | |
50 } | |
51 | |
52 | |
53 static void DecodeAnswer(std::string& answer, | |
54 const Orthanc::HttpClient::HttpHeaders& headers) | |
55 { | |
56 Orthanc::HttpCompression contentEncoding = Orthanc::HttpCompression_None; | |
57 | |
58 for (Orthanc::HttpClient::HttpHeaders::const_iterator it = headers.begin(); | |
59 it != headers.end(); ++it) | |
60 { | |
61 std::string s; | |
62 Orthanc::Toolbox::ToLowerCase(s, it->first); | |
63 | |
64 if (s == "content-encoding") | |
65 { | |
66 if (it->second == "gzip") | |
67 { | |
68 contentEncoding = Orthanc::HttpCompression_Gzip; | |
69 } | |
70 else | |
71 { | |
72 throw Orthanc::OrthancException(Orthanc::ErrorCode_NetworkProtocol, | |
73 "Unsupported HTTP Content-Encoding: " + it->second); | |
74 } | |
75 | |
76 break; | |
77 } | |
78 } | |
79 | |
80 if (contentEncoding == Orthanc::HttpCompression_Gzip) | |
81 { | |
82 std::string compressed; | |
83 answer.swap(compressed); | |
84 | |
85 Orthanc::GzipCompressor compressor; | |
86 compressor.Uncompress(answer, compressed.c_str(), compressed.size()); | |
87 | |
88 LOG(INFO) << "Uncompressing gzip Encoding: from " << compressed.size() | |
89 << " to " << answer.size() << " bytes"; | |
90 } | |
91 } | |
92 | |
93 | |
1098
17660df24c36
simplification of IOracleRunner
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1079
diff
changeset
|
94 static IMessage* Execute(const HttpCommand& command) |
1077 | 95 { |
96 Orthanc::HttpClient client; | |
97 client.SetUrl(command.GetUrl()); | |
98 client.SetMethod(command.GetMethod()); | |
99 client.SetTimeout(command.GetTimeout()); | |
100 | |
101 CopyHttpHeaders(client, command.GetHttpHeaders()); | |
102 | |
1079
e6d2ff8f1ab4
credentials in HttpCommand
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1077
diff
changeset
|
103 if (command.HasCredentials()) |
e6d2ff8f1ab4
credentials in HttpCommand
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1077
diff
changeset
|
104 { |
e6d2ff8f1ab4
credentials in HttpCommand
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1077
diff
changeset
|
105 client.SetCredentials(command.GetUsername().c_str(), command.GetPassword().c_str()); |
e6d2ff8f1ab4
credentials in HttpCommand
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1077
diff
changeset
|
106 } |
e6d2ff8f1ab4
credentials in HttpCommand
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1077
diff
changeset
|
107 |
1077 | 108 if (command.GetMethod() == Orthanc::HttpMethod_Post || |
109 command.GetMethod() == Orthanc::HttpMethod_Put) | |
110 { | |
111 client.SetBody(command.GetBody()); | |
112 } | |
113 | |
114 std::string answer; | |
115 Orthanc::HttpClient::HttpHeaders answerHeaders; | |
116 client.ApplyAndThrowException(answer, answerHeaders); | |
117 | |
118 DecodeAnswer(answer, answerHeaders); | |
119 | |
1098
17660df24c36
simplification of IOracleRunner
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1079
diff
changeset
|
120 return new HttpCommand::SuccessMessage(command, answerHeaders, answer); |
1077 | 121 } |
122 | |
123 | |
1098
17660df24c36
simplification of IOracleRunner
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1079
diff
changeset
|
124 static IMessage* Execute(const Orthanc::WebServiceParameters& orthanc, |
17660df24c36
simplification of IOracleRunner
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1079
diff
changeset
|
125 const OrthancRestApiCommand& command) |
1077 | 126 { |
127 Orthanc::HttpClient client(orthanc, command.GetUri()); | |
128 client.SetMethod(command.GetMethod()); | |
129 client.SetTimeout(command.GetTimeout()); | |
130 | |
131 CopyHttpHeaders(client, command.GetHttpHeaders()); | |
132 | |
133 if (command.GetMethod() == Orthanc::HttpMethod_Post || | |
134 command.GetMethod() == Orthanc::HttpMethod_Put) | |
135 { | |
136 client.SetBody(command.GetBody()); | |
137 } | |
138 | |
139 std::string answer; | |
140 Orthanc::HttpClient::HttpHeaders answerHeaders; | |
141 client.ApplyAndThrowException(answer, answerHeaders); | |
142 | |
143 DecodeAnswer(answer, answerHeaders); | |
144 | |
1098
17660df24c36
simplification of IOracleRunner
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1079
diff
changeset
|
145 return new OrthancRestApiCommand::SuccessMessage(command, answerHeaders, answer); |
1077 | 146 } |
147 | |
148 | |
1098
17660df24c36
simplification of IOracleRunner
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1079
diff
changeset
|
149 static IMessage* Execute(const Orthanc::WebServiceParameters& orthanc, |
17660df24c36
simplification of IOracleRunner
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1079
diff
changeset
|
150 const GetOrthancImageCommand& command) |
1077 | 151 { |
152 Orthanc::HttpClient client(orthanc, command.GetUri()); | |
153 client.SetTimeout(command.GetTimeout()); | |
154 | |
155 CopyHttpHeaders(client, command.GetHttpHeaders()); | |
156 | |
157 std::string answer; | |
158 Orthanc::HttpClient::HttpHeaders answerHeaders; | |
159 client.ApplyAndThrowException(answer, answerHeaders); | |
160 | |
161 DecodeAnswer(answer, answerHeaders); | |
162 | |
1098
17660df24c36
simplification of IOracleRunner
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1079
diff
changeset
|
163 return command.ProcessHttpAnswer(answer, answerHeaders); |
1077 | 164 } |
165 | |
166 | |
1098
17660df24c36
simplification of IOracleRunner
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1079
diff
changeset
|
167 static IMessage* Execute(const Orthanc::WebServiceParameters& orthanc, |
17660df24c36
simplification of IOracleRunner
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1079
diff
changeset
|
168 const GetOrthancWebViewerJpegCommand& command) |
1077 | 169 { |
170 Orthanc::HttpClient client(orthanc, command.GetUri()); | |
171 client.SetTimeout(command.GetTimeout()); | |
172 | |
173 CopyHttpHeaders(client, command.GetHttpHeaders()); | |
174 | |
175 std::string answer; | |
176 Orthanc::HttpClient::HttpHeaders answerHeaders; | |
177 client.ApplyAndThrowException(answer, answerHeaders); | |
178 | |
179 DecodeAnswer(answer, answerHeaders); | |
180 | |
1098
17660df24c36
simplification of IOracleRunner
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1079
diff
changeset
|
181 return command.ProcessHttpAnswer(answer); |
1077 | 182 } |
183 | |
184 | |
1104 | 185 static IMessage* Execute(const std::string& root, |
186 const ReadFileCommand& command) | |
187 { | |
188 boost::filesystem::path a(root); | |
189 boost::filesystem::path b(command.GetPath()); | |
190 | |
191 boost::filesystem::path path; | |
192 if (b.is_absolute()) | |
193 { | |
194 path = b; | |
195 } | |
196 else | |
197 { | |
198 path = a / b; | |
199 } | |
200 | |
201 std::string content; | |
202 Orthanc::SystemToolbox::ReadFile(content, path.string(), true /* log */); | |
203 | |
204 return new ReadFileCommand::SuccessMessage(command, content); | |
205 } | |
206 | |
207 | |
1098
17660df24c36
simplification of IOracleRunner
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1079
diff
changeset
|
208 IMessage* GenericOracleRunner::Run(IOracleCommand& command) |
1077 | 209 { |
210 try | |
211 { | |
212 switch (command.GetType()) | |
213 { | |
214 case IOracleCommand::Type_Sleep: | |
215 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadParameterType, | |
216 "Sleep command cannot be executed by the runner"); | |
217 | |
218 case IOracleCommand::Type_Http: | |
1098
17660df24c36
simplification of IOracleRunner
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1079
diff
changeset
|
219 return Execute(dynamic_cast<const HttpCommand&>(command)); |
1077 | 220 |
221 case IOracleCommand::Type_OrthancRestApi: | |
1098
17660df24c36
simplification of IOracleRunner
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1079
diff
changeset
|
222 return Execute(orthanc_, dynamic_cast<const OrthancRestApiCommand&>(command)); |
1077 | 223 |
224 case IOracleCommand::Type_GetOrthancImage: | |
1098
17660df24c36
simplification of IOracleRunner
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1079
diff
changeset
|
225 return Execute(orthanc_, dynamic_cast<const GetOrthancImageCommand&>(command)); |
1077 | 226 |
227 case IOracleCommand::Type_GetOrthancWebViewerJpeg: | |
1098
17660df24c36
simplification of IOracleRunner
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1079
diff
changeset
|
228 return Execute(orthanc_, dynamic_cast<const GetOrthancWebViewerJpegCommand&>(command)); |
1077 | 229 |
230 case IOracleCommand::Type_Custom: | |
1098
17660df24c36
simplification of IOracleRunner
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1079
diff
changeset
|
231 return dynamic_cast<CustomOracleCommand&>(command).Execute(*this); |
1077 | 232 |
1104 | 233 case IOracleCommand::Type_ReadFile: |
234 return Execute(rootDirectory_, dynamic_cast<const ReadFileCommand&>(command)); | |
235 | |
1077 | 236 default: |
237 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented); | |
238 } | |
239 } | |
240 catch (Orthanc::OrthancException& e) | |
241 { | |
242 LOG(ERROR) << "Exception within the oracle: " << e.What(); | |
1098
17660df24c36
simplification of IOracleRunner
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1079
diff
changeset
|
243 return new OracleCommandExceptionMessage(command, e); |
1077 | 244 } |
245 catch (...) | |
246 { | |
247 LOG(ERROR) << "Threaded exception within the oracle"; | |
1098
17660df24c36
simplification of IOracleRunner
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1079
diff
changeset
|
248 return new OracleCommandExceptionMessage(command, Orthanc::ErrorCode_InternalError); |
1077 | 249 } |
250 } | |
251 } |