Refine source code, improve the quality and readability.

Signed-off-by: Tao He <sighingnow@gmail.com>
This commit is contained in:
Tao He 2021-09-15 14:18:04 +08:00
parent 42c2fdf58c
commit 4d6d0e2732
42 changed files with 344 additions and 251 deletions

View File

@ -125,10 +125,9 @@ install (FILES ${CMAKE_CURRENT_SOURCE_DIR}/etcd/Client.hpp
${CMAKE_CURRENT_SOURCE_DIR}/etcd/Response.hpp ${CMAKE_CURRENT_SOURCE_DIR}/etcd/Response.hpp
${CMAKE_CURRENT_SOURCE_DIR}/etcd/Value.hpp ${CMAKE_CURRENT_SOURCE_DIR}/etcd/Value.hpp
${CMAKE_CURRENT_SOURCE_DIR}/etcd/Watcher.hpp ${CMAKE_CURRENT_SOURCE_DIR}/etcd/Watcher.hpp
${CMAKE_CURRENT_BINARY_DIR}/proto/gen/proto/kv.pb.h
DESTINATION include/etcd) DESTINATION include/etcd)
install (FILES ${CMAKE_CURRENT_SOURCE_DIR}/etcd/v3/Transaction.hpp install (FILES ${CMAKE_CURRENT_SOURCE_DIR}/etcd/v3/action_constants.hpp
${CMAKE_CURRENT_BINARY_DIR}/proto/gen/proto/txn.pb.h ${CMAKE_CURRENT_SOURCE_DIR}/etcd/v3/Transaction.hpp
DESTINATION include/etcd/v3) DESTINATION include/etcd/v3)
configure_file(etcd-cpp-api-config.in.cmake configure_file(etcd-cpp-api-config.in.cmake
@ -201,8 +200,8 @@ set(CPACK_DEBIAN_PACKAGE_INSTALL "/usr/lib/lib*.so*"
"/usr/lib/cmake/etcd-cpp-api/*.cmake" "/usr/lib/cmake/etcd-cpp-api/*.cmake"
"/usr/include/etcd/*.h" "/usr/include/etcd/*.h"
"/usr/include/etcd/*.hpp" "/usr/include/etcd/*.hpp"
"/usr/include/etcd/v3/*.h" "/usr/include/etcd/v3/action_constants.hpp"
"/usr/include/etcd/v3/*.hpp" "/usr/include/etcd/v3/Transaction.hpp"
) )
set(CPACK_DEBIAN_PACKAGE_BUILD_NUMBER_PREFIX "") set(CPACK_DEBIAN_PACKAGE_BUILD_NUMBER_PREFIX "")

111
README.md
View File

@ -11,9 +11,11 @@ i.e., `ETCDCTL_API=3`.
+ **Linux** + **Linux**
- Ubuntu 18.04, requires upgrade gRPC libraries (has been tested with 1.27.x). - Ubuntu 18.04, requires upgrade gRPC libraries (has been tested with 1.27.x).
- Ubuntu 20.04 - Ubuntu 20.04
+ **MacOS** + **MacOS**
- MacOS 10.15 - MacOS 10.15
- MacOS 11.0 - MacOS 11.0
+ **Windows** + **Windows**
- Windows 10, with [vcpkg](https://github.com/microsoft/vcpkg) - Windows 10, with [vcpkg](https://github.com/microsoft/vcpkg)
@ -85,13 +87,13 @@ Github when you encounter problems when working with etcd 3.x releases.
``` ```
Methods of the etcd client object are sending the corresponding gRPC requests and are returning Methods of the etcd client object are sending the corresponding gRPC requests and are returning
immediately with a ```pplx::task``` object. The task object is responsible for handling the immediately with a `pplx::task` object. The task object is responsible for handling the
reception of the HTTP response as well as parsing the gRPC of the response. All of this is done reception of the HTTP response as well as parsing the gRPC of the response. All of this is done
asynchronously in a background thread so you can continue your code to do other operations while the asynchronously in a background thread so you can continue your code to do other operations while the
current etcd operation is executing in the background or you can wait for the response with the current etcd operation is executing in the background or you can wait for the response with the
```wait()``` or ```get()``` methods if a synchronous behavior is enough for your needs. These methods `wait()` or `get()` methods if a synchronous behavior is enough for your needs. These methods
are blocking until the HTTP response arrives or some error situation happens. ```get()``` method are blocking until the HTTP response arrives or some error situation happens. `get()` method
also returns the ```etcd::Response``` object. also returns the `etcd::Response` object.
```c++ ```c++
etcd::Client etcd("http://127.0.0.1:4001"); etcd::Client etcd("http://127.0.0.1:4001");
@ -103,9 +105,9 @@ also returns the ```etcd::Response``` object.
The pplx library allows to do even more. You can attach continuation objects to the task if you do The pplx library allows to do even more. You can attach continuation objects to the task if you do
not care about when the response is coming you only want to specify what to do then. This not care about when the response is coming you only want to specify what to do then. This
can be achieved by calling the ```then``` method of the task, giving a function object parameter to can be achieved by calling the `then` method of the task, giving a function object parameter to
it that can be used as a callback when the response is arrived and processed. The parameter of this it that can be used as a callback when the response is arrived and processed. The parameter of this
callback should be either a ```etcd::Response``` or a ```pplx::task<etcd:Response>```. You should callback should be either a `etcd::Response` or a `pplx::task<etcd:Response>`. You should
probably use a C++ lambda function here as a callback. probably use a C++ lambda function here as a callback.
```c++ ```c++
@ -118,10 +120,10 @@ probably use a C++ lambda function here as a callback.
// ... your code can continue here without any delay // ... your code can continue here without any delay
``` ```
Your lambda function should have a parameter of type ```etcd::Response``` or Your lambda function should have a parameter of type `etcd::Response` or
```pplx::task<etcd::Response>```. In the latter case you can get the actual ```etcd::Response``` `pplx::task<etcd::Response>`. In the latter case you can get the actual `etcd::Response`
object with the ```get()``` function of the task. Calling get can raise exceptions so this is the way object with the `get()` function of the task. Calling get can raise exceptions so this is the way
how you can catch the errors generated by the REST interface. The ```get()``` call will not block in how you can catch the errors generated by the REST interface. The `get()` call will not block in
this case since the response has been already arrived (we are inside the callback). this case since the response has been already arrived (we are inside the callback).
```c++ ```c++
@ -238,21 +240,21 @@ We also provide a tool [`setup-ca.sh`](./security-config/setup-ca.sh) as a helpe
### Reading a value ### Reading a value
You can read a value with the ```get``` method of the client instance. The only parameter is the You can read a value with the `get()` method of the client instance. The only parameter is the
key to be read. If the read operation is successful then the value of the key can be acquired with key to be read. If the read operation is successful then the value of the key can be acquired with
the ```value()``` method of the response. Success of the operation can be checked with the the `value()` method of the response. Success of the operation can be checked with the
```is_ok()``` method of the response. In case of an error, the ```error_code()``` and `is_ok()` method of the response. In case of an error, the `error_code()` and
```error_message()``` methods can be called for some further detail. `error_message()` methods can be called for some further detail.
Please note that there can be two kind of error situations. There can be some problem with the Please note that there can be two kind of error situations. There can be some problem with the
communication between the client and the etcd server. In this case the ```get()``` method of the communication between the client and the etcd server. In this case the `get()``` method of the
response task will throw an exception as shown above. If the communication is ok but there is some response task will throw an exception as shown above. If the communication is ok but there is some
problem with the content of the actual operation, like attempting to read a non-existing key then the problem with the content of the actual operation, like attempting to read a non-existing key then the
response object will give you all the details. Let's see this in an example. response object will give you all the details. Let's see this in an example.
The Value object of the response also holds some extra information besides the string value of the The Value object of the response also holds some extra information besides the string value of the
key. You can also get the index number of the creation and the last modification of this key with key. You can also get the index number of the creation and the last modification of this key with
the ```created_index()``` and the ```modified_index()``` methods. the `created_index()` and the `modified_index()` methods.
```c++ ```c++
etcd::Client etcd("http://127.0.0.1:4001"); etcd::Client etcd("http://127.0.0.1:4001");
@ -274,12 +276,12 @@ the ```created_index()``` and the ```modified_index()``` methods.
### Modifying a value ### Modifying a value
Setting the value of a key can be done with the ```set()``` method of the client. You simply pass Setting the value of a key can be done with the `set()` method of the client. You simply pass
the key and the value as string parameters and you are done. The newly set value object can be asked the key and the value as string parameters and you are done. The newly set value object can be asked
from the response object exactly the same way as in case of the reading (with the ```value()``` from the response object exactly the same way as in case of the reading (with the `value()`
method). This way you can check for example the index value of your modification. You can also check method). This way you can check for example the index value of your modification. You can also check
what was the previous value that this operation was overwritten. You can do that with the what was the previous value that this operation was overwritten. You can do that with the
```prev_value()``` method of the response object. `prev_value()` method of the response object.
```c++ ```c++
etcd::Client etcd("http://127.0.0.1:4001"); etcd::Client etcd("http://127.0.0.1:4001");
@ -304,28 +306,28 @@ The set method creates a new leaf node if it weren't exists already or modifies
There are a couple of other modification methods that are executing the write operation only upon There are a couple of other modification methods that are executing the write operation only upon
some specific conditions. some specific conditions.
* ```add(key, value)``` creates a new value if it's key does not exists and returns a "Key * `add(key, value)` creates a new value if it's key does not exists and returns a "Key
already exists" error otherwise (error code 105) already exists" error otherwise (error code `ERROR_KEY_ALREADY_EXISTS`)
* ```modify(key, value)``` modifies an already existing value or returns a "Key not found" error * `modify(key, value)` modifies an already existing value or returns a "Key not found" error
otherwise (error code 100) otherwise (error code `KEY_NOT_FOUND`)
* ```modify_if(key, value, old_value)``` modifies an already existing value but only if the previous * `modify_if(key, value, old_value)` modifies an already existing value but only if the previous
value equals with old_value. If the values does not match returns with "Compare failed" error value equals with old_value. If the values does not match returns with "Compare failed" error
(code 101) (code `ERROR_COMPARE_FAILED`)
* ```modify_if(key, value, old_index)``` modifies an already existing value but only if the index of * `modify_if(key, value, old_index)` modifies an already existing value but only if the index of
the previous value equals with old_index. If the indices does not match returns with "Compare the previous value equals with old_index. If the indices does not match returns with "Compare
failed" error (code 101) failed" error (code `ERROR_COMPARE_FAILED`)
### Deleting a value ### Deleting a value
Values can be deleted with the ```rm``` method passing the key to be deleted as a parameter. The key Values can be deleted with the `rm` method passing the key to be deleted as a parameter. The key
should point to an existing value. There are conditional variations for deletion too. should point to an existing value. There are conditional variations for deletion too.
* ```rm_if(key, value, old_value)``` deletes an already existing value but only if the previous * `rm_if(key, value, old_value)` deletes an already existing value but only if the previous
value equals with old_value. If the values does not match returns with "Compare failed" error value equals with old_value. If the values does not match returns with "Compare failed" error
(code 101) (code `ERROR_COMPARE_FAILED`)
* ```rm_if(key, value, old_index)``` deletes an already existing value but only if the index of * `rm_if(key, value, old_index)` deletes an already existing value but only if the index of
the previous value equals with old_index. If the indices does not match returns with "Compare the previous value equals with old_index. If the indices does not match returns with "Compare
failed" error (code 101) failed" error (code `ERROR_COMPARE_FAILED`)
### Handling directory nodes ### Handling directory nodes
@ -367,10 +369,9 @@ keys defined by the prefix. mkdir method is removed since etcdv3 treats everythi
+ While in etcdv2 cpp client it will return "key1" and "/test/new_dir" directory should + While in etcdv2 cpp client it will return "key1" and "/test/new_dir" directory should
be created first before you can set "key1". be created first before you can set "key1".
When you list a directory the response object's ```keys()``` and ```values()``` methods gives When you list a directory the response object's `keys()` and `values()` methods gives
you a vector of key names and values. The ```value()``` method with an integer parameter also you a vector of key names and values. The `value()` method with an integer parameter also
returns with the i-th element of the values vector, so ```response.values()[i] == returns with the i-th element of the values vector, so `response.values()[i] == response.value(i)`.
response.value(i)```.
```c++ ```c++
etcd::Client etcd("http://127.0.0.1:4001"); etcd::Client etcd("http://127.0.0.1:4001");
@ -384,10 +385,10 @@ keys defined by the prefix. mkdir method is removed since etcdv3 treats everythi
3. Removing directory: 3. Removing directory:
If you want the delete recursively then you have to pass a second ```true``` parameter If you want the delete recursively then you have to pass a second `true` parameter
to rmdir and supply a key. This key will be treated as a prefix. All keys that match the to rmdir and supply a key. This key will be treated as a prefix. All keys that match the
prefix will be deleted. All deleted keys will be placed in ```response.values()``` and prefix will be deleted. All deleted keys will be placed in `response.values()` and
```response.keys()```. This parameter defaults to ```false```. `response.keys()`. This parameter defaults to `false`.
```c++ ```c++
etcd::Client etcd("http://127.0.0.1:4001"); etcd::Client etcd("http://127.0.0.1:4001");
@ -426,22 +427,22 @@ Users can also feed their own lease directory for lock:
### Watching for changes ### Watching for changes
Watching for a change is possible with the ```watch()``` operation of the client. The watch method Watching for a change is possible with the `watch()` operation of the client. The watch method
simply does not deliver a response object until the watched value changes in any way (modified or simply does not deliver a response object until the watched value changes in any way (modified or
deleted). When a change happens the returned result object will be the same as the result object of deleted). When a change happens the returned result object will be the same as the result object of
the modification operation. So if the change is triggered by a value change, then the modification operation. So if the change is triggered by a value change, then
```response.action()``` will return "set", ```response.value()``` will hold the new `response.action()` will return "set", `response.value()` will hold the new
value and ```response.prev_value()``` will contain the previous value. In case of a delete value and `response.prev_value()` will contain the previous value. In case of a delete
```response.action()``` will return "delete", ```response.value()``` will be empty and should not be `response.action()` will return "delete", `response.value()` will be empty and should not be
called at all and ```response.prev_value()``` will contain the deleted value. called at all and `response.prev_value()` will contain the deleted value.
As mentioned in the section "handling directory nodes", directory nodes are not supported anymore As mentioned in the section "handling directory nodes", directory nodes are not supported anymore
in etcdv3. in etcdv3.
However it is still possible to watch a whole "directory subtree", or more specifically a set of However it is still possible to watch a whole "directory subtree", or more specifically a set of
keys that match the prefix, for changes with passing ```true``` to the second ```recursive``` keys that match the prefix, for changes with passing `true` to the second `recursive`
parameter of ```watch``` (this parameter defaults to ```false``` if omitted). In this case the parameter of `watch` (this parameter defaults to `false` if omitted). In this case the
modified value object's ```key()``` method can be handy to determine what key is actually changed. modified value object's `key()` method can be handy to determine what key is actually changed.
Since this can be a long lasting operation you have to be prepared that is terminated by an Since this can be a long lasting operation you have to be prepared that is terminated by an
exception and you have to restart the watch operation. exception and you have to restart the watch operation.
@ -468,17 +469,17 @@ void watch_for_changes()
} }
``` ```
At first glance it seems that ```watch_for_changes()``` calls itself on every value change but in At first glance it seems that `watch_for_changes()` calls itself on every value change but in
fact it just sends the asynchronous request, sets up a callback for the response and then returns. The fact it just sends the asynchronous request, sets up a callback for the response and then returns. The
callback is executed by some thread from the pplx library's thread pool and the callback (in this callback is executed by some thread from the pplx library's thread pool and the callback (in this
case a small lambda function actually) will call ```watch_for_changes``` again from there. case a small lambda function actually) will call `watch_for_changes()` again from there.
#### Watcher Class #### Watcher Class
Users can watch a key indefinitely or until user cancels the watch. This can be done by Users can watch a key indefinitely or until user cancels the watch. This can be done by
instantiating a Watcher class. The supplied callback function in Watcher class will be instantiating a Watcher class. The supplied callback function in Watcher class will be
called every time there is an event for the specified key. Watch stream will be cancelled called every time there is an event for the specified key. Watch stream will be cancelled
either by user implicitly calling ```Cancel()``` or when watcher class is destroyed. either by user implicitly calling `Cancel()` or when watcher class is destroyed.
```c++ ```c++
etcd::Watcher watcher("http://127.0.0.1:2379", "/test", printResponse); etcd::Watcher watcher("http://127.0.0.1:2379", "/test", printResponse);
@ -491,7 +492,9 @@ either by user implicitly calling ```Cancel()``` or when watcher class is destro
#### Watcher re-connection #### Watcher re-connection
A watcher will be disconnected from etcd server in some cases, for some examples, the etcd server is restarted, or the network is temporarily unavailable. It is users' responsibility to decide if a watcher should re-connect to the etcd server. A watcher will be disconnected from etcd server in some cases, for some examples, the etcd
server is restarted, or the network is temporarily unavailable. It is users' responsibility
to decide if a watcher should re-connect to the etcd server.
Here is an example how users can make a watcher re-connect to server after disconnected. Here is an example how users can make a watcher re-connect to server after disconnected.
@ -534,9 +537,9 @@ initialize_watcher(endpoints, prefix, callback, watcher);
### Requesting for lease ### Requesting for lease
Users can request for lease which is governed by a time-to-live(TTL) value given by the user. Users can request for lease which is governed by a time-to-live(TTL) value given by the user.
Moreover, user can attached the lease to a key(s) by indicating the lease id in ```add()```, Moreover, user can attached the lease to a key(s) by indicating the lease id in `add()`,
```set()```, ```modify()``` and ```modify_if()```. Also the ttl will that was granted by etcd `set()`, `modify()` and `modify_if()`. Also the ttl will that was granted by etcd
server will be indicated in ```ttl()```. server will be indicated in `ttl()`.
```c++ ```c++
etcd::Client etcd("http://127.0.0.1:4001"); etcd::Client etcd("http://127.0.0.1:4001");

View File

@ -8,6 +8,7 @@
#include "pplx/pplxtasks.h" #include "pplx/pplxtasks.h"
#include "etcd/Response.hpp" #include "etcd/Response.hpp"
#include "etcd/v3/action_constants.hpp"
namespace etcdv3 { namespace etcdv3 {
class Transaction; class Transaction;
@ -29,6 +30,10 @@ namespace grpc_impl {
namespace etcd namespace etcd
{ {
using etcdv3::ERROR_KEY_NOT_FOUND;
using etcdv3::ERROR_COMPARE_FAILED;
using etcdv3::ERROR_KEY_ALREADY_EXISTS;
class KeepAlive; class KeepAlive;
class Watcher; class Watcher;

View File

@ -18,7 +18,7 @@ using v3lockpb::Lock;
namespace etcdv3 namespace etcdv3
{ {
enum Atomicity_Type enum AtomicityType
{ {
PREV_INDEX = 0, PREV_INDEX = 0,
PREV_VALUE = 1 PREV_VALUE = 1
@ -47,7 +47,7 @@ namespace etcdv3
class Action class Action
{ {
public: public:
Action(etcdv3::ActionParameters params); Action(etcdv3::ActionParameters const &params);
void waitForResponse(); void waitForResponse();
const std::chrono::high_resolution_clock::time_point startTimepoint(); const std::chrono::high_resolution_clock::time_point startTimepoint();
protected: protected:

View File

@ -16,7 +16,7 @@ namespace etcdv3
class AsyncCompareAndDeleteAction : public etcdv3::Action class AsyncCompareAndDeleteAction : public etcdv3::Action
{ {
public: public:
AsyncCompareAndDeleteAction(etcdv3::ActionParameters param, etcdv3::Atomicity_Type type); AsyncCompareAndDeleteAction(etcdv3::ActionParameters const &param, etcdv3::AtomicityType type);
AsyncTxnResponse ParseResponse(); AsyncTxnResponse ParseResponse();
private: private:
TxnResponse reply; TxnResponse reply;

View File

@ -16,7 +16,7 @@ namespace etcdv3
class AsyncCompareAndSwapAction : public etcdv3::Action class AsyncCompareAndSwapAction : public etcdv3::Action
{ {
public: public:
AsyncCompareAndSwapAction(etcdv3::ActionParameters param, etcdv3::Atomicity_Type type); AsyncCompareAndSwapAction(etcdv3::ActionParameters const &param, etcdv3::AtomicityType type);
AsyncTxnResponse ParseResponse(); AsyncTxnResponse ParseResponse();
private: private:
TxnResponse reply; TxnResponse reply;

View File

@ -15,7 +15,7 @@ namespace etcdv3
class AsyncDeleteAction : public etcdv3::Action class AsyncDeleteAction : public etcdv3::Action
{ {
public: public:
AsyncDeleteAction(etcdv3::ActionParameters param); AsyncDeleteAction(etcdv3::ActionParameters const &param);
AsyncDeleteRangeResponse ParseResponse(); AsyncDeleteRangeResponse ParseResponse();
private: private:
DeleteRangeResponse reply; DeleteRangeResponse reply;

View File

@ -15,7 +15,7 @@ namespace etcdv3
class AsyncHeadAction : public etcdv3::Action class AsyncHeadAction : public etcdv3::Action
{ {
public: public:
AsyncHeadAction(etcdv3::ActionParameters param); AsyncHeadAction(etcdv3::ActionParameters const &param);
AsyncHeadResponse ParseResponse(); AsyncHeadResponse ParseResponse();
private: private:
RangeResponse reply; RangeResponse reply;

View File

@ -15,7 +15,7 @@ namespace etcdv3
{ {
public: public:
AsyncHeadResponse(){}; AsyncHeadResponse(){};
void ParseResponse(RangeResponse& resp, bool prefix=false); void ParseResponse(RangeResponse& resp);
}; };
} }

View File

@ -25,7 +25,7 @@ namespace etcdv3
{ {
class AsyncLeaseGrantAction : public etcdv3::Action { class AsyncLeaseGrantAction : public etcdv3::Action {
public: public:
AsyncLeaseGrantAction(etcdv3::ActionParameters param); AsyncLeaseGrantAction(etcdv3::ActionParameters const &param);
AsyncLeaseGrantResponse ParseResponse(); AsyncLeaseGrantResponse ParseResponse();
private: private:
LeaseGrantResponse reply; LeaseGrantResponse reply;
@ -34,7 +34,7 @@ namespace etcdv3
class AsyncLeaseRevokeAction: public etcdv3::Action { class AsyncLeaseRevokeAction: public etcdv3::Action {
public: public:
AsyncLeaseRevokeAction(etcdv3::ActionParameters param); AsyncLeaseRevokeAction(etcdv3::ActionParameters const &param);
AsyncLeaseRevokeResponse ParseResponse(); AsyncLeaseRevokeResponse ParseResponse();
private: private:
LeaseRevokeResponse reply; LeaseRevokeResponse reply;
@ -43,7 +43,7 @@ namespace etcdv3
class AsyncLeaseKeepAliveAction: public etcdv3::Action { class AsyncLeaseKeepAliveAction: public etcdv3::Action {
public: public:
AsyncLeaseKeepAliveAction(etcdv3::ActionParameters param); AsyncLeaseKeepAliveAction(etcdv3::ActionParameters const &param);
AsyncLeaseKeepAliveResponse ParseResponse(); AsyncLeaseKeepAliveResponse ParseResponse();
etcd::Response Refresh(); etcd::Response Refresh();
@ -61,7 +61,7 @@ namespace etcdv3
class AsyncLeaseTimeToLiveAction: public etcdv3::Action { class AsyncLeaseTimeToLiveAction: public etcdv3::Action {
public: public:
AsyncLeaseTimeToLiveAction(etcdv3::ActionParameters param); AsyncLeaseTimeToLiveAction(etcdv3::ActionParameters const &param);
AsyncLeaseTimeToLiveResponse ParseResponse(); AsyncLeaseTimeToLiveResponse ParseResponse();
private: private:
LeaseTimeToLiveResponse reply; LeaseTimeToLiveResponse reply;
@ -70,7 +70,7 @@ namespace etcdv3
class AsyncLeaseLeasesAction: public etcdv3::Action { class AsyncLeaseLeasesAction: public etcdv3::Action {
public: public:
AsyncLeaseLeasesAction(etcdv3::ActionParameters param); AsyncLeaseLeasesAction(etcdv3::ActionParameters const &param);
AsyncLeaseLeasesResponse ParseResponse(); AsyncLeaseLeasesResponse ParseResponse();
private: private:
LeaseLeasesResponse reply; LeaseLeasesResponse reply;

View File

@ -20,7 +20,7 @@ namespace etcdv3
class AsyncLockAction : public etcdv3::Action class AsyncLockAction : public etcdv3::Action
{ {
public: public:
AsyncLockAction(etcdv3::ActionParameters param); AsyncLockAction(etcdv3::ActionParameters const &param);
AsyncLockResponse ParseResponse(); AsyncLockResponse ParseResponse();
private: private:
LockResponse reply; LockResponse reply;
@ -30,7 +30,7 @@ namespace etcdv3
class AsyncUnlockAction : public etcdv3::Action class AsyncUnlockAction : public etcdv3::Action
{ {
public: public:
AsyncUnlockAction(etcdv3::ActionParameters param); AsyncUnlockAction(etcdv3::ActionParameters const &param);
AsyncUnlockResponse ParseResponse(); AsyncUnlockResponse ParseResponse();
private: private:
UnlockResponse reply; UnlockResponse reply;

View File

@ -15,7 +15,7 @@ namespace etcdv3
class AsyncRangeAction : public etcdv3::Action class AsyncRangeAction : public etcdv3::Action
{ {
public: public:
AsyncRangeAction(etcdv3::ActionParameters param); AsyncRangeAction(etcdv3::ActionParameters const &param);
AsyncRangeResponse ParseResponse(); AsyncRangeResponse ParseResponse();
private: private:
RangeResponse reply; RangeResponse reply;

View File

@ -16,7 +16,7 @@ namespace etcdv3
class AsyncSetAction : public etcdv3::Action class AsyncSetAction : public etcdv3::Action
{ {
public: public:
AsyncSetAction(etcdv3::ActionParameters param, bool create=false); AsyncSetAction(etcdv3::ActionParameters const &param, bool create=false);
AsyncTxnResponse ParseResponse(); AsyncTxnResponse ParseResponse();
private: private:
TxnResponse reply; TxnResponse reply;

View File

@ -9,6 +9,7 @@
using grpc::ClientAsyncResponseReader; using grpc::ClientAsyncResponseReader;
using etcdserverpb::TxnRequest;
using etcdserverpb::TxnResponse; using etcdserverpb::TxnResponse;
using etcdserverpb::KV; using etcdserverpb::KV;
@ -17,7 +18,7 @@ namespace etcdv3
class AsyncTxnAction : public etcdv3::Action class AsyncTxnAction : public etcdv3::Action
{ {
public: public:
AsyncTxnAction(etcdv3::ActionParameters param, etcdv3::Transaction const &tx); AsyncTxnAction(etcdv3::ActionParameters const &param, etcdv3::Transaction const &tx);
AsyncTxnResponse ParseResponse(); AsyncTxnResponse ParseResponse();
private: private:
TxnResponse reply; TxnResponse reply;

View File

@ -16,7 +16,7 @@ namespace etcdv3
class AsyncUpdateAction : public etcdv3::Action class AsyncUpdateAction : public etcdv3::Action
{ {
public: public:
AsyncUpdateAction(etcdv3::ActionParameters param); AsyncUpdateAction(etcdv3::ActionParameters const &param);
AsyncTxnResponse ParseResponse(); AsyncTxnResponse ParseResponse();
private: private:
TxnResponse reply; TxnResponse reply;

View File

@ -19,7 +19,7 @@ namespace etcdv3
class AsyncWatchAction : public etcdv3::Action class AsyncWatchAction : public etcdv3::Action
{ {
public: public:
AsyncWatchAction(etcdv3::ActionParameters param); AsyncWatchAction(etcdv3::ActionParameters const &param);
AsyncWatchResponse ParseResponse(); AsyncWatchResponse ParseResponse();
void waitForResponse(); void waitForResponse();
void waitForResponse(std::function<void(etcd::Response)> callback); void waitForResponse(std::function<void(etcd::Response)> callback);

View File

@ -3,22 +3,35 @@
#include <string> #include <string>
#include "txn.pb.h"
namespace etcdserverpb { namespace etcdserverpb {
class TxnRequest; class TxnRequest;
} }
namespace etcdv3 { namespace etcdv3 {
enum class CompareResult {
EQUAL = 0,
GREATER = 1,
LESS = 2,
NOT_EQUAL = 3,
};
enum class CompareTarget {
VERSION = 0,
CREATE = 1,
MOD = 2,
VALUE = 3,
LEASE = 4,
};
class Transaction { class Transaction {
public: public:
Transaction(); Transaction();
Transaction(std::string const&); Transaction(std::string const&);
virtual ~Transaction(); virtual ~Transaction();
void init_compare(etcdserverpb::Compare::CompareResult, etcdserverpb::Compare::CompareTarget); void init_compare(CompareResult, CompareTarget);
void init_compare(std::string const &, etcdserverpb::Compare::CompareResult, etcdserverpb::Compare::CompareTarget); void init_compare(std::string const &old_value, CompareResult, CompareTarget);
void init_compare(int, etcdserverpb::Compare::CompareResult, etcdserverpb::Compare::CompareTarget); void init_compare(int old_value, CompareResult, CompareTarget);
void setup_basic_failure_operation(std::string const &key); void setup_basic_failure_operation(std::string const &key);
void setup_set_failure_operation(std::string const &key, std::string const &value, int64_t leaseid); void setup_set_failure_operation(std::string const &key, std::string const &value, int64_t leaseid);

View File

@ -13,6 +13,13 @@ namespace etcdv3
extern char const * LOCK_ACTION; extern char const * LOCK_ACTION;
extern char const * UNLOCK_ACTION; extern char const * UNLOCK_ACTION;
extern char const * TXN_ACTION; extern char const * TXN_ACTION;
extern char const * WATCH_ACTION;
extern char const * LEASEGRANT;
extern char const * LEASEREVOKE;
extern char const * LEASEKEEPALIVE;
extern char const * LEASETIMETOLIVE;
extern char const * LEASELEASES;
extern char const * NUL; extern char const * NUL;
@ -24,6 +31,10 @@ namespace etcdv3
extern char const * WATCH_CREATE; extern char const * WATCH_CREATE;
extern char const * WATCH_WRITE; extern char const * WATCH_WRITE;
extern char const * WATCH_WRITES_DONE; extern char const * WATCH_WRITES_DONE;
extern const int ERROR_KEY_NOT_FOUND;
extern const int ERROR_COMPARE_FAILED;
extern const int ERROR_KEY_ALREADY_EXISTS;
} }
#endif #endif

View File

@ -4,7 +4,6 @@ package etcdserverpb;
import "gogoproto/gogo.proto"; import "gogoproto/gogo.proto";
import "kv.proto"; import "kv.proto";
import "auth.proto"; import "auth.proto";
import "txn.proto";
// for grpc-gateway // for grpc-gateway
import "google/api/annotations.proto"; import "google/api/annotations.proto";
@ -533,6 +532,46 @@ message ResponseOp {
} }
} }
message Compare {
enum CompareResult {
EQUAL = 0;
GREATER = 1;
LESS = 2;
NOT_EQUAL = 3;
}
enum CompareTarget {
VERSION = 0;
CREATE = 1;
MOD = 2;
VALUE = 3;
LEASE = 4;
}
// result is logical comparison operation for this comparison.
CompareResult result = 1;
// target is the key-value field to inspect for the comparison.
CompareTarget target = 2;
// key is the subject key for the comparison operation.
bytes key = 3;
oneof target_union {
// version is the version of the given key
int64 version = 4;
// create_revision is the creation revision of the given key
int64 create_revision = 5;
// mod_revision is the last modified revision of the given key.
int64 mod_revision = 6;
// value is the value of the given key, in bytes.
bytes value = 7;
// lease is the lease id of the given key.
int64 lease = 8;
// leave room for more target_union field tags, jump to 64
}
// range_end compares the given target to all keys in the range [key, range_end).
// See RangeRequest for more details on key ranges.
bytes range_end = 64;
// TODO: fill out with most of the rest of RangeRequest fields when needed.
}
// From google paxosdb paper: // From google paxosdb paper:
// Our implementation hinges around a powerful primitive which we call MultiOp. All other database // Our implementation hinges around a powerful primitive which we call MultiOp. All other database
// operations except for iteration are implemented as a single call to MultiOp. A MultiOp is applied atomically // operations except for iteration are implemented as a single call to MultiOp. A MultiOp is applied atomically

View File

@ -1,42 +0,0 @@
syntax = "proto3";
package etcdserverpb;
message Compare {
enum CompareResult {
EQUAL = 0;
GREATER = 1;
LESS = 2;
NOT_EQUAL = 3;
}
enum CompareTarget {
VERSION = 0;
CREATE = 1;
MOD = 2;
VALUE = 3;
LEASE = 4;
}
// result is logical comparison operation for this comparison.
CompareResult result = 1;
// target is the key-value field to inspect for the comparison.
CompareTarget target = 2;
// key is the subject key for the comparison operation.
bytes key = 3;
oneof target_union {
// version is the version of the given key
int64 version = 4;
// create_revision is the creation revision of the given key
int64 create_revision = 5;
// mod_revision is the last modified revision of the given key.
int64 mod_revision = 6;
// value is the value of the given key, in bytes.
bytes value = 7;
// lease is the lease id of the given key.
int64 lease = 8;
// leave room for more target_union field tags, jump to 64
}
// range_end compares the given target to all keys in the range [key, range_end).
// See RangeRequest for more details on key ranges.
bytes range_end = 64;
// TODO: fill out with most of the rest of RangeRequest fields when needed.
}

View File

@ -347,7 +347,7 @@ pplx::task<etcd::Response> etcd::Client::add(std::string const & key, std::strin
params.lease_id = res.value().lease(); params.lease_id = res.value().lease();
} }
} }
std::shared_ptr<etcdv3::AsyncSetAction> call(new etcdv3::AsyncSetAction(params,true)); std::shared_ptr<etcdv3::AsyncSetAction> call(new etcdv3::AsyncSetAction(params, true));
return Response::create(call); return Response::create(call);
} }
@ -428,7 +428,8 @@ pplx::task<etcd::Response> etcd::Client::modify_if(std::string const & key, std:
params.lease_id = res.value().lease(); params.lease_id = res.value().lease();
} }
} }
std::shared_ptr<etcdv3::AsyncCompareAndSwapAction> call(new etcdv3::AsyncCompareAndSwapAction(params,etcdv3::Atomicity_Type::PREV_VALUE)); std::shared_ptr<etcdv3::AsyncCompareAndSwapAction> call(
new etcdv3::AsyncCompareAndSwapAction(params,etcdv3::AtomicityType::PREV_VALUE));
return Response::create(call); return Response::create(call);
} }
@ -441,7 +442,8 @@ pplx::task<etcd::Response> etcd::Client::modify_if(std::string const & key, std:
params.old_value.assign(old_value); params.old_value.assign(old_value);
params.lease_id = leaseid; params.lease_id = leaseid;
params.kv_stub = stubs->kvServiceStub.get(); params.kv_stub = stubs->kvServiceStub.get();
std::shared_ptr<etcdv3::AsyncCompareAndSwapAction> call(new etcdv3::AsyncCompareAndSwapAction(params,etcdv3::Atomicity_Type::PREV_VALUE)); std::shared_ptr<etcdv3::AsyncCompareAndSwapAction> call(
new etcdv3::AsyncCompareAndSwapAction(params,etcdv3::AtomicityType::PREV_VALUE));
return Response::create(call); return Response::create(call);
} }
@ -468,7 +470,8 @@ pplx::task<etcd::Response> etcd::Client::modify_if(std::string const & key, std:
params.lease_id = res.value().lease(); params.lease_id = res.value().lease();
} }
} }
std::shared_ptr<etcdv3::AsyncCompareAndSwapAction> call(new etcdv3::AsyncCompareAndSwapAction(params,etcdv3::Atomicity_Type::PREV_INDEX)); std::shared_ptr<etcdv3::AsyncCompareAndSwapAction> call(
new etcdv3::AsyncCompareAndSwapAction(params,etcdv3::AtomicityType::PREV_INDEX));
return Response::create(call); return Response::create(call);
} }
@ -481,7 +484,8 @@ pplx::task<etcd::Response> etcd::Client::modify_if(std::string const & key, std:
params.lease_id = leaseid; params.lease_id = leaseid;
params.old_revision = old_index; params.old_revision = old_index;
params.kv_stub = stubs->kvServiceStub.get(); params.kv_stub = stubs->kvServiceStub.get();
std::shared_ptr<etcdv3::AsyncCompareAndSwapAction> call(new etcdv3::AsyncCompareAndSwapAction(params,etcdv3::Atomicity_Type::PREV_INDEX)); std::shared_ptr<etcdv3::AsyncCompareAndSwapAction> call(
new etcdv3::AsyncCompareAndSwapAction(params,etcdv3::AtomicityType::PREV_INDEX));
return Response::create(call); return Response::create(call);
} }
@ -504,7 +508,8 @@ pplx::task<etcd::Response> etcd::Client::rm_if(std::string const & key, std::str
params.key.assign(key); params.key.assign(key);
params.old_value.assign(old_value); params.old_value.assign(old_value);
params.kv_stub = stubs->kvServiceStub.get(); params.kv_stub = stubs->kvServiceStub.get();
std::shared_ptr<etcdv3::AsyncCompareAndDeleteAction> call(new etcdv3::AsyncCompareAndDeleteAction(params,etcdv3::Atomicity_Type::PREV_VALUE)); std::shared_ptr<etcdv3::AsyncCompareAndDeleteAction> call(
new etcdv3::AsyncCompareAndDeleteAction(params,etcdv3::AtomicityType::PREV_VALUE));
return Response::create(call); return Response::create(call);
} }
@ -515,7 +520,8 @@ pplx::task<etcd::Response> etcd::Client::rm_if(std::string const & key, int old_
params.key.assign(key); params.key.assign(key);
params.old_revision = old_index; params.old_revision = old_index;
params.kv_stub = stubs->kvServiceStub.get(); params.kv_stub = stubs->kvServiceStub.get();
std::shared_ptr<etcdv3::AsyncCompareAndDeleteAction> call(new etcdv3::AsyncCompareAndDeleteAction(params, etcdv3::Atomicity_Type::PREV_INDEX));; std::shared_ptr<etcdv3::AsyncCompareAndDeleteAction> call(
new etcdv3::AsyncCompareAndDeleteAction(params, etcdv3::AtomicityType::PREV_INDEX));;
return Response::create(call); return Response::create(call);
} }

View File

@ -2,7 +2,7 @@
#include "etcd/v3/action_constants.hpp" #include "etcd/v3/action_constants.hpp"
#include "etcd/v3/Action.hpp" #include "etcd/v3/Action.hpp"
etcdv3::Action::Action(etcdv3::ActionParameters params) etcdv3::Action::Action(etcdv3::ActionParameters const &params)
{ {
parameters = params; parameters = params;
if (!parameters.auth_token.empty()) { if (!parameters.auth_token.empty()) {

View File

@ -1,27 +1,30 @@
#include "etcd/v3/AsyncCompareAndDeleteAction.hpp" #include "etcd/v3/AsyncCompareAndDeleteAction.hpp"
#include "etcd/v3/action_constants.hpp" #include "etcd/v3/action_constants.hpp"
#include "etcd/v3/Transaction.hpp" #include "etcd/v3/Transaction.hpp"
using etcdserverpb::Compare;
using etcdserverpb::RangeRequest; using etcdserverpb::RangeRequest;
using etcdserverpb::PutRequest; using etcdserverpb::PutRequest;
using etcdserverpb::RequestOp; using etcdserverpb::RequestOp;
using etcdserverpb::ResponseOp; using etcdserverpb::ResponseOp;
using etcdserverpb::TxnRequest; using etcdserverpb::TxnRequest;
etcdv3::AsyncCompareAndDeleteAction::AsyncCompareAndDeleteAction(etcdv3::ActionParameters param, etcdv3::Atomicity_Type type) etcdv3::AsyncCompareAndDeleteAction::AsyncCompareAndDeleteAction(
etcdv3::ActionParameters const &param, etcdv3::AtomicityType type)
:etcdv3::Action(param) :etcdv3::Action(param)
{ {
etcdv3::Transaction transaction(parameters.key); etcdv3::Transaction transaction(parameters.key);
if(type == etcdv3::Atomicity_Type::PREV_VALUE) if(type == etcdv3::AtomicityType::PREV_VALUE)
{ {
transaction.init_compare(parameters.old_value, Compare::CompareResult::Compare_CompareResult_EQUAL, transaction.init_compare(parameters.old_value,
Compare::CompareTarget::Compare_CompareTarget_VALUE); CompareResult::EQUAL,
CompareTarget::VALUE);
} }
else if (type == etcdv3::Atomicity_Type::PREV_INDEX) else if (type == etcdv3::AtomicityType::PREV_INDEX)
{ {
transaction.init_compare(parameters.old_revision, Compare::CompareResult::Compare_CompareResult_EQUAL, transaction.init_compare(parameters.old_revision,
Compare::CompareTarget::Compare_CompareTarget_MOD); CompareResult::EQUAL,
CompareTarget::MOD);
} }
transaction.setup_compare_and_delete_operation(parameters.key); transaction.setup_compare_and_delete_operation(parameters.key);
@ -34,6 +37,8 @@ etcdv3::AsyncCompareAndDeleteAction::AsyncCompareAndDeleteAction(etcdv3::ActionP
etcdv3::AsyncTxnResponse etcdv3::AsyncCompareAndDeleteAction::ParseResponse() etcdv3::AsyncTxnResponse etcdv3::AsyncCompareAndDeleteAction::ParseResponse()
{ {
AsyncTxnResponse txn_resp; AsyncTxnResponse txn_resp;
txn_resp.set_action(etcdv3::COMPAREDELETE_ACTION);
if(!status.ok()) if(!status.ok())
{ {
txn_resp.set_error_code(status.error_code()); txn_resp.set_error_code(status.error_code());
@ -42,11 +47,10 @@ etcdv3::AsyncTxnResponse etcdv3::AsyncCompareAndDeleteAction::ParseResponse()
else else
{ {
txn_resp.ParseResponse(parameters.key, parameters.withPrefix, reply); txn_resp.ParseResponse(parameters.key, parameters.withPrefix, reply);
txn_resp.set_action(etcdv3::COMPAREDELETE_ACTION);
if(!reply.succeeded()) if(!reply.succeeded())
{ {
txn_resp.set_error_code(101); txn_resp.set_error_code(ERROR_COMPARE_FAILED);
txn_resp.set_error_message("Compare failed"); txn_resp.set_error_message("Compare failed");
} }
} }

View File

@ -1,27 +1,30 @@
#include "etcd/v3/AsyncCompareAndSwapAction.hpp" #include "etcd/v3/AsyncCompareAndSwapAction.hpp"
#include "etcd/v3/action_constants.hpp" #include "etcd/v3/action_constants.hpp"
#include "etcd/v3/Transaction.hpp" #include "etcd/v3/Transaction.hpp"
using etcdserverpb::Compare;
using etcdserverpb::RangeRequest; using etcdserverpb::RangeRequest;
using etcdserverpb::PutRequest; using etcdserverpb::PutRequest;
using etcdserverpb::RequestOp; using etcdserverpb::RequestOp;
using etcdserverpb::ResponseOp; using etcdserverpb::ResponseOp;
using etcdserverpb::TxnRequest; using etcdserverpb::TxnRequest;
etcdv3::AsyncCompareAndSwapAction::AsyncCompareAndSwapAction(etcdv3::ActionParameters param, etcdv3::Atomicity_Type type) etcdv3::AsyncCompareAndSwapAction::AsyncCompareAndSwapAction(
etcdv3::ActionParameters const &param, etcdv3::AtomicityType type)
: etcdv3::Action(param) : etcdv3::Action(param)
{ {
etcdv3::Transaction transaction(parameters.key); etcdv3::Transaction transaction(parameters.key);
if(type == etcdv3::Atomicity_Type::PREV_VALUE) if(type == etcdv3::AtomicityType::PREV_VALUE)
{ {
transaction.init_compare(parameters.old_value, Compare::CompareResult::Compare_CompareResult_EQUAL, transaction.init_compare(parameters.old_value,
Compare::CompareTarget::Compare_CompareTarget_VALUE); CompareResult::EQUAL,
CompareTarget::VALUE);
} }
else if (type == etcdv3::Atomicity_Type::PREV_INDEX) else if (type == etcdv3::AtomicityType::PREV_INDEX)
{ {
transaction.init_compare(parameters.old_revision, Compare::CompareResult::Compare_CompareResult_EQUAL, transaction.init_compare(parameters.old_revision,
Compare::CompareTarget::Compare_CompareTarget_MOD); CompareResult::EQUAL,
CompareTarget::MOD);
} }
transaction.setup_basic_failure_operation(parameters.key); transaction.setup_basic_failure_operation(parameters.key);
@ -34,6 +37,7 @@ etcdv3::AsyncCompareAndSwapAction::AsyncCompareAndSwapAction(etcdv3::ActionParam
etcdv3::AsyncTxnResponse etcdv3::AsyncCompareAndSwapAction::ParseResponse() etcdv3::AsyncTxnResponse etcdv3::AsyncCompareAndSwapAction::ParseResponse()
{ {
AsyncTxnResponse txn_resp; AsyncTxnResponse txn_resp;
txn_resp.set_action(etcdv3::COMPARESWAP_ACTION);
if(!status.ok()) if(!status.ok())
{ {
@ -43,13 +47,12 @@ etcdv3::AsyncTxnResponse etcdv3::AsyncCompareAndSwapAction::ParseResponse()
else else
{ {
txn_resp.ParseResponse(parameters.key, parameters.withPrefix, reply); txn_resp.ParseResponse(parameters.key, parameters.withPrefix, reply);
txn_resp.set_action(etcdv3::COMPARESWAP_ACTION);
//if there is an error code returned by parseResponse, we must //if there is an error code returned by parseResponse, we must
//not overwrite it. //not overwrite it.
if(!reply.succeeded() && !txn_resp.get_error_code()) if(!reply.succeeded() && !txn_resp.get_error_code())
{ {
txn_resp.set_error_code(101); txn_resp.set_error_code(ERROR_COMPARE_FAILED);
txn_resp.set_error_message("Compare failed"); txn_resp.set_error_message("Compare failed");
} }
} }

View File

@ -3,7 +3,8 @@
using etcdserverpb::DeleteRangeRequest; using etcdserverpb::DeleteRangeRequest;
etcdv3::AsyncDeleteAction::AsyncDeleteAction(ActionParameters param) etcdv3::AsyncDeleteAction::AsyncDeleteAction(
ActionParameters const &param)
: etcdv3::Action(param) : etcdv3::Action(param)
{ {
DeleteRangeRequest del_request; DeleteRangeRequest del_request;
@ -28,6 +29,7 @@ etcdv3::AsyncDeleteAction::AsyncDeleteAction(ActionParameters param)
etcdv3::AsyncDeleteRangeResponse etcdv3::AsyncDeleteAction::ParseResponse() etcdv3::AsyncDeleteRangeResponse etcdv3::AsyncDeleteAction::ParseResponse()
{ {
AsyncDeleteRangeResponse del_resp; AsyncDeleteRangeResponse del_resp;
del_resp.set_action(etcdv3::DELETE_ACTION);
if(!status.ok()) if(!status.ok())
{ {

View File

@ -8,12 +8,11 @@ void etcdv3::AsyncDeleteRangeResponse::ParseResponse(std::string const& key, boo
if(resp.prev_kvs_size() == 0) if(resp.prev_kvs_size() == 0)
{ {
error_code=100; error_code = etcdv3::ERROR_KEY_NOT_FOUND;
error_message="Key not found"; error_message = "Key not found";
} }
else else
{ {
action = etcdv3::DELETE_ACTION;
//get all previous values //get all previous values
for(int cnt=0; cnt < resp.prev_kvs_size(); cnt++) for(int cnt=0; cnt < resp.prev_kvs_size(); cnt++)
{ {
@ -29,6 +28,5 @@ void etcdv3::AsyncDeleteRangeResponse::ParseResponse(std::string const& key, boo
value.kvs.clear_value(); value.kvs.clear_value();
values.clear(); values.clear();
} }
} }
} }

View File

@ -6,7 +6,8 @@
using etcdserverpb::RangeRequest; using etcdserverpb::RangeRequest;
etcdv3::AsyncHeadAction::AsyncHeadAction(etcdv3::ActionParameters param) etcdv3::AsyncHeadAction::AsyncHeadAction(
etcdv3::ActionParameters const &param)
: etcdv3::Action(param) : etcdv3::Action(param)
{ {
RangeRequest get_request; RangeRequest get_request;
@ -18,15 +19,17 @@ etcdv3::AsyncHeadAction::AsyncHeadAction(etcdv3::ActionParameters param)
etcdv3::AsyncHeadResponse etcdv3::AsyncHeadAction::ParseResponse() etcdv3::AsyncHeadResponse etcdv3::AsyncHeadAction::ParseResponse()
{ {
AsyncHeadResponse range_resp; AsyncHeadResponse head_resp;
head_resp.set_action(etcdv3::GET_ACTION);
if(!status.ok()) if(!status.ok())
{ {
range_resp.set_error_code(status.error_code()); head_resp.set_error_code(status.error_code());
range_resp.set_error_message(status.error_message()); head_resp.set_error_message(status.error_message());
} }
else else
{ {
range_resp.ParseResponse(reply, parameters.withPrefix || !parameters.range_end.empty()); head_resp.ParseResponse(reply);
} }
return range_resp; return head_resp;
} }

View File

@ -2,8 +2,7 @@
#include "etcd/v3/action_constants.hpp" #include "etcd/v3/action_constants.hpp"
void etcdv3::AsyncHeadResponse::ParseResponse(RangeResponse& resp, bool prefix) void etcdv3::AsyncHeadResponse::ParseResponse(RangeResponse& resp)
{ {
action = etcdv3::GET_ACTION;
index = resp.header().revision(); index = resp.header().revision();
} }

View File

@ -9,7 +9,8 @@ using etcdserverpb::LeaseKeepAliveRequest;
using etcdserverpb::LeaseTimeToLiveRequest; using etcdserverpb::LeaseTimeToLiveRequest;
using etcdserverpb::LeaseLeasesRequest; using etcdserverpb::LeaseLeasesRequest;
etcdv3::AsyncLeaseGrantAction::AsyncLeaseGrantAction(etcdv3::ActionParameters param) etcdv3::AsyncLeaseGrantAction::AsyncLeaseGrantAction(
etcdv3::ActionParameters const &param)
: etcdv3::Action(param) : etcdv3::Action(param)
{ {
LeaseGrantRequest leasegrant_request; LeaseGrantRequest leasegrant_request;
@ -24,6 +25,8 @@ etcdv3::AsyncLeaseGrantAction::AsyncLeaseGrantAction(etcdv3::ActionParameters pa
etcdv3::AsyncLeaseGrantResponse etcdv3::AsyncLeaseGrantAction::ParseResponse() etcdv3::AsyncLeaseGrantResponse etcdv3::AsyncLeaseGrantAction::ParseResponse()
{ {
AsyncLeaseGrantResponse lease_resp; AsyncLeaseGrantResponse lease_resp;
lease_resp.set_action(etcdv3::LEASEGRANT);
if (!status.ok()) { if (!status.ok()) {
lease_resp.set_error_code(status.error_code()); lease_resp.set_error_code(status.error_code());
lease_resp.set_error_message(status.error_message()); lease_resp.set_error_message(status.error_message());
@ -33,7 +36,8 @@ etcdv3::AsyncLeaseGrantResponse etcdv3::AsyncLeaseGrantAction::ParseResponse()
return lease_resp; return lease_resp;
} }
etcdv3::AsyncLeaseRevokeAction::AsyncLeaseRevokeAction(etcdv3::ActionParameters param) etcdv3::AsyncLeaseRevokeAction::AsyncLeaseRevokeAction(
etcdv3::ActionParameters const &param)
: etcdv3::Action(param) : etcdv3::Action(param)
{ {
LeaseRevokeRequest leaserevoke_request; LeaseRevokeRequest leaserevoke_request;
@ -46,6 +50,8 @@ etcdv3::AsyncLeaseRevokeAction::AsyncLeaseRevokeAction(etcdv3::ActionParameters
etcdv3::AsyncLeaseRevokeResponse etcdv3::AsyncLeaseRevokeAction::ParseResponse() etcdv3::AsyncLeaseRevokeResponse etcdv3::AsyncLeaseRevokeAction::ParseResponse()
{ {
AsyncLeaseRevokeResponse lease_resp; AsyncLeaseRevokeResponse lease_resp;
lease_resp.set_action(etcdv3::LEASEREVOKE);
if (!status.ok()) { if (!status.ok()) {
lease_resp.set_error_code(status.error_code()); lease_resp.set_error_code(status.error_code());
lease_resp.set_error_message(status.error_message()); lease_resp.set_error_message(status.error_message());
@ -55,7 +61,8 @@ etcdv3::AsyncLeaseRevokeResponse etcdv3::AsyncLeaseRevokeAction::ParseResponse()
return lease_resp; return lease_resp;
} }
etcdv3::AsyncLeaseKeepAliveAction::AsyncLeaseKeepAliveAction(etcdv3::ActionParameters param) etcdv3::AsyncLeaseKeepAliveAction::AsyncLeaseKeepAliveAction(
etcdv3::ActionParameters const &param)
: etcdv3::Action(param) : etcdv3::Action(param)
{ {
isCancelled = false; isCancelled = false;
@ -73,6 +80,8 @@ etcdv3::AsyncLeaseKeepAliveAction::AsyncLeaseKeepAliveAction(etcdv3::ActionParam
etcdv3::AsyncLeaseKeepAliveResponse etcdv3::AsyncLeaseKeepAliveAction::ParseResponse() etcdv3::AsyncLeaseKeepAliveResponse etcdv3::AsyncLeaseKeepAliveAction::ParseResponse()
{ {
AsyncLeaseKeepAliveResponse lease_resp; AsyncLeaseKeepAliveResponse lease_resp;
lease_resp.set_action(etcdv3::LEASEKEEPALIVE);
if (!status.ok()) { if (!status.ok()) {
lease_resp.set_error_code(status.error_code()); lease_resp.set_error_code(status.error_code());
lease_resp.set_error_message(status.error_message()); lease_resp.set_error_message(status.error_message());
@ -133,7 +142,8 @@ bool etcdv3::AsyncLeaseKeepAliveAction::Cancelled() const
return isCancelled; return isCancelled;
} }
etcdv3::AsyncLeaseTimeToLiveAction::AsyncLeaseTimeToLiveAction(etcdv3::ActionParameters param) etcdv3::AsyncLeaseTimeToLiveAction::AsyncLeaseTimeToLiveAction(
etcdv3::ActionParameters const &param)
: etcdv3::Action(param) : etcdv3::Action(param)
{ {
LeaseTimeToLiveRequest leasetimetolive_request; LeaseTimeToLiveRequest leasetimetolive_request;
@ -148,6 +158,8 @@ etcdv3::AsyncLeaseTimeToLiveAction::AsyncLeaseTimeToLiveAction(etcdv3::ActionPar
etcdv3::AsyncLeaseTimeToLiveResponse etcdv3::AsyncLeaseTimeToLiveAction::ParseResponse() etcdv3::AsyncLeaseTimeToLiveResponse etcdv3::AsyncLeaseTimeToLiveAction::ParseResponse()
{ {
AsyncLeaseTimeToLiveResponse lease_resp; AsyncLeaseTimeToLiveResponse lease_resp;
lease_resp.set_action(etcdv3::LEASETIMETOLIVE);
if (!status.ok()) { if (!status.ok()) {
lease_resp.set_error_code(status.error_code()); lease_resp.set_error_code(status.error_code());
lease_resp.set_error_message(status.error_message()); lease_resp.set_error_message(status.error_message());
@ -157,7 +169,8 @@ etcdv3::AsyncLeaseTimeToLiveResponse etcdv3::AsyncLeaseTimeToLiveAction::ParseRe
return lease_resp; return lease_resp;
} }
etcdv3::AsyncLeaseLeasesAction::AsyncLeaseLeasesAction(etcdv3::ActionParameters param) etcdv3::AsyncLeaseLeasesAction::AsyncLeaseLeasesAction(
etcdv3::ActionParameters const &param)
: etcdv3::Action(param) : etcdv3::Action(param)
{ {
LeaseLeasesRequest leaseleases_request; LeaseLeasesRequest leaseleases_request;
@ -169,6 +182,8 @@ etcdv3::AsyncLeaseLeasesAction::AsyncLeaseLeasesAction(etcdv3::ActionParameters
etcdv3::AsyncLeaseLeasesResponse etcdv3::AsyncLeaseLeasesAction::ParseResponse() etcdv3::AsyncLeaseLeasesResponse etcdv3::AsyncLeaseLeasesAction::ParseResponse()
{ {
AsyncLeaseLeasesResponse lease_resp; AsyncLeaseLeasesResponse lease_resp;
lease_resp.set_action(etcdv3::LEASELEASES);
if (!status.ok()) { if (!status.ok()) {
lease_resp.set_error_code(status.error_code()); lease_resp.set_error_code(status.error_code());
lease_resp.set_error_message(status.error_message()); lease_resp.set_error_message(status.error_message());

View File

@ -4,7 +4,8 @@
using v3lockpb::LockRequest; using v3lockpb::LockRequest;
using v3lockpb::UnlockRequest; using v3lockpb::UnlockRequest;
etcdv3::AsyncLockAction::AsyncLockAction(ActionParameters param) etcdv3::AsyncLockAction::AsyncLockAction(
ActionParameters const &param)
: etcdv3::Action(param) : etcdv3::Action(param)
{ {
LockRequest lock_request; LockRequest lock_request;
@ -18,6 +19,7 @@ etcdv3::AsyncLockAction::AsyncLockAction(ActionParameters param)
etcdv3::AsyncLockResponse etcdv3::AsyncLockAction::ParseResponse() etcdv3::AsyncLockResponse etcdv3::AsyncLockAction::ParseResponse()
{ {
AsyncLockResponse lock_resp; AsyncLockResponse lock_resp;
lock_resp.set_action(etcdv3::LOCK_ACTION);
if(!status.ok()) if(!status.ok())
{ {
@ -27,13 +29,13 @@ etcdv3::AsyncLockResponse etcdv3::AsyncLockAction::ParseResponse()
else else
{ {
lock_resp.ParseResponse(reply); lock_resp.ParseResponse(reply);
lock_resp.set_action(etcdv3::LOCK_ACTION);
} }
return lock_resp; return lock_resp;
} }
etcdv3::AsyncUnlockAction::AsyncUnlockAction(ActionParameters param) etcdv3::AsyncUnlockAction::AsyncUnlockAction(
ActionParameters const &param)
: etcdv3::Action(param) : etcdv3::Action(param)
{ {
UnlockRequest unlock_request; UnlockRequest unlock_request;
@ -46,6 +48,7 @@ etcdv3::AsyncUnlockAction::AsyncUnlockAction(ActionParameters param)
etcdv3::AsyncUnlockResponse etcdv3::AsyncUnlockAction::ParseResponse() etcdv3::AsyncUnlockResponse etcdv3::AsyncUnlockAction::ParseResponse()
{ {
AsyncUnlockResponse unlock_resp; AsyncUnlockResponse unlock_resp;
unlock_resp.set_action(etcdv3::UNLOCK_ACTION);
if(!status.ok()) if(!status.ok())
{ {
@ -55,7 +58,6 @@ etcdv3::AsyncUnlockResponse etcdv3::AsyncUnlockAction::ParseResponse()
else else
{ {
unlock_resp.ParseResponse(reply); unlock_resp.ParseResponse(reply);
unlock_resp.set_action(etcdv3::UNLOCK_ACTION);
} }
return unlock_resp; return unlock_resp;

View File

@ -6,7 +6,8 @@
using etcdserverpb::RangeRequest; using etcdserverpb::RangeRequest;
etcdv3::AsyncRangeAction::AsyncRangeAction(etcdv3::ActionParameters param) etcdv3::AsyncRangeAction::AsyncRangeAction(
etcdv3::ActionParameters const &param)
: etcdv3::Action(param) : etcdv3::Action(param)
{ {
RangeRequest get_request; RangeRequest get_request;
@ -36,6 +37,8 @@ etcdv3::AsyncRangeAction::AsyncRangeAction(etcdv3::ActionParameters param)
etcdv3::AsyncRangeResponse etcdv3::AsyncRangeAction::ParseResponse() etcdv3::AsyncRangeResponse etcdv3::AsyncRangeAction::ParseResponse()
{ {
AsyncRangeResponse range_resp; AsyncRangeResponse range_resp;
range_resp.set_action(etcdv3::GET_ACTION);
if(!status.ok()) if(!status.ok())
{ {
range_resp.set_error_code(status.error_code()); range_resp.set_error_code(status.error_code());

View File

@ -4,12 +4,11 @@
void etcdv3::AsyncRangeResponse::ParseResponse(RangeResponse& resp, bool prefix) void etcdv3::AsyncRangeResponse::ParseResponse(RangeResponse& resp, bool prefix)
{ {
action = etcdv3::GET_ACTION;
index = resp.header().revision(); index = resp.header().revision();
if(resp.kvs_size() == 0 && !prefix) if(resp.kvs_size() == 0 && !prefix)
{ {
error_code=100; error_code = etcdv3::ERROR_KEY_NOT_FOUND;
error_message="Key not found"; error_message = "Key not found";
return; return;
} }
else else

View File

@ -1,16 +1,16 @@
#include "etcd/v3/AsyncSetAction.hpp" #include "etcd/v3/AsyncSetAction.hpp"
#include "etcd/v3/action_constants.hpp" #include "etcd/v3/action_constants.hpp"
#include "etcd/v3/Transaction.hpp" #include "etcd/v3/Transaction.hpp"
using etcdserverpb::Compare; etcdv3::AsyncSetAction::AsyncSetAction(
etcdv3::ActionParameters const &param, bool create)
etcdv3::AsyncSetAction::AsyncSetAction(etcdv3::ActionParameters param, bool create)
: etcdv3::Action(param) : etcdv3::Action(param)
{ {
etcdv3::Transaction transaction(parameters.key); etcdv3::Transaction transaction(parameters.key);
isCreate = create; isCreate = create;
transaction.init_compare(Compare::CompareResult::Compare_CompareResult_EQUAL, transaction.init_compare(CompareResult::EQUAL,
Compare::CompareTarget::Compare_CompareTarget_VERSION); CompareTarget::VERSION);
transaction.setup_basic_create_sequence(parameters.key, parameters.value, parameters.lease_id); transaction.setup_basic_create_sequence(parameters.key, parameters.value, parameters.lease_id);
@ -30,6 +30,7 @@ etcdv3::AsyncTxnResponse etcdv3::AsyncSetAction::ParseResponse()
{ {
AsyncTxnResponse txn_resp; AsyncTxnResponse txn_resp;
txn_resp.set_action(isCreate? etcdv3::CREATE_ACTION : etcdv3::SET_ACTION);
if(!status.ok()) if(!status.ok())
{ {
@ -39,12 +40,10 @@ etcdv3::AsyncTxnResponse etcdv3::AsyncSetAction::ParseResponse()
else else
{ {
txn_resp.ParseResponse(parameters.key, parameters.withPrefix, reply); txn_resp.ParseResponse(parameters.key, parameters.withPrefix, reply);
std::string action = isCreate? etcdv3::CREATE_ACTION:etcdv3::SET_ACTION;
txn_resp.set_action(action);
if(!reply.succeeded() && action == etcdv3::CREATE_ACTION) if(!reply.succeeded() && isCreate)
{ {
txn_resp.set_error_code(105); txn_resp.set_error_code(etcdv3::ERROR_KEY_ALREADY_EXISTS);
txn_resp.set_error_message("Key already exists"); txn_resp.set_error_message("Key already exists");
} }
} }

View File

@ -3,7 +3,8 @@
#include "etcd/v3/Transaction.hpp" #include "etcd/v3/Transaction.hpp"
etcdv3::AsyncTxnAction::AsyncTxnAction(etcdv3::ActionParameters param, etcdv3::Transaction const &tx) etcdv3::AsyncTxnAction::AsyncTxnAction(
etcdv3::ActionParameters const &param, etcdv3::Transaction const &tx)
: etcdv3::Action(param) : etcdv3::Action(param)
{ {
response_reader = parameters.kv_stub->AsyncTxn(&context, *tx.txn_request, &cq_); response_reader = parameters.kv_stub->AsyncTxn(&context, *tx.txn_request, &cq_);
@ -13,6 +14,7 @@ etcdv3::AsyncTxnAction::AsyncTxnAction(etcdv3::ActionParameters param, etcdv3::T
etcdv3::AsyncTxnResponse etcdv3::AsyncTxnAction::ParseResponse() etcdv3::AsyncTxnResponse etcdv3::AsyncTxnAction::ParseResponse()
{ {
AsyncTxnResponse txn_resp; AsyncTxnResponse txn_resp;
txn_resp.set_action(etcdv3::TXN_ACTION);
if(!status.ok()) if(!status.ok())
{ {
@ -22,13 +24,12 @@ etcdv3::AsyncTxnResponse etcdv3::AsyncTxnAction::ParseResponse()
else else
{ {
txn_resp.ParseResponse(parameters.key, parameters.withPrefix, reply); txn_resp.ParseResponse(parameters.key, parameters.withPrefix, reply);
txn_resp.set_action(etcdv3::TXN_ACTION);
//if there is an error code returned by parseResponse, we must //if there is an error code returned by parseResponse, we must
//not overwrite it. //not overwrite it.
if(!reply.succeeded() && !txn_resp.get_error_code()) if(!reply.succeeded() && !txn_resp.get_error_code())
{ {
txn_resp.set_error_code(101); txn_resp.set_error_code(ERROR_COMPARE_FAILED);
txn_resp.set_error_message("compare failed"); txn_resp.set_error_message("compare failed");
} }
} }

View File

@ -1,21 +1,22 @@
#include "etcd/v3/AsyncUpdateAction.hpp" #include "etcd/v3/AsyncUpdateAction.hpp"
#include "etcd/v3/AsyncRangeResponse.hpp"
#include "etcd/v3/action_constants.hpp" #include "etcd/v3/action_constants.hpp"
#include "etcd/v3/AsyncRangeResponse.hpp"
#include "etcd/v3/Transaction.hpp" #include "etcd/v3/Transaction.hpp"
using etcdserverpb::Compare;
using etcdserverpb::RangeRequest; using etcdserverpb::RangeRequest;
using etcdserverpb::PutRequest; using etcdserverpb::PutRequest;
using etcdserverpb::RequestOp; using etcdserverpb::RequestOp;
using etcdserverpb::ResponseOp; using etcdserverpb::ResponseOp;
using etcdserverpb::TxnRequest; using etcdserverpb::TxnRequest;
etcdv3::AsyncUpdateAction::AsyncUpdateAction(etcdv3::ActionParameters param) etcdv3::AsyncUpdateAction::AsyncUpdateAction(
etcdv3::ActionParameters const &param)
: etcdv3::Action(param) : etcdv3::Action(param)
{ {
etcdv3::Transaction transaction(parameters.key); etcdv3::Transaction transaction(parameters.key);
transaction.init_compare(Compare::CompareResult::Compare_CompareResult_GREATER, transaction.init_compare(CompareResult::GREATER,
Compare::CompareTarget::Compare_CompareTarget_VERSION); CompareTarget::VERSION);
transaction.setup_compare_and_swap_sequence(parameters.value, parameters.lease_id); transaction.setup_compare_and_swap_sequence(parameters.value, parameters.lease_id);
@ -41,10 +42,9 @@ etcdv3::AsyncTxnResponse etcdv3::AsyncUpdateAction::ParseResponse()
} }
else else
{ {
txn_resp.set_error_code(100); txn_resp.set_error_code(etcdv3::ERROR_KEY_NOT_FOUND);
txn_resp.set_error_message("Key not found"); txn_resp.set_error_message("Key not found");
} }
} }
return txn_resp; return txn_resp;
} }

View File

@ -6,7 +6,8 @@ using etcdserverpb::RangeRequest;
using etcdserverpb::RangeResponse; using etcdserverpb::RangeResponse;
using etcdserverpb::WatchCreateRequest; using etcdserverpb::WatchCreateRequest;
etcdv3::AsyncWatchAction::AsyncWatchAction(etcdv3::ActionParameters param) etcdv3::AsyncWatchAction::AsyncWatchAction(
etcdv3::ActionParameters const &param)
: etcdv3::Action(param) : etcdv3::Action(param)
{ {
isCancelled.store(false); isCancelled.store(false);
@ -158,6 +159,8 @@ void etcdv3::AsyncWatchAction::waitForResponse(std::function<void(etcd::Response
etcdv3::AsyncWatchResponse etcdv3::AsyncWatchAction::ParseResponse() etcdv3::AsyncWatchResponse etcdv3::AsyncWatchAction::ParseResponse()
{ {
AsyncWatchResponse watch_resp; AsyncWatchResponse watch_resp;
watch_resp.set_action(etcdv3::WATCH_ACTION);
if(!status.ok()) if(!status.ok())
{ {
watch_resp.set_error_code(status.error_code()); watch_resp.set_error_code(status.error_code());

View File

@ -8,6 +8,22 @@ using etcdserverpb::PutRequest;
using etcdserverpb::RequestOp; using etcdserverpb::RequestOp;
using etcdserverpb::DeleteRangeRequest; using etcdserverpb::DeleteRangeRequest;
namespace etcdv3 {
namespace detail {
static etcdserverpb::Compare::CompareResult to_compare_result(CompareResult r) {
return static_cast<etcdserverpb::Compare::CompareResult>(static_cast<int>(r));
}
static etcdserverpb::Compare::CompareTarget to_compare_target(CompareTarget t) {
return static_cast<etcdserverpb::Compare::CompareTarget>(static_cast<int>(t));
}
}
}
etcdv3::Transaction::Transaction() { etcdv3::Transaction::Transaction() {
txn_request.reset(new etcdserverpb::TxnRequest{}); txn_request.reset(new etcdserverpb::TxnRequest{});
} }
@ -16,28 +32,28 @@ etcdv3::Transaction::Transaction(const std::string& key) : key(key) {
txn_request.reset(new etcdserverpb::TxnRequest{}); txn_request.reset(new etcdserverpb::TxnRequest{});
} }
void etcdv3::Transaction::init_compare(Compare::CompareResult result, Compare::CompareTarget target){ void etcdv3::Transaction::init_compare(CompareResult result, CompareTarget target){
Compare* compare = txn_request->add_compare(); Compare* compare = txn_request->add_compare();
compare->set_result(result); compare->set_result(detail::to_compare_result(result));
compare->set_target(target); compare->set_target(detail::to_compare_target(target));
compare->set_key(key); compare->set_key(key);
compare->set_version(0); compare->set_version(0);
} }
void etcdv3::Transaction::init_compare(std::string const& old_value, Compare::CompareResult result, Compare::CompareTarget target){ void etcdv3::Transaction::init_compare(std::string const& old_value, CompareResult result, CompareTarget target){
Compare* compare = txn_request->add_compare(); Compare* compare = txn_request->add_compare();
compare->set_result(result); compare->set_result(detail::to_compare_result(result));
compare->set_target(target); compare->set_target(detail::to_compare_target(target));
compare->set_key(key); compare->set_key(key);
compare->set_value(old_value); compare->set_value(old_value);
} }
void etcdv3::Transaction::init_compare(int old_index, Compare::CompareResult result, Compare::CompareTarget target){ void etcdv3::Transaction::init_compare(int old_index, CompareResult result, CompareTarget target){
Compare* compare = txn_request->add_compare(); Compare* compare = txn_request->add_compare();
compare->set_result(result); compare->set_result(detail::to_compare_result(result));
compare->set_target(target); compare->set_target(detail::to_compare_target(target));
compare->set_key(key); compare->set_key(key);
compare->set_mod_revision(old_index); compare->set_mod_revision(old_index);

View File

@ -10,6 +10,13 @@ char const * etcdv3::COMPAREDELETE_ACTION = "compareAndDelete";
char const * etcdv3::LOCK_ACTION = "lock"; char const * etcdv3::LOCK_ACTION = "lock";
char const * etcdv3::UNLOCK_ACTION = "unlock"; char const * etcdv3::UNLOCK_ACTION = "unlock";
char const * etcdv3::TXN_ACTION = "txn"; char const * etcdv3::TXN_ACTION = "txn";
char const * etcdv3::WATCH_ACTION = "watch";
char const * etcdv3::LEASEGRANT = "leasegrant";
char const * etcdv3::LEASEREVOKE = "leaserevoke";
char const * etcdv3::LEASEKEEPALIVE = "leasekeepalive";
char const * etcdv3::LEASETIMETOLIVE = "leasetimetolive";
char const * etcdv3::LEASELEASES = "leaseleases";
// see: noPrefixEnd in etcd, however c++ doesn't allows '\0' inside a string, thus we use // see: noPrefixEnd in etcd, however c++ doesn't allows '\0' inside a string, thus we use
// the UTF-8 char U+0000 (i.e., "\xC0\x80"). // the UTF-8 char U+0000 (i.e., "\xC0\x80").
@ -23,3 +30,7 @@ char const * etcdv3::KEEPALIVE_DONE = "keepalive done";
char const * etcdv3::WATCH_CREATE = "watch create"; char const * etcdv3::WATCH_CREATE = "watch create";
char const * etcdv3::WATCH_WRITE = "watch write"; char const * etcdv3::WATCH_WRITE = "watch write";
char const * etcdv3::WATCH_WRITES_DONE = "watch writes done"; char const * etcdv3::WATCH_WRITES_DONE = "watch writes done";
const int etcdv3::ERROR_KEY_NOT_FOUND = 100;
const int etcdv3::ERROR_COMPARE_FAILED = 101;
const int etcdv3::ERROR_KEY_ALREADY_EXISTS = 105;

View File

@ -26,8 +26,8 @@ TEST_CASE("add a new key after authenticate")
CHECK(0 < val.created_index()); CHECK(0 < val.created_index());
CHECK(0 < val.modified_index()); CHECK(0 < val.modified_index());
CHECK(0 < resp.index()); CHECK(0 < resp.index());
CHECK(105 == etcd->add("/test/key1", "43").get().error_code()); // Key already exists CHECK(etcd::ERROR_KEY_ALREADY_EXISTS == etcd->add("/test/key1", "43").get().error_code()); // Key already exists
CHECK(105 == etcd->add("/test/key1", "42").get().error_code()); // Key already exists CHECK(etcd::ERROR_KEY_ALREADY_EXISTS == etcd->add("/test/key1", "42").get().error_code()); // Key already exists
CHECK("Key already exists" == etcd->add("/test/key1", "42").get().error_message()); CHECK("Key already exists" == etcd->add("/test/key1", "42").get().error_message());
} }

View File

@ -14,12 +14,12 @@ TEST_CASE("sync operations")
// add // add
CHECK(0 == etcd.add("/test/key1", "42").error_code()); CHECK(0 == etcd.add("/test/key1", "42").error_code());
CHECK(105 == etcd.add("/test/key1", "42").error_code()); // Key already exists CHECK(etcd::ERROR_KEY_ALREADY_EXISTS == etcd.add("/test/key1", "42").error_code()); // Key already exists
CHECK("42" == etcd.get("/test/key1").value().as_string()); CHECK("42" == etcd.get("/test/key1").value().as_string());
// modify // modify
CHECK(0 == etcd.modify("/test/key1", "43").error_code()); CHECK(0 == etcd.modify("/test/key1", "43").error_code());
CHECK(100 == etcd.modify("/test/key2", "43").error_code()); // Key not found CHECK(etcd::ERROR_KEY_NOT_FOUND == etcd.modify("/test/key2", "43").error_code()); // Key not found
CHECK("43" == etcd.modify("/test/key1", "42").prev_value().as_string()); CHECK("43" == etcd.modify("/test/key1", "42").prev_value().as_string());
// set // set
@ -32,7 +32,7 @@ TEST_CASE("sync operations")
CHECK("43" == etcd.get("/test/key1").value().as_string()); CHECK("43" == etcd.get("/test/key1").value().as_string());
CHECK("44" == etcd.get("/test/key2").value().as_string()); CHECK("44" == etcd.get("/test/key2").value().as_string());
CHECK("44" == etcd.get("/test/key3").value().as_string()); CHECK("44" == etcd.get("/test/key3").value().as_string());
CHECK(100 == etcd.get("/test/key4").error_code()); // key not found CHECK(etcd::ERROR_KEY_NOT_FOUND == etcd.get("/test/key4").error_code()); // key not found
// rm // rm
CHECK(3 == etcd.ls("/test").keys().size()); CHECK(3 == etcd.ls("/test").keys().size());
@ -46,24 +46,24 @@ TEST_CASE("sync operations")
CHECK(2 == etcd.ls("/test/new_dir").keys().size()); CHECK(2 == etcd.ls("/test/new_dir").keys().size());
// rmdir // rmdir
CHECK(100 == etcd.rmdir("/test/new_dir").error_code()); // key not found CHECK(etcd::ERROR_KEY_NOT_FOUND == etcd.rmdir("/test/new_dir").error_code()); // key not found
CHECK(0 == etcd.rmdir("/test/new_dir", true).error_code()); CHECK(0 == etcd.rmdir("/test/new_dir", true).error_code());
// compare and swap // compare and swap
etcd.set("/test/key1", "42"); etcd.set("/test/key1", "42");
int index = etcd.modify_if("/test/key1", "43", "42").index(); int index = etcd.modify_if("/test/key1", "43", "42").index();
CHECK(101 == etcd.modify_if("/test/key1", "44", "42").error_code()); CHECK(etcd::ERROR_COMPARE_FAILED == etcd.modify_if("/test/key1", "44", "42").error_code());
REQUIRE(etcd.modify_if("/test/key1", "44", index).is_ok()); REQUIRE(etcd.modify_if("/test/key1", "44", index).is_ok());
CHECK(101 == etcd.modify_if("/test/key1", "45", index).error_code()); CHECK(etcd::ERROR_COMPARE_FAILED == etcd.modify_if("/test/key1", "45", index).error_code());
// atomic compare-and-delete based on prevValue // atomic compare-and-delete based on prevValue
etcd.set("/test/key1", "42"); etcd.set("/test/key1", "42");
CHECK(101 == etcd.rm_if("/test/key1", "43").error_code()); CHECK(etcd::ERROR_COMPARE_FAILED == etcd.rm_if("/test/key1", "43").error_code());
CHECK(0 == etcd.rm_if("/test/key1", "42").error_code()); CHECK(0 == etcd.rm_if("/test/key1", "42").error_code());
// atomic compare-and-delete based on prevIndex // atomic compare-and-delete based on prevIndex
index = etcd.set("/test/key1", "42").index(); index = etcd.set("/test/key1", "42").index();
CHECK(101 == etcd.rm_if("/test/key1", index - 1).error_code()); CHECK(etcd::ERROR_COMPARE_FAILED == etcd.rm_if("/test/key1", index - 1).error_code());
CHECK(0 == etcd.rm_if("/test/key1", index).error_code()); CHECK(0 == etcd.rm_if("/test/key1", index).error_code());
//leasegrant //leasegrant

View File

@ -28,8 +28,8 @@ TEST_CASE("add a new key")
CHECK(0 < val.created_index()); CHECK(0 < val.created_index());
CHECK(0 < val.modified_index()); CHECK(0 < val.modified_index());
CHECK(0 < resp.index()); CHECK(0 < resp.index());
CHECK(105 == etcd.add("/test/key1", "43").get().error_code()); // Key already exists CHECK(etcd::ERROR_KEY_ALREADY_EXISTS == etcd.add("/test/key1", "43").get().error_code()); // Key already exists
CHECK(105 == etcd.add("/test/key1", "42").get().error_code()); // Key already exists CHECK(etcd::ERROR_KEY_ALREADY_EXISTS == etcd.add("/test/key1", "42").get().error_code()); // Key already exists
CHECK("Key already exists" == etcd.add("/test/key1", "42").get().error_message()); CHECK("Key already exists" == etcd.add("/test/key1", "42").get().error_message());
} }
@ -48,7 +48,7 @@ TEST_CASE("simplified read")
{ {
etcd::Client etcd("http://127.0.0.1:2379"); etcd::Client etcd("http://127.0.0.1:2379");
CHECK("42" == etcd.get("/test/key1").get().value().as_string()); CHECK("42" == etcd.get("/test/key1").get().value().as_string());
CHECK(100 == etcd.get("/test/key2").get().error_code()); // Key not found CHECK(etcd::ERROR_KEY_NOT_FOUND == etcd.get("/test/key2").get().error_code()); // Key not found
CHECK("" == etcd.get("/test/key2").get().value().as_string()); // Key not found CHECK("" == etcd.get("/test/key2").get().value().as_string()); // Key not found
} }
@ -58,7 +58,7 @@ TEST_CASE("modify a key")
etcd::Response resp = etcd.modify("/test/key1", "43").get(); etcd::Response resp = etcd.modify("/test/key1", "43").get();
REQUIRE(0 == resp.error_code()); // overwrite REQUIRE(0 == resp.error_code()); // overwrite
CHECK("update" == resp.action()); CHECK("update" == resp.action());
CHECK(100 == etcd.modify("/test/key2", "43").get().error_code()); // Key not found CHECK(etcd::ERROR_KEY_NOT_FOUND == etcd.modify("/test/key2", "43").get().error_code()); // Key not found
CHECK("43" == etcd.modify("/test/key1", "42").get().prev_value().as_string()); CHECK("43" == etcd.modify("/test/key1", "42").get().prev_value().as_string());
} }
@ -96,13 +96,13 @@ TEST_CASE("atomic compare-and-swap")
// modify fails the second time // modify fails the second time
res = etcd.modify_if("/test/key1", "44", "42").get(); res = etcd.modify_if("/test/key1", "44", "42").get();
CHECK(!res.is_ok()); CHECK(!res.is_ok());
CHECK(101 == res.error_code()); CHECK(etcd::ERROR_COMPARE_FAILED == res.error_code());
CHECK("Compare failed" == res.error_message()); CHECK("Compare failed" == res.error_message());
// modify fails the second time // modify fails the second time
res = etcd.modify_if("/test/key222", "44", "42").get(); res = etcd.modify_if("/test/key222", "44", "42").get();
CHECK(!res.is_ok()); CHECK(!res.is_ok());
CHECK(100 == res.error_code()); CHECK(etcd::ERROR_KEY_NOT_FOUND == res.error_code());
CHECK("Key not found" == res.error_message()); CHECK("Key not found" == res.error_message());
} }
@ -111,7 +111,7 @@ TEST_CASE("delete a value")
etcd::Client etcd("http://127.0.0.1:2379"); etcd::Client etcd("http://127.0.0.1:2379");
etcd::Response resp = etcd.rm("/test/key11111").get(); etcd::Response resp = etcd.rm("/test/key11111").get();
CHECK(!resp.is_ok()); CHECK(!resp.is_ok());
CHECK(100 == resp.error_code()); CHECK(etcd::ERROR_KEY_NOT_FOUND == resp.error_code());
CHECK("Key not found" == resp.error_message()); CHECK("Key not found" == resp.error_message());
int index = etcd.get("/test/key1").get().index(); int index = etcd.get("/test/key1").get().index();
@ -145,7 +145,7 @@ TEST_CASE("atomic compare-and-delete based on prevValue")
etcd::Response res = etcd.rm_if("/test/key1", "43").get(); etcd::Response res = etcd.rm_if("/test/key1", "43").get();
CHECK(!res.is_ok()); CHECK(!res.is_ok());
CHECK(101 == res.error_code()); CHECK(etcd::ERROR_COMPARE_FAILED == res.error_code());
CHECK("Compare failed" == res.error_message()); CHECK("Compare failed" == res.error_message());
res = etcd.rm_if("/test/key1", "42").get(); res = etcd.rm_if("/test/key1", "42").get();
@ -161,7 +161,7 @@ TEST_CASE("atomic compare-and-delete based on prevIndex")
etcd::Response res = etcd.rm_if("/test/key1", index - 1).get(); etcd::Response res = etcd.rm_if("/test/key1", index - 1).get();
CHECK(!res.is_ok()); CHECK(!res.is_ok());
CHECK(101 == res.error_code()); CHECK(etcd::ERROR_COMPARE_FAILED == res.error_code());
CHECK("Compare failed" == res.error_message()); CHECK("Compare failed" == res.error_message());
res = etcd.rm_if("/test/key1", index).get(); res = etcd.rm_if("/test/key1", index).get();
@ -186,7 +186,7 @@ TEST_CASE("deep atomic compare-and-swap")
// modify fails the second time // modify fails the second time
res = etcd.modify_if("/test/key1", "44", "42").get(); res = etcd.modify_if("/test/key1", "44", "42").get();
CHECK(!res.is_ok()); CHECK(!res.is_ok());
CHECK(101 == res.error_code()); CHECK(etcd::ERROR_COMPARE_FAILED == res.error_code());
CHECK("Compare failed" == res.error_message()); CHECK("Compare failed" == res.error_message());
// succes with the correct index // succes with the correct index
@ -198,7 +198,7 @@ TEST_CASE("deep atomic compare-and-swap")
// index changes so second modify fails // index changes so second modify fails
res = etcd.modify_if("/test/key1", "45", index).get(); res = etcd.modify_if("/test/key1", "45", index).get();
CHECK(!res.is_ok()); CHECK(!res.is_ok());
CHECK(101 == res.error_code()); CHECK(etcd::ERROR_COMPARE_FAILED == res.error_code());
CHECK("Compare failed" == res.error_message()); CHECK("Compare failed" == res.error_message());
} }
@ -282,7 +282,7 @@ TEST_CASE("delete a directory")
etcd.set("/test/new_dir/key2", "value2").wait(); etcd.set("/test/new_dir/key2", "value2").wait();
etcd.set("/test/new_dir/key3", "value3").wait(); etcd.set("/test/new_dir/key3", "value3").wait();
CHECK(100 == etcd.rmdir("/test/new_dir").get().error_code()); // key not found CHECK(etcd::ERROR_KEY_NOT_FOUND == etcd.rmdir("/test/new_dir").get().error_code()); // key not found
etcd::Response resp = etcd.ls("/test/new_dir").get(); etcd::Response resp = etcd.ls("/test/new_dir").get();
resp = etcd.rmdir("/test/new_dir", true).get(); resp = etcd.rmdir("/test/new_dir", true).get();
@ -296,12 +296,12 @@ TEST_CASE("delete a directory")
resp = etcd.rmdir("/test/dirnotfound", true).get(); resp = etcd.rmdir("/test/dirnotfound", true).get();
CHECK(!resp.is_ok()); CHECK(!resp.is_ok());
CHECK(100 == resp.error_code()); CHECK(etcd::ERROR_KEY_NOT_FOUND == resp.error_code());
CHECK("Key not found" == resp.error_message()); CHECK("Key not found" == resp.error_message());
resp = etcd.rmdir("/test/new_dir", false).get(); resp = etcd.rmdir("/test/new_dir", false).get();
CHECK(!resp.is_ok()); CHECK(!resp.is_ok());
CHECK(100 == resp.error_code()); CHECK(etcd::ERROR_KEY_NOT_FOUND == resp.error_code());
CHECK("Key not found" == resp.error_message()); CHECK("Key not found" == resp.error_message());
} }
@ -309,7 +309,7 @@ TEST_CASE("delete by range")
{ {
etcd::Client etcd("http://127.0.0.1:2379"); etcd::Client etcd("http://127.0.0.1:2379");
CHECK(100 == etcd.rmdir("/test/new_dir").get().error_code()); // key not found CHECK(etcd::ERROR_KEY_NOT_FOUND == etcd.rmdir("/test/new_dir").get().error_code()); // key not found
etcd::Response resp = etcd.ls("/test/new_dir").get(); etcd::Response resp = etcd.ls("/test/new_dir").get();
etcd.set("/test/new_dir/key1", "value1").wait(); etcd.set("/test/new_dir/key1", "value1").wait();

View File

@ -29,8 +29,8 @@ TEST_CASE("add a new key after authenticate")
CHECK(0 < val.created_index()); CHECK(0 < val.created_index());
CHECK(0 < val.modified_index()); CHECK(0 < val.modified_index());
CHECK(0 < resp.index()); CHECK(0 < resp.index());
CHECK(105 == etcd->add("/test/key1", "43").get().error_code()); // Key already exists CHECK(etcd::ERROR_KEY_ALREADY_EXISTS == etcd->add("/test/key1", "43").get().error_code()); // Key already exists
CHECK(105 == etcd->add("/test/key1", "42").get().error_code()); // Key already exists CHECK(etcd::ERROR_KEY_ALREADY_EXISTS == etcd->add("/test/key1", "42").get().error_code()); // Key already exists
CHECK("Key already exists" == etcd->add("/test/key1", "42").get().error_message()); CHECK("Key already exists" == etcd->add("/test/key1", "42").get().error_message());
} }