Mercurial > hg > orthanc-stone
annotate Framework/Oracle/GenericOracleRunner.cpp @ 1083:f72d1ab42932 broker
integration mainline->broker
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Tue, 22 Oct 2019 13:14:05 +0200 |
parents | e6d2ff8f1ab4 |
children | 17660df24c36 |
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" | |
30 | |
31 #include <Core/Compression/GzipCompressor.h> | |
32 #include <Core/HttpClient.h> | |
33 #include <Core/OrthancException.h> | |
34 #include <Core/Toolbox.h> | |
35 | |
36 namespace OrthancStone | |
37 { | |
38 static void CopyHttpHeaders(Orthanc::HttpClient& client, | |
39 const Orthanc::HttpClient::HttpHeaders& headers) | |
40 { | |
41 for (Orthanc::HttpClient::HttpHeaders::const_iterator | |
42 it = headers.begin(); it != headers.end(); it++ ) | |
43 { | |
44 client.AddHeader(it->first, it->second); | |
45 } | |
46 } | |
47 | |
48 | |
49 static void DecodeAnswer(std::string& answer, | |
50 const Orthanc::HttpClient::HttpHeaders& headers) | |
51 { | |
52 Orthanc::HttpCompression contentEncoding = Orthanc::HttpCompression_None; | |
53 | |
54 for (Orthanc::HttpClient::HttpHeaders::const_iterator it = headers.begin(); | |
55 it != headers.end(); ++it) | |
56 { | |
57 std::string s; | |
58 Orthanc::Toolbox::ToLowerCase(s, it->first); | |
59 | |
60 if (s == "content-encoding") | |
61 { | |
62 if (it->second == "gzip") | |
63 { | |
64 contentEncoding = Orthanc::HttpCompression_Gzip; | |
65 } | |
66 else | |
67 { | |
68 throw Orthanc::OrthancException(Orthanc::ErrorCode_NetworkProtocol, | |
69 "Unsupported HTTP Content-Encoding: " + it->second); | |
70 } | |
71 | |
72 break; | |
73 } | |
74 } | |
75 | |
76 if (contentEncoding == Orthanc::HttpCompression_Gzip) | |
77 { | |
78 std::string compressed; | |
79 answer.swap(compressed); | |
80 | |
81 Orthanc::GzipCompressor compressor; | |
82 compressor.Uncompress(answer, compressed.c_str(), compressed.size()); | |
83 | |
84 LOG(INFO) << "Uncompressing gzip Encoding: from " << compressed.size() | |
85 << " to " << answer.size() << " bytes"; | |
86 } | |
87 } | |
88 | |
89 | |
90 static void Execute(IMessageEmitter& emitter, | |
91 boost::weak_ptr<IObserver>& receiver, | |
92 const HttpCommand& command) | |
93 { | |
94 Orthanc::HttpClient client; | |
95 client.SetUrl(command.GetUrl()); | |
96 client.SetMethod(command.GetMethod()); | |
97 client.SetTimeout(command.GetTimeout()); | |
98 | |
99 CopyHttpHeaders(client, command.GetHttpHeaders()); | |
100 | |
1079
e6d2ff8f1ab4
credentials in HttpCommand
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1077
diff
changeset
|
101 if (command.HasCredentials()) |
e6d2ff8f1ab4
credentials in HttpCommand
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1077
diff
changeset
|
102 { |
e6d2ff8f1ab4
credentials in HttpCommand
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1077
diff
changeset
|
103 client.SetCredentials(command.GetUsername().c_str(), command.GetPassword().c_str()); |
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 |
1077 | 106 if (command.GetMethod() == Orthanc::HttpMethod_Post || |
107 command.GetMethod() == Orthanc::HttpMethod_Put) | |
108 { | |
109 client.SetBody(command.GetBody()); | |
110 } | |
111 | |
112 std::string answer; | |
113 Orthanc::HttpClient::HttpHeaders answerHeaders; | |
114 client.ApplyAndThrowException(answer, answerHeaders); | |
115 | |
116 DecodeAnswer(answer, answerHeaders); | |
117 | |
118 HttpCommand::SuccessMessage message(command, answerHeaders, answer); | |
119 emitter.EmitMessage(receiver, message); | |
120 } | |
121 | |
122 | |
123 static void Execute(IMessageEmitter& emitter, | |
124 const Orthanc::WebServiceParameters& orthanc, | |
125 boost::weak_ptr<IObserver>& receiver, | |
126 const OrthancRestApiCommand& command) | |
127 { | |
128 Orthanc::HttpClient client(orthanc, command.GetUri()); | |
129 client.SetMethod(command.GetMethod()); | |
130 client.SetTimeout(command.GetTimeout()); | |
131 | |
132 CopyHttpHeaders(client, command.GetHttpHeaders()); | |
133 | |
134 if (command.GetMethod() == Orthanc::HttpMethod_Post || | |
135 command.GetMethod() == Orthanc::HttpMethod_Put) | |
136 { | |
137 client.SetBody(command.GetBody()); | |
138 } | |
139 | |
140 std::string answer; | |
141 Orthanc::HttpClient::HttpHeaders answerHeaders; | |
142 client.ApplyAndThrowException(answer, answerHeaders); | |
143 | |
144 DecodeAnswer(answer, answerHeaders); | |
145 | |
146 OrthancRestApiCommand::SuccessMessage message(command, answerHeaders, answer); | |
147 emitter.EmitMessage(receiver, message); | |
148 } | |
149 | |
150 | |
151 static void Execute(IMessageEmitter& emitter, | |
152 const Orthanc::WebServiceParameters& orthanc, | |
153 boost::weak_ptr<IObserver>& receiver, | |
154 const GetOrthancImageCommand& command) | |
155 { | |
156 Orthanc::HttpClient client(orthanc, command.GetUri()); | |
157 client.SetTimeout(command.GetTimeout()); | |
158 | |
159 CopyHttpHeaders(client, command.GetHttpHeaders()); | |
160 | |
161 std::string answer; | |
162 Orthanc::HttpClient::HttpHeaders answerHeaders; | |
163 client.ApplyAndThrowException(answer, answerHeaders); | |
164 | |
165 DecodeAnswer(answer, answerHeaders); | |
166 | |
167 command.ProcessHttpAnswer(emitter, receiver, answer, answerHeaders); | |
168 } | |
169 | |
170 | |
171 static void Execute(IMessageEmitter& emitter, | |
172 const Orthanc::WebServiceParameters& orthanc, | |
173 boost::weak_ptr<IObserver>& receiver, | |
174 const GetOrthancWebViewerJpegCommand& command) | |
175 { | |
176 Orthanc::HttpClient client(orthanc, command.GetUri()); | |
177 client.SetTimeout(command.GetTimeout()); | |
178 | |
179 CopyHttpHeaders(client, command.GetHttpHeaders()); | |
180 | |
181 std::string answer; | |
182 Orthanc::HttpClient::HttpHeaders answerHeaders; | |
183 client.ApplyAndThrowException(answer, answerHeaders); | |
184 | |
185 DecodeAnswer(answer, answerHeaders); | |
186 | |
187 command.ProcessHttpAnswer(emitter, receiver, answer); | |
188 } | |
189 | |
190 | |
191 void GenericOracleRunner::Run(boost::weak_ptr<IObserver>& receiver, | |
192 IOracleCommand& command) | |
193 { | |
194 try | |
195 { | |
196 switch (command.GetType()) | |
197 { | |
198 case IOracleCommand::Type_Sleep: | |
199 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadParameterType, | |
200 "Sleep command cannot be executed by the runner"); | |
201 break; | |
202 | |
203 case IOracleCommand::Type_Http: | |
1079
e6d2ff8f1ab4
credentials in HttpCommand
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1077
diff
changeset
|
204 Execute(emitter_, receiver, dynamic_cast<const HttpCommand&>(command)); |
1077 | 205 break; |
206 | |
207 case IOracleCommand::Type_OrthancRestApi: | |
208 Execute(emitter_, orthanc_, receiver, dynamic_cast<const OrthancRestApiCommand&>(command)); | |
209 break; | |
210 | |
211 case IOracleCommand::Type_GetOrthancImage: | |
212 Execute(emitter_, orthanc_, receiver, dynamic_cast<const GetOrthancImageCommand&>(command)); | |
213 break; | |
214 | |
215 case IOracleCommand::Type_GetOrthancWebViewerJpeg: | |
216 Execute(emitter_, orthanc_, receiver, dynamic_cast<const GetOrthancWebViewerJpegCommand&>(command)); | |
217 break; | |
218 | |
219 case IOracleCommand::Type_Custom: | |
220 dynamic_cast<CustomOracleCommand&>(command).Execute(emitter_, receiver, *this); | |
221 break; | |
222 | |
223 default: | |
224 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented); | |
225 } | |
226 } | |
227 catch (Orthanc::OrthancException& e) | |
228 { | |
229 LOG(ERROR) << "Exception within the oracle: " << e.What(); | |
230 emitter_.EmitMessage(receiver, OracleCommandExceptionMessage(command, e)); | |
231 } | |
232 catch (...) | |
233 { | |
234 LOG(ERROR) << "Threaded exception within the oracle"; | |
235 emitter_.EmitMessage(receiver, OracleCommandExceptionMessage | |
236 (command, Orthanc::ErrorCode_InternalError)); | |
237 } | |
238 } | |
239 } |