Add SoapAsyncClient.
This commit is contained in:
@@ -2,8 +2,8 @@
|
||||
|
||||
#include "json/json.h"
|
||||
|
||||
#include "webcc/rest_async_client.h"
|
||||
#include "webcc/logger.h"
|
||||
#include "webcc/rest_async_client.h"
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
@@ -50,7 +50,7 @@ class BookListClient {
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
class BookDetailClient {
|
||||
public:
|
||||
public:
|
||||
BookDetailClient(boost::asio::io_context& io_context,
|
||||
const std::string& host, const std::string& port)
|
||||
: rest_client_(io_context, host, port) {
|
||||
@@ -83,7 +83,7 @@ public:
|
||||
rest_client_.Delete("/book/" + id, handler);
|
||||
}
|
||||
|
||||
private:
|
||||
private:
|
||||
webcc::RestAsyncClient rest_client_;
|
||||
};
|
||||
|
||||
@@ -112,8 +112,7 @@ int main(int argc, char* argv[]) {
|
||||
BookDetailClient detail_client(io_context, host, port);
|
||||
|
||||
// Response handler.
|
||||
auto handler = [](std::shared_ptr<webcc::HttpResponse> response,
|
||||
webcc::Error error,
|
||||
auto handler = [](webcc::HttpResponsePtr response, webcc::Error error,
|
||||
bool timed_out) {
|
||||
if (error == webcc::kNoError) {
|
||||
std::cout << response->content() << std::endl;
|
||||
|
||||
@@ -23,7 +23,8 @@ BookClient::BookClient(const std::string& host, const std::string& port)
|
||||
soap_client_.set_indent_str(" ");
|
||||
}
|
||||
|
||||
bool BookClient::CreateBook(const std::string& title, double price, std::string* id) {
|
||||
bool BookClient::CreateBook(const std::string& title, double price,
|
||||
std::string* id) {
|
||||
PrintSeparateLine();
|
||||
std::cout << "CreateBook: " << title << ", " << price << std::endl;
|
||||
|
||||
@@ -91,7 +92,8 @@ bool BookClient::Call0(const std::string& operation, std::string* result_str) {
|
||||
}
|
||||
|
||||
|
||||
bool BookClient::Call1(const std::string& operation, webcc::SoapParameter&& parameter,
|
||||
bool BookClient::Call1(const std::string& operation,
|
||||
webcc::SoapParameter&& parameter,
|
||||
std::string* result_str) {
|
||||
std::vector<webcc::SoapParameter> parameters{
|
||||
{ std::move(parameter) }
|
||||
|
||||
@@ -65,6 +65,7 @@ endif()
|
||||
|
||||
if(WEBCC_ENABLE_SOAP)
|
||||
set(SOAP_HEADERS
|
||||
soap_async_client.h
|
||||
soap_client.h
|
||||
soap_message.h
|
||||
soap_parameter.h
|
||||
@@ -77,6 +78,7 @@ if(WEBCC_ENABLE_SOAP)
|
||||
)
|
||||
|
||||
set(SOAP_SOURCES
|
||||
soap_async_client.cc
|
||||
soap_client.cc
|
||||
soap_message.cc
|
||||
soap_response.cc
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
namespace webcc {
|
||||
|
||||
// Request handler/callback.
|
||||
// Response handler/callback.
|
||||
typedef std::function<void(HttpResponsePtr, Error, bool)> HttpResponseHandler;
|
||||
|
||||
class HttpAsyncClient : public std::enable_shared_from_this<HttpAsyncClient> {
|
||||
|
||||
@@ -12,8 +12,6 @@ void RestAsyncClient::Request(const std::string& method,
|
||||
const std::string& url,
|
||||
std::string&& content,
|
||||
HttpResponseHandler response_handler) {
|
||||
response_handler_ = response_handler;
|
||||
|
||||
HttpRequestPtr request(new webcc::HttpRequest());
|
||||
|
||||
request->set_method(method);
|
||||
@@ -33,7 +31,7 @@ void RestAsyncClient::Request(const std::string& method,
|
||||
http_client->set_timeout_seconds(timeout_seconds_);
|
||||
}
|
||||
|
||||
http_client->Request(request, response_handler_);
|
||||
http_client->Request(request, response_handler);
|
||||
}
|
||||
|
||||
} // namespace webcc
|
||||
|
||||
@@ -51,8 +51,6 @@ class RestAsyncClient {
|
||||
std::string host_;
|
||||
std::string port_;
|
||||
|
||||
HttpResponseHandler response_handler_;
|
||||
|
||||
// Timeout in seconds; only effective when > 0.
|
||||
int timeout_seconds_;
|
||||
};
|
||||
|
||||
+19
-15
@@ -24,21 +24,7 @@ class RestClient {
|
||||
timeout_seconds_ = timeout_seconds;
|
||||
}
|
||||
|
||||
HttpResponsePtr response() const { return response_; }
|
||||
|
||||
int response_status() const {
|
||||
assert(response_);
|
||||
return response_->status();
|
||||
}
|
||||
|
||||
const std::string& response_content() const {
|
||||
assert(response_);
|
||||
return response_->content();
|
||||
}
|
||||
|
||||
bool timed_out() const { return timed_out_; }
|
||||
|
||||
Error error() const { return error_; }
|
||||
// Requests
|
||||
|
||||
inline bool Get(const std::string& url) {
|
||||
return Request(kHttpGet, url, "");
|
||||
@@ -60,6 +46,24 @@ class RestClient {
|
||||
return Request(kHttpDelete, url, "");
|
||||
}
|
||||
|
||||
// Response & Result
|
||||
|
||||
HttpResponsePtr response() const { return response_; }
|
||||
|
||||
int response_status() const {
|
||||
assert(response_);
|
||||
return response_->status();
|
||||
}
|
||||
|
||||
const std::string& response_content() const {
|
||||
assert(response_);
|
||||
return response_->content();
|
||||
}
|
||||
|
||||
bool timed_out() const { return timed_out_; }
|
||||
|
||||
Error error() const { return error_; }
|
||||
|
||||
private:
|
||||
bool Request(const std::string& method, const std::string& url,
|
||||
std::string&& content);
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
#include "webcc/soap_async_client.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <utility> // for move()
|
||||
|
||||
#include "webcc/http_async_client.h"
|
||||
#include "webcc/soap_request.h"
|
||||
#include "webcc/soap_response.h"
|
||||
|
||||
namespace webcc {
|
||||
|
||||
SoapAsyncClient::SoapAsyncClient(boost::asio::io_context& io_context,
|
||||
const std::string& host,
|
||||
const std::string& port)
|
||||
: io_context_(io_context),
|
||||
host_(host), port_(port),
|
||||
soapenv_ns_(kSoapEnvNamespace),
|
||||
format_raw_(true), timeout_seconds_(0) {
|
||||
if (port_.empty()) {
|
||||
std::size_t i = host_.find_last_of(':');
|
||||
if (i != std::string::npos) {
|
||||
port_ = host_.substr(i + 1);
|
||||
host_ = host_.substr(0, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SoapAsyncClient::Request(const std::string& operation,
|
||||
std::vector<SoapParameter>&& parameters,
|
||||
SoapResponseHandler soap_response_handler) {
|
||||
assert(service_ns_.IsValid());
|
||||
assert(!url_.empty() && !host_.empty());
|
||||
assert(!result_name_.empty());
|
||||
|
||||
SoapRequest soap_request;
|
||||
|
||||
soap_request.set_soapenv_ns(soapenv_ns_);
|
||||
soap_request.set_service_ns(service_ns_);
|
||||
|
||||
soap_request.set_operation(operation);
|
||||
|
||||
for (SoapParameter& p : parameters) {
|
||||
soap_request.AddParameter(std::move(p));
|
||||
}
|
||||
|
||||
std::string http_content;
|
||||
soap_request.ToXml(format_raw_, indent_str_, &http_content);
|
||||
|
||||
HttpRequestPtr http_request;
|
||||
|
||||
http_request->set_method(kHttpPost);
|
||||
http_request->set_url(url_);
|
||||
http_request->SetContent(std::move(http_content), true);
|
||||
http_request->SetContentType(kTextXmlUtf8);
|
||||
http_request->SetHost(host_, port_);
|
||||
http_request->SetHeader(kSoapAction, operation);
|
||||
http_request->UpdateStartLine();
|
||||
|
||||
HttpAsyncClientPtr http_client(new HttpAsyncClient(io_context_));
|
||||
|
||||
if (timeout_seconds_ > 0) {
|
||||
http_client->set_timeout_seconds(timeout_seconds_);
|
||||
}
|
||||
|
||||
auto http_response_handler = std::bind(&SoapAsyncClient::ResponseHandler,
|
||||
this, soap_response_handler,
|
||||
std::placeholders::_1,
|
||||
std::placeholders::_2,
|
||||
std::placeholders::_3);
|
||||
|
||||
http_client->Request(http_request, http_response_handler);
|
||||
}
|
||||
|
||||
void SoapAsyncClient::ResponseHandler(SoapResponseHandler soap_response_handler,
|
||||
HttpResponsePtr http_response,
|
||||
Error error, bool timed_out) {
|
||||
if (error != kNoError) {
|
||||
soap_response_handler("", error, timed_out);
|
||||
} else {
|
||||
SoapResponse soap_response;
|
||||
soap_response.set_result_name(result_name_);
|
||||
|
||||
if (!soap_response.FromXml(http_response->content())) {
|
||||
soap_response_handler("", kXmlError, false);
|
||||
} else {
|
||||
soap_response_handler(soap_response.result_moved(), kNoError, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace webcc
|
||||
@@ -0,0 +1,85 @@
|
||||
#ifndef WEBCC_SOAP_ASYNC_CLIENT_H_
|
||||
#define WEBCC_SOAP_ASYNC_CLIENT_H_
|
||||
|
||||
#include <functional>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "webcc/http_async_client.h"
|
||||
#include "webcc/soap_message.h"
|
||||
#include "webcc/soap_parameter.h"
|
||||
|
||||
namespace webcc {
|
||||
|
||||
// Response handler/callback.
|
||||
typedef std::function<void(std::string, Error, bool)> SoapResponseHandler;
|
||||
|
||||
class SoapAsyncClient {
|
||||
public:
|
||||
// If |port| is empty, |host| will be checked to see if it contains port or
|
||||
// not (separated by ':').
|
||||
SoapAsyncClient(boost::asio::io_context& io_context, // NOLINT
|
||||
const std::string& host, const std::string& port = "");
|
||||
|
||||
~SoapAsyncClient() = default;
|
||||
|
||||
DELETE_COPY_AND_ASSIGN(SoapAsyncClient);
|
||||
|
||||
void set_timeout_seconds(int timeout_seconds) {
|
||||
timeout_seconds_ = timeout_seconds;
|
||||
}
|
||||
|
||||
void set_url(const std::string& url) { url_ = url; }
|
||||
|
||||
void set_service_ns(const SoapNamespace& service_ns) {
|
||||
service_ns_ = service_ns;
|
||||
}
|
||||
|
||||
void set_result_name(const std::string& result_name) {
|
||||
result_name_ = result_name;
|
||||
}
|
||||
|
||||
void set_format_raw(bool format_raw) { format_raw_ = format_raw; }
|
||||
|
||||
void set_indent_str(const std::string& indent_str) {
|
||||
indent_str_ = indent_str;
|
||||
}
|
||||
|
||||
void Request(const std::string& operation,
|
||||
std::vector<SoapParameter>&& parameters,
|
||||
SoapResponseHandler soap_response_handler);
|
||||
|
||||
private:
|
||||
void ResponseHandler(SoapResponseHandler soap_response_handler,
|
||||
HttpResponsePtr http_response,
|
||||
Error error, bool timed_out);
|
||||
|
||||
boost::asio::io_context& io_context_;
|
||||
|
||||
std::string host_;
|
||||
std::string port_; // Leave this empty to use default 80.
|
||||
|
||||
// Request URL.
|
||||
std::string url_;
|
||||
|
||||
SoapNamespace soapenv_ns_; // SOAP envelope namespace.
|
||||
SoapNamespace service_ns_; // Namespace for your web service.
|
||||
|
||||
// Response result XML node name.
|
||||
// E.g., "Result".
|
||||
std::string result_name_;
|
||||
|
||||
// Format request XML without any indentation or line breaks.
|
||||
bool format_raw_;
|
||||
|
||||
// Indent string for request XML.
|
||||
// Applicable when |format_raw_| is false.
|
||||
std::string indent_str_;
|
||||
|
||||
// Timeout in seconds; only effective when > 0.
|
||||
int timeout_seconds_;
|
||||
};
|
||||
|
||||
} // namespace webcc
|
||||
|
||||
#endif // WEBCC_SOAP_ASYNC_CLIENT_H_
|
||||
@@ -4,8 +4,6 @@
|
||||
#include <utility> // for move()
|
||||
|
||||
#include "webcc/http_client.h"
|
||||
#include "webcc/http_request.h"
|
||||
#include "webcc/http_response.h"
|
||||
#include "webcc/soap_request.h"
|
||||
#include "webcc/soap_response.h"
|
||||
|
||||
|
||||
+4
-4
@@ -39,14 +39,14 @@ class SoapClient {
|
||||
indent_str_ = indent_str;
|
||||
}
|
||||
|
||||
bool timed_out() const { return timed_out_; }
|
||||
|
||||
Error error() const { return error_; }
|
||||
|
||||
bool Request(const std::string& operation,
|
||||
std::vector<SoapParameter>&& parameters,
|
||||
std::string* result);
|
||||
|
||||
bool timed_out() const { return timed_out_; }
|
||||
|
||||
Error error() const { return error_; }
|
||||
|
||||
private:
|
||||
std::string host_;
|
||||
std::string port_; // Leave this empty to use default 80.
|
||||
|
||||
Reference in New Issue
Block a user