Accept an `grpc::ChannelArguments` argument in client's constructors.
Resolves #103. Signed-off-by: Tao He <sighingnow@gmail.com>
This commit is contained in:
parent
bfb56be151
commit
a23e156886
54
README.md
54
README.md
|
|
@ -81,7 +81,7 @@ Github when you encounter problems when working with etcd 3.x releases.
|
|||
## Usage
|
||||
|
||||
```c++
|
||||
etcd::Client etcd("http://127.0.0.1:4001");
|
||||
etcd::Client etcd("http://127.0.0.1:2379");
|
||||
etcd::Response response = etcd.get("/test/key1").get();
|
||||
std::cout << response.value().as_string();
|
||||
```
|
||||
|
|
@ -96,7 +96,7 @@ are blocking until the HTTP response arrives or some error situation happens. `g
|
|||
also returns the `etcd::Response` object.
|
||||
|
||||
```c++
|
||||
etcd::Client etcd("http://127.0.0.1:4001");
|
||||
etcd::Client etcd("http://127.0.0.1:2379");
|
||||
pplx::task<etcd::Response> response_task = etcd.get("/test/key1");
|
||||
// ... do something else
|
||||
etcd::Response response = response_task.get();
|
||||
|
|
@ -111,7 +111,7 @@ callback should be either a `etcd::Response` or a `pplx::task<etcd:Response>`. Y
|
|||
probably use a C++ lambda function here as a callback.
|
||||
|
||||
```c++
|
||||
etcd::Client etcd("http://127.0.0.1:4001");
|
||||
etcd::Client etcd("http://127.0.0.1:2379");
|
||||
etcd.get("/test/key1").then([](etcd::Response response)
|
||||
{
|
||||
std::cout << response.value().as_string();
|
||||
|
|
@ -127,7 +127,7 @@ how you can catch the errors generated by the REST interface. The `get()` call w
|
|||
this case since the response has been already arrived (we are inside the callback).
|
||||
|
||||
```c++
|
||||
etcd::Client etcd("http://127.0.0.1:4001");
|
||||
etcd::Client etcd("http://127.0.0.1:2379");
|
||||
etcd.get("/test/key1").then([](pplx::task<etcd::Response> response_task)
|
||||
{
|
||||
try
|
||||
|
|
@ -238,7 +238,7 @@ transport security using openssl.
|
|||
|
||||
We also provide a tool [`setup-ca.sh`](./security-config/setup-ca.sh) as a helper for development and testing.
|
||||
|
||||
#### transport security & Multiple endpoints
|
||||
#### transport security & multiple endpoints
|
||||
|
||||
If you want to use multiple `https://` endpoints, and you are working with self-signed certificates, you
|
||||
may encountered errors like
|
||||
|
|
@ -271,6 +271,36 @@ And pass a `target_name_override` arguments to `WithSSL`,
|
|||
For more discussion about this feature, see also [#87](https://github.com/etcd-cpp-apiv3/etcd-cpp-apiv3/issues/87),
|
||||
[grpc#20186](https://github.com/grpc/grpc/issues/20186) and [grpc#22119](https://github.com/grpc/grpc/issues/22119).
|
||||
|
||||
### Fine-grained gRPC channel arguments
|
||||
|
||||
By default the etcd-cpp-apiv3 library will set the following arguments for transport layer
|
||||
|
||||
+ `GRPC_ARG_MAX_SEND_MESSAGE_LENGTH` to `INT_MAX`
|
||||
+ `GRPC_ARG_MAX_RECEIVE_MESSAGE_LENGTH` to `INT_MAX`
|
||||
|
||||
If _load balancer strategy_ is specified, the following argument will be set
|
||||
|
||||
+ `GRPC_ARG_LB_POLICY_NAME`
|
||||
|
||||
When transport security is enabled and `target_name_override` is specified when working with SSL, the
|
||||
following argument will be set
|
||||
|
||||
+ `GRPC_SSL_TARGET_NAME_OVERRIDE_ARG`
|
||||
|
||||
Further, all variants of constructors for `etcd::Client` accepts an extra `grpc::ChannelArguments` argument
|
||||
which can be used for fine-grained control the gRPC settings, e.g.,
|
||||
|
||||
```cpp
|
||||
grpc::ChannelArguments grpc_args;
|
||||
grpc_args.SetInt(GRPC_ARG_KEEPALIVE_TIME_MS, 2000);
|
||||
grpc_args.SetInt(GRPC_ARG_KEEPALIVE_TIMEOUT_MS, 6000);
|
||||
grpc_args.SetInt(GRPC_ARG_KEEPALIVE_PERMIT_WITHOUT_CALLS, 1);
|
||||
|
||||
etcd::Client etcd("http://127.0.0.1:2379", grpc_args);
|
||||
```
|
||||
|
||||
For more motivation and discussion about the above design, please refer to [issue-103](https://github.com/etcd-cpp-apiv3/etcd-cpp-apiv3/issues/103).
|
||||
|
||||
### Reading a value
|
||||
|
||||
You can read a value with the `get()` method of the client instance. The only parameter is the
|
||||
|
|
@ -290,7 +320,7 @@ key. You can also get the index number of the creation and the last modification
|
|||
the `created_index()` and the `modified_index()` methods.
|
||||
|
||||
```c++
|
||||
etcd::Client etcd("http://127.0.0.1:4001");
|
||||
etcd::Client etcd("http://127.0.0.1:2379");
|
||||
pplx::task<etcd::Response> response_task = etcd.get("/test/key1");
|
||||
|
||||
try
|
||||
|
|
@ -317,7 +347,7 @@ what was the previous value that this operation was overwritten. You can do that
|
|||
`prev_value()` method of the response object.
|
||||
|
||||
```c++
|
||||
etcd::Client etcd("http://127.0.0.1:4001");
|
||||
etcd::Client etcd("http://127.0.0.1:2379");
|
||||
pplx::task<etcd::Response> response_task = etcd.set("/test/key1", "42");
|
||||
|
||||
try
|
||||
|
|
@ -407,7 +437,7 @@ keys defined by the prefix. mkdir method is removed since etcdv3 treats everythi
|
|||
returns with the i-th element of the values vector, so `response.values()[i] == response.value(i)`.
|
||||
|
||||
```c++
|
||||
etcd::Client etcd("http://127.0.0.1:4001");
|
||||
etcd::Client etcd("http://127.0.0.1:2379");
|
||||
etcd::Response resp = etcd.ls("/test/new_dir").get();
|
||||
for (int i = 0; i < resp.keys().size(); ++i)
|
||||
{
|
||||
|
|
@ -424,7 +454,7 @@ prefix will be deleted. All deleted keys will be placed in `response.values()` a
|
|||
`response.keys()`. This parameter defaults to `false`.
|
||||
|
||||
```c++
|
||||
etcd::Client etcd("http://127.0.0.1:4001");
|
||||
etcd::Client etcd("http://127.0.0.1:2379");
|
||||
etcd.set("/test/key1", "foo");
|
||||
etcd.set("/test/key2", "bar");
|
||||
etcd.set("/test/key3", "foo_bar");
|
||||
|
|
@ -444,7 +474,7 @@ The key supplied will NOT be treated as a prefix and will be treated as a normal
|
|||
Etcd lock has been supported as follows:
|
||||
|
||||
```c++
|
||||
etcd::Client etcd("http://127.0.0.1:4001");
|
||||
etcd::Client etcd("http://127.0.0.1:2379");
|
||||
etcd.lock("/test/lock");
|
||||
```
|
||||
|
||||
|
|
@ -454,7 +484,7 @@ the lock is unlocked.
|
|||
Users can also feed their own lease directory for lock:
|
||||
|
||||
```c++
|
||||
etcd::Client etcd("http://127.0.0.1:4001");
|
||||
etcd::Client etcd("http://127.0.0.1:2379");
|
||||
etcd.lock_with_lease("/test/lock", lease_id);
|
||||
```
|
||||
|
||||
|
|
@ -575,7 +605,7 @@ Moreover, user can attached the lease to a key(s) by indicating the lease id in
|
|||
server will be indicated in `ttl()`.
|
||||
|
||||
```c++
|
||||
etcd::Client etcd("http://127.0.0.1:4001");
|
||||
etcd::Client etcd("http://127.0.0.1:2379");
|
||||
etcd::Response resp = etcd.leasegrant(60).get();
|
||||
etcd.set("/test/key2", "bar", resp.value().lease());
|
||||
std::cout << "ttl" << resp.value().ttl();
|
||||
|
|
|
|||
|
|
@ -20,6 +20,10 @@ namespace etcdv3 {
|
|||
}
|
||||
}
|
||||
|
||||
namespace grpc {
|
||||
class ChannelArguments;
|
||||
}
|
||||
|
||||
#if defined(WITH_GRPC_CHANNEL_CLASS)
|
||||
namespace grpc {
|
||||
class Channel;
|
||||
|
|
@ -56,6 +60,16 @@ namespace etcd
|
|||
Client(std::string const & etcd_url,
|
||||
std::string const & load_balancer = "round_robin");
|
||||
|
||||
/**
|
||||
* Constructs an etcd client object.
|
||||
*
|
||||
* @param etcd_url is the url of the etcd server to connect to, like "http://127.0.0.1:2379",
|
||||
* or multiple url, seperated by ',' or ';'.
|
||||
* @param arguments user provided grpc channel arguments.
|
||||
*/
|
||||
Client(std::string const & etcd_url,
|
||||
grpc::ChannelArguments const & arguments);
|
||||
|
||||
/**
|
||||
* Constructs an etcd client object.
|
||||
*
|
||||
|
|
@ -66,6 +80,16 @@ namespace etcd
|
|||
static etcd::Client *WithUrl(std::string const & etcd_url,
|
||||
std::string const & load_balancer = "round_robin");
|
||||
|
||||
/**
|
||||
* Constructs an etcd client object.
|
||||
*
|
||||
* @param etcd_url is the url of the etcd server to connect to, like "http://127.0.0.1:2379",
|
||||
* or multiple url, seperated by ',' or ';'.
|
||||
* @param arguments user provided grpc channel arguments.
|
||||
*/
|
||||
static etcd::Client *WithUrl(std::string const & etcd_url,
|
||||
grpc::ChannelArguments const & arguments);
|
||||
|
||||
/**
|
||||
* Constructs an etcd client object.
|
||||
*
|
||||
|
|
@ -80,6 +104,20 @@ namespace etcd
|
|||
std::string const & password,
|
||||
std::string const & load_balancer = "round_robin");
|
||||
|
||||
/**
|
||||
* Constructs an etcd client object.
|
||||
*
|
||||
* @param etcd_url is the url of the etcd server to connect to, like "http://127.0.0.1:2379",
|
||||
* or multiple url, seperated by ',' or ';'.
|
||||
* @param username username of etcd auth
|
||||
* @param password password of etcd auth
|
||||
* @param arguments user provided grpc channel arguments.
|
||||
*/
|
||||
Client(std::string const & etcd_url,
|
||||
std::string const & username,
|
||||
std::string const & password,
|
||||
grpc::ChannelArguments const & arguments);
|
||||
|
||||
/**
|
||||
* Constructs an etcd client object.
|
||||
*
|
||||
|
|
@ -94,6 +132,20 @@ namespace etcd
|
|||
std::string const & password,
|
||||
std::string const & load_balancer = "round_robin");
|
||||
|
||||
/**
|
||||
* Constructs an etcd client object.
|
||||
*
|
||||
* @param etcd_url is the url of the etcd server to connect to, like "http://127.0.0.1:2379",
|
||||
* or multiple url, seperated by ',' or ';'.
|
||||
* @param username username of etcd auth
|
||||
* @param password password of etcd auth
|
||||
* @param arguments user provided grpc channel arguments.
|
||||
*/
|
||||
static etcd::Client *WithUser(std::string const & etcd_url,
|
||||
std::string const & username,
|
||||
std::string const & password,
|
||||
grpc::ChannelArguments const & arguments);
|
||||
|
||||
/**
|
||||
* Constructs an etcd client object.
|
||||
*
|
||||
|
|
@ -111,6 +163,23 @@ namespace etcd
|
|||
std::string const & target_name_override,
|
||||
std::string const & load_balancer);
|
||||
|
||||
/**
|
||||
* Constructs an etcd client object.
|
||||
*
|
||||
* @param etcd_url is the url of the etcd server to connect to, like "http://127.0.0.1:2379",
|
||||
* or multiple url, seperated by ',' or ';'.
|
||||
* @param ca root CA file for SSL/TLS connection.
|
||||
* @param cert cert chain file for SSL/TLS authentication, could be empty string.
|
||||
* @param key private key file for SSL/TLS authentication, could be empty string.
|
||||
* @param arguments user provided grpc channel arguments.
|
||||
*/
|
||||
Client(std::string const & etcd_url,
|
||||
std::string const & ca,
|
||||
std::string const & cert,
|
||||
std::string const & key,
|
||||
std::string const & target_name_override,
|
||||
grpc::ChannelArguments const & arguments);
|
||||
|
||||
/**
|
||||
* Constructs an etcd client object.
|
||||
*
|
||||
|
|
@ -131,6 +200,26 @@ namespace etcd
|
|||
std::string const & target_name_override = "",
|
||||
std::string const & load_balancer = "round_robin");
|
||||
|
||||
/**
|
||||
* Constructs an etcd client object.
|
||||
*
|
||||
* @param etcd_url is the url of the etcd server to connect to, like "http://127.0.0.1:2379",
|
||||
* or multiple url, seperated by ',' or ';'.
|
||||
* @param ca root CA file for SSL/TLS connection.
|
||||
* @param cert cert chain file for SSL/TLS authentication, could be empty string.
|
||||
* @param key private key file for SSL/TLS authentication, could be empty string.
|
||||
* @param target_name_override Override the target host name if you want to pass multiple address
|
||||
* for load balancing with SSL, and there's no DNS. The @target_name_override@ must exist in the
|
||||
* SANS of your SSL certificate.
|
||||
* @param arguments user provided grpc channel arguments.
|
||||
*/
|
||||
static etcd::Client *WithSSL(std::string const & etcd_url,
|
||||
grpc::ChannelArguments const & arguments,
|
||||
std::string const & ca,
|
||||
std::string const & cert = "",
|
||||
std::string const & key = "",
|
||||
std::string const & target_name_override = "");
|
||||
|
||||
/**
|
||||
* Get the HEAD revision of the connected etcd server.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -200,11 +200,36 @@ etcd::Client::Client(std::string const & address,
|
|||
stubs->electionServiceStub = Election::NewStub(this->channel);
|
||||
}
|
||||
|
||||
etcd::Client::Client(std::string const & address,
|
||||
grpc::ChannelArguments const & arguments)
|
||||
{
|
||||
// create channels
|
||||
std::string const addresses = etcd::detail::strip_and_resolve_addresses(address);
|
||||
grpc::ChannelArguments grpc_args = arguments;
|
||||
grpc_args.SetMaxSendMessageSize(std::numeric_limits<int>::max());
|
||||
grpc_args.SetMaxReceiveMessageSize(std::numeric_limits<int>::max());
|
||||
std::shared_ptr<grpc::ChannelCredentials> creds = grpc::InsecureChannelCredentials();
|
||||
this->channel = grpc::CreateCustomChannel(addresses, creds, grpc_args);
|
||||
|
||||
// create stubs
|
||||
stubs.reset(new EtcdServerStubs{});
|
||||
stubs->kvServiceStub = KV::NewStub(this->channel);
|
||||
stubs->watchServiceStub= Watch::NewStub(this->channel);
|
||||
stubs->leaseServiceStub= Lease::NewStub(this->channel);
|
||||
stubs->lockServiceStub = Lock::NewStub(this->channel);
|
||||
stubs->electionServiceStub = Election::NewStub(this->channel);
|
||||
}
|
||||
|
||||
etcd::Client *etcd::Client::WithUrl(std::string const & etcd_url,
|
||||
std::string const & load_balancer) {
|
||||
return new etcd::Client(etcd_url, load_balancer);
|
||||
}
|
||||
|
||||
etcd::Client *etcd::Client::WithUrl(std::string const & etcd_url,
|
||||
grpc::ChannelArguments const & arguments) {
|
||||
return new etcd::Client(etcd_url, arguments);
|
||||
}
|
||||
|
||||
etcd::Client::Client(std::string const & address,
|
||||
std::string const & username,
|
||||
std::string const & password,
|
||||
|
|
@ -235,6 +260,35 @@ etcd::Client::Client(std::string const & address,
|
|||
stubs->electionServiceStub = Election::NewStub(this->channel);
|
||||
}
|
||||
|
||||
etcd::Client::Client(std::string const & address,
|
||||
std::string const & username,
|
||||
std::string const & password,
|
||||
grpc::ChannelArguments const & arguments)
|
||||
{
|
||||
// create channels
|
||||
std::string const addresses = etcd::detail::strip_and_resolve_addresses(address);
|
||||
grpc::ChannelArguments grpc_args = arguments;
|
||||
grpc_args.SetMaxSendMessageSize(std::numeric_limits<int>::max());
|
||||
grpc_args.SetMaxReceiveMessageSize(std::numeric_limits<int>::max());
|
||||
std::shared_ptr<grpc::ChannelCredentials> creds = grpc::InsecureChannelCredentials();
|
||||
this->channel = grpc::CreateCustomChannel(addresses, creds, grpc_args);
|
||||
|
||||
// auth
|
||||
std::string token_or_message;
|
||||
if (!etcd::detail::authenticate(this->channel, username, password, token_or_message)) {
|
||||
throw std::invalid_argument("Etcd authentication failed: " + token_or_message);
|
||||
}
|
||||
this->auth_token = token_or_message;
|
||||
|
||||
// setup stubs
|
||||
stubs.reset(new EtcdServerStubs{});
|
||||
stubs->kvServiceStub = KV::NewStub(this->channel);
|
||||
stubs->watchServiceStub= Watch::NewStub(this->channel);
|
||||
stubs->leaseServiceStub= Lease::NewStub(this->channel);
|
||||
stubs->lockServiceStub = Lock::NewStub(this->channel);
|
||||
stubs->electionServiceStub = Election::NewStub(this->channel);
|
||||
}
|
||||
|
||||
etcd::Client *etcd::Client::WithUser(std::string const & etcd_url,
|
||||
std::string const & username,
|
||||
std::string const & password,
|
||||
|
|
@ -242,6 +296,14 @@ etcd::Client *etcd::Client::WithUser(std::string const & etcd_url,
|
|||
return new etcd::Client(etcd_url, username, password, load_balancer);
|
||||
}
|
||||
|
||||
etcd::Client *etcd::Client::WithUser(std::string const & etcd_url,
|
||||
std::string const & username,
|
||||
std::string const & password,
|
||||
grpc::ChannelArguments const & arguments) {
|
||||
return new etcd::Client(etcd_url, username, password, arguments);
|
||||
}
|
||||
|
||||
|
||||
etcd::Client::Client(std::string const & address,
|
||||
std::string const & ca,
|
||||
std::string const & cert,
|
||||
|
|
@ -271,6 +333,34 @@ etcd::Client::Client(std::string const & address,
|
|||
stubs->electionServiceStub = Election::NewStub(this->channel);
|
||||
}
|
||||
|
||||
etcd::Client::Client(std::string const & address,
|
||||
std::string const & ca,
|
||||
std::string const & cert,
|
||||
std::string const & key,
|
||||
std::string const & target_name_override,
|
||||
grpc::ChannelArguments const & arguments)
|
||||
{
|
||||
// create channels
|
||||
std::string const addresses = etcd::detail::strip_and_resolve_addresses(address);
|
||||
grpc::ChannelArguments grpc_args = arguments;
|
||||
grpc_args.SetMaxSendMessageSize(std::numeric_limits<int>::max());
|
||||
grpc_args.SetMaxReceiveMessageSize(std::numeric_limits<int>::max());
|
||||
std::shared_ptr<grpc::ChannelCredentials> creds = grpc::SslCredentials(
|
||||
etcd::detail::make_ssl_credentials(ca, cert, key));
|
||||
if (!target_name_override.empty()) {
|
||||
grpc_args.SetString(GRPC_SSL_TARGET_NAME_OVERRIDE_ARG, target_name_override);
|
||||
}
|
||||
this->channel = grpc::CreateCustomChannel(addresses, creds, grpc_args);
|
||||
|
||||
// setup stubs
|
||||
stubs.reset(new EtcdServerStubs{});
|
||||
stubs->kvServiceStub = KV::NewStub(this->channel);
|
||||
stubs->watchServiceStub= Watch::NewStub(this->channel);
|
||||
stubs->leaseServiceStub= Lease::NewStub(this->channel);
|
||||
stubs->lockServiceStub = Lock::NewStub(this->channel);
|
||||
stubs->electionServiceStub = Election::NewStub(this->channel);
|
||||
}
|
||||
|
||||
etcd::Client *etcd::Client::WithSSL(std::string const & etcd_url,
|
||||
std::string const & ca,
|
||||
std::string const & cert,
|
||||
|
|
@ -280,6 +370,15 @@ etcd::Client *etcd::Client::WithSSL(std::string const & etcd_url,
|
|||
return new etcd::Client(etcd_url, ca, cert, key, target_name_override, load_balancer);
|
||||
}
|
||||
|
||||
etcd::Client *etcd::Client::WithSSL(std::string const & etcd_url,
|
||||
grpc::ChannelArguments const & arguments,
|
||||
std::string const & ca,
|
||||
std::string const & cert,
|
||||
std::string const & key,
|
||||
std::string const & target_name_override) {
|
||||
return new etcd::Client(etcd_url, ca, cert, key, target_name_override, arguments);
|
||||
}
|
||||
|
||||
pplx::task<etcd::Response> etcd::Client::head()
|
||||
{
|
||||
etcdv3::ActionParameters params;
|
||||
|
|
|
|||
Loading…
Reference in New Issue