Mercurial > hg > orthanc-stone
comparison Framework/Oracle/GenericOracleRunner.cpp @ 1077:d7a18a3cd6f9 broker
IOracleRunner
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Thu, 17 Oct 2019 16:51:41 +0200 |
parents | |
children | e6d2ff8f1ab4 |
comparison
equal
deleted
inserted
replaced
1076:008dbc4ceb62 | 1077:d7a18a3cd6f9 |
---|---|
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 | |
101 if (command.GetMethod() == Orthanc::HttpMethod_Post || | |
102 command.GetMethod() == Orthanc::HttpMethod_Put) | |
103 { | |
104 client.SetBody(command.GetBody()); | |
105 } | |
106 | |
107 std::string answer; | |
108 Orthanc::HttpClient::HttpHeaders answerHeaders; | |
109 client.ApplyAndThrowException(answer, answerHeaders); | |
110 | |
111 DecodeAnswer(answer, answerHeaders); | |
112 | |
113 HttpCommand::SuccessMessage message(command, answerHeaders, answer); | |
114 emitter.EmitMessage(receiver, message); | |
115 } | |
116 | |
117 | |
118 static void Execute(IMessageEmitter& emitter, | |
119 const Orthanc::WebServiceParameters& orthanc, | |
120 boost::weak_ptr<IObserver>& receiver, | |
121 const OrthancRestApiCommand& command) | |
122 { | |
123 Orthanc::HttpClient client(orthanc, command.GetUri()); | |
124 client.SetMethod(command.GetMethod()); | |
125 client.SetTimeout(command.GetTimeout()); | |
126 | |
127 CopyHttpHeaders(client, command.GetHttpHeaders()); | |
128 | |
129 if (command.GetMethod() == Orthanc::HttpMethod_Post || | |
130 command.GetMethod() == Orthanc::HttpMethod_Put) | |
131 { | |
132 client.SetBody(command.GetBody()); | |
133 } | |
134 | |
135 std::string answer; | |
136 Orthanc::HttpClient::HttpHeaders answerHeaders; | |
137 client.ApplyAndThrowException(answer, answerHeaders); | |
138 | |
139 DecodeAnswer(answer, answerHeaders); | |
140 | |
141 OrthancRestApiCommand::SuccessMessage message(command, answerHeaders, answer); | |
142 emitter.EmitMessage(receiver, message); | |
143 } | |
144 | |
145 | |
146 static void Execute(IMessageEmitter& emitter, | |
147 const Orthanc::WebServiceParameters& orthanc, | |
148 boost::weak_ptr<IObserver>& receiver, | |
149 const GetOrthancImageCommand& command) | |
150 { | |
151 Orthanc::HttpClient client(orthanc, command.GetUri()); | |
152 client.SetTimeout(command.GetTimeout()); | |
153 | |
154 CopyHttpHeaders(client, command.GetHttpHeaders()); | |
155 | |
156 std::string answer; | |
157 Orthanc::HttpClient::HttpHeaders answerHeaders; | |
158 client.ApplyAndThrowException(answer, answerHeaders); | |
159 | |
160 DecodeAnswer(answer, answerHeaders); | |
161 | |
162 command.ProcessHttpAnswer(emitter, receiver, answer, answerHeaders); | |
163 } | |
164 | |
165 | |
166 static void Execute(IMessageEmitter& emitter, | |
167 const Orthanc::WebServiceParameters& orthanc, | |
168 boost::weak_ptr<IObserver>& receiver, | |
169 const GetOrthancWebViewerJpegCommand& command) | |
170 { | |
171 Orthanc::HttpClient client(orthanc, command.GetUri()); | |
172 client.SetTimeout(command.GetTimeout()); | |
173 | |
174 CopyHttpHeaders(client, command.GetHttpHeaders()); | |
175 | |
176 std::string answer; | |
177 Orthanc::HttpClient::HttpHeaders answerHeaders; | |
178 client.ApplyAndThrowException(answer, answerHeaders); | |
179 | |
180 DecodeAnswer(answer, answerHeaders); | |
181 | |
182 command.ProcessHttpAnswer(emitter, receiver, answer); | |
183 } | |
184 | |
185 | |
186 void GenericOracleRunner::Run(boost::weak_ptr<IObserver>& receiver, | |
187 IOracleCommand& command) | |
188 { | |
189 try | |
190 { | |
191 switch (command.GetType()) | |
192 { | |
193 case IOracleCommand::Type_Sleep: | |
194 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadParameterType, | |
195 "Sleep command cannot be executed by the runner"); | |
196 break; | |
197 | |
198 case IOracleCommand::Type_Http: | |
199 Execute(emitter_, receiver, | |
200 dynamic_cast<const HttpCommand&>(command)); | |
201 break; | |
202 | |
203 case IOracleCommand::Type_OrthancRestApi: | |
204 Execute(emitter_, orthanc_, receiver, dynamic_cast<const OrthancRestApiCommand&>(command)); | |
205 break; | |
206 | |
207 case IOracleCommand::Type_GetOrthancImage: | |
208 Execute(emitter_, orthanc_, receiver, dynamic_cast<const GetOrthancImageCommand&>(command)); | |
209 break; | |
210 | |
211 case IOracleCommand::Type_GetOrthancWebViewerJpeg: | |
212 Execute(emitter_, orthanc_, receiver, dynamic_cast<const GetOrthancWebViewerJpegCommand&>(command)); | |
213 break; | |
214 | |
215 case IOracleCommand::Type_Custom: | |
216 dynamic_cast<CustomOracleCommand&>(command).Execute(emitter_, receiver, *this); | |
217 break; | |
218 | |
219 default: | |
220 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented); | |
221 } | |
222 } | |
223 catch (Orthanc::OrthancException& e) | |
224 { | |
225 LOG(ERROR) << "Exception within the oracle: " << e.What(); | |
226 emitter_.EmitMessage(receiver, OracleCommandExceptionMessage(command, e)); | |
227 } | |
228 catch (...) | |
229 { | |
230 LOG(ERROR) << "Threaded exception within the oracle"; | |
231 emitter_.EmitMessage(receiver, OracleCommandExceptionMessage | |
232 (command, Orthanc::ErrorCode_InternalError)); | |
233 } | |
234 } | |
235 } |