First commit

This commit is contained in:
Arches 2016-08-29 16:14:57 +02:00
parent 19061bd9e1
commit e37cb46922
23 changed files with 5082 additions and 0 deletions

165
etcd/Client.hpp.orig Normal file
View File

@ -0,0 +1,165 @@
#ifndef __ETCD_CLIENT_HPP__
#define __ETCD_CLIENT_HPP__
#include "etcd/Response.hpp"
#include "v3/include/Transaction.hpp"
#include "v3/include/AsyncTxnResponse.hpp"
#include <cpprest/http_client.h>
#include <string>
#include <grpc++/grpc++.h>
#include "proto/rpc.grpc.pb.h"
using etcdserverpb::KV;
using etcdserverpb::Watch;
namespace etcd
{
/**
* Client is responsible for maintaining a connection towards an etcd server.
* Etcd operations can be reached via the methods of the client.
*/
class Client
{
public:
/**
* Constructs an etcd client object.
* @param etcd_url is the url of the etcd server to connect to, like "http://127.0.0.1:4001"
*/
Client(std::string const & etcd_url);
/**
* Sends a get request to the etcd server
* @param key is the key to be read
*/
pplx::task<Response> get(std::string const & key);
/**
* Sets the value of a key. The key will be modified if already exists or created
* if it does not exists.
* @param key is the key to be created or modified
* @param value is the new value to be set
*/
pplx::task<Response> set(std::string const & key, std::string const & value);
/**
* Creates a new key and sets it's value. Fails if the key already exists.
* @param key is the key to be created
* @param value is the value to be set
*/
pplx::task<Response> add(std::string const & key, std::string const & value);
/**
* Modifies an existing key. Fails if the key does not exists.
* @param key is the key to be modified
* @param value is the new value to be set
*/
pplx::task<Response> modify(std::string const & key, std::string const & value);
/**
* Modifies an existing key only if it has a specific value. Fails if the key does not exists
* or the original value differs from the expected one.
* @param key is the key to be modified
* @param value is the new value to be set
* @param old_value is the value to be replaced
*/
pplx::task<Response> modify_if(std::string const & key, std::string const & value, std::string const & old_value);
/**
* Modifies an existing key only if it has a specific modification index value. Fails if the key
* does not exists or the modification index of the previous value differs from the expected one.
* @param key is the key to be modified
* @param value is the new value to be set
* @param old_index is the expected index of the original value
*/
pplx::task<Response> modify_if(std::string const & key, std::string const & value, int old_index);
/**
* Removes a single key. The key has to point to a plain, non directory entry.
* @param key is the key to be deleted
*/
pplx::task<Response> rm(std::string const & key);
/**
* Removes a single key but only if it has a specific value. Fails if the key does not exists
* or the its value differs from the expected one.
* @param key is the key to be deleted
*/
pplx::task<Response> rm_if(std::string const & key, std::string const & old_value);
/**
* Removes an existing key only if it has a specific modification index value. Fails if the key
* does not exists or the modification index of it differs from the expected one.
* @param key is the key to be deleted
* @param old_index is the expected index of the existing value
*/
pplx::task<Response> rm_if(std::string const & key, int old_index);
/**
* Gets a directory listing of the directory identified by the key.
* @param key is the key to be listed
*/
pplx::task<Response> ls(std::string const & key);
/**
* Removes a directory node. Fails if the parent directory dos not exists or not a directory.
* @param key is the directory to be created to be listed
* @param recursive if true then delete a whole subtree, otherwise deletes only an empty directory.
*/
pplx::task<Response> rmdir(std::string const & key, bool recursive = false);
/**
* Watches for changes of a key or a subtree. Please note that if you watch e.g. "/testdir" and
* a new key is created, like "/testdir/newkey" then no change happened in the value of
* "/testdir" so your watch will not detect this. If you want to detect addition and deletion of
* directory entries then you have to do a recursive watch.
* @param key is the value or directory to be watched
* @param recursive if true watch a whole subtree
*/
pplx::task<Response> watch(std::string const & key, bool recursive = false);
/**
* Watches for changes of a key or a subtree from a specific index. The index value can be in the "past".
* @param key is the value or directory to be watched
* @param fromIndex the first index we are interested in
* @param recursive if true watch a whole subtree
*/
pplx::task<Response> watch(std::string const & key, int fromIndex, bool recursive = false);
protected:
std::unique_ptr<KV::Stub> stub_;
std::unique_ptr<Watch::Stub> watchServiceStub;
std::unique_ptr<KV::Stub> stub_;
pplx::task<etcd::Response> send_asyncput(const std::string& key, const std::string& value);
pplx::task<etcd::Response> send_asyncadd(std::string const & key, const std::string& value);
pplx::task<etcd::Response> send_asyncmodify(std::string const & key, std::string const & value);
pplx::task<etcd::Response> send_asyncget(std::string const & key,std::string const& range_end="");
pplx::task<etcd::Response> send_put(const std::string& key, const std::string& value);
pplx::task<etcd::Response> send_get(std::string const & key);
pplx::task<etcd::Response> send_asyncmodify_if(std::string const & key, std::string const & value, std::string const & old_value);
<<<<<<< a592ce75a199b4e275a50c5f29992aa7dc0ff8d1
pplx::task<etcd::Response> send_asyncmodify_if(std::string const & key, std::string const & value, int old_index);
pplx::task<etcd::Response> send_asyncdelete(std::string const & key, bool recursive);
pplx::task<etcd::Response> send_asyncrm_if(std::string const &key, std::string const &old_value);
pplx::task<etcd::Response> send_asyncrm_if(std::string const &key, int old_index);
pplx::task<etcd::Response> send_asyncwatch(std::string const & key, bool recursive);
pplx::task<etcd::Response> send_asyncwatch(std::string const & key, int fromIndex, bool recursive);
private:
std::shared_ptr<etcdv3::AsyncTxnResponse> initiate_transaction(const std::string &operation,
etcdv3::Transaction& transaction);
};
=======
pplx::task<etcd::Response> send_asyncdelete(std::string const & key, bool recursive);
};
>>>>>>> Added delete
}
#endif

View File

@ -0,0 +1,184 @@
#ifndef __ETCD_CLIENT_HPP__
#define __ETCD_CLIENT_HPP__
#include "etcd/Response.hpp"
#include <cpprest/http_client.h>
#include <string>
#include <grpc++/grpc++.h>
#include "proto/rpc.grpc.pb.h"
<<<<<<< b05a30586ef0191ca0d81fb87d79d781fc89f341
using grpc::Channel;
using grpc::ClientAsyncResponseReader;
using grpc::ClientContext;
using grpc::CompletionQueue;
using grpc::Status;
using etcdserverpb::PutRequest;
using etcdserverpb::PutResponse;
using etcdserverpb::RangeRequest;
using etcdserverpb::RangeResponse;
=======
>>>>>>> Use Txn
using etcdserverpb::KV;
using etcdserverpb::Watch;
namespace etcd
{
/**
* Client is responsible for maintaining a connection towards an etcd server.
* Etcd operations can be reached via the methods of the client.
*/
class Client
{
public:
/**
* Constructs an etcd client object.
* @param etcd_url is the url of the etcd server to connect to, like "http://127.0.0.1:4001"
*/
Client(std::string const & etcd_url);
/**
* Sends a get request to the etcd server
* @param key is the key to be read
*/
pplx::task<Response> get(std::string const & key);
/**
* Sets the value of a key. The key will be modified if already exists or created
* if it does not exists.
* @param key is the key to be created or modified
* @param value is the new value to be set
*/
pplx::task<Response> set(std::string const & key, std::string const & value);
/**
* Creates a new key and sets it's value. Fails if the key already exists.
* @param key is the key to be created
* @param value is the value to be set
*/
pplx::task<Response> add(std::string const & key, std::string const & value);
/**
* Modifies an existing key. Fails if the key does not exists.
* @param key is the key to be modified
* @param value is the new value to be set
*/
pplx::task<Response> modify(std::string const & key, std::string const & value);
/**
* Modifies an existing key only if it has a specific value. Fails if the key does not exists
* or the original value differs from the expected one.
* @param key is the key to be modified
* @param value is the new value to be set
* @param old_value is the value to be replaced
*/
pplx::task<Response> modify_if(std::string const & key, std::string const & value, std::string const & old_value);
/**
* Modifies an existing key only if it has a specific modification index value. Fails if the key
* does not exists or the modification index of the previous value differs from the expected one.
* @param key is the key to be modified
* @param value is the new value to be set
* @param old_index is the expected index of the original value
*/
pplx::task<Response> modify_if(std::string const & key, std::string const & value, int old_index);
/**
* Removes a single key. The key has to point to a plain, non directory entry.
* @param key is the key to be deleted
*/
pplx::task<Response> rm(std::string const & key);
/**
* Removes a single key but only if it has a specific value. Fails if the key does not exists
* or the its value differs from the expected one.
* @param key is the key to be deleted
*/
pplx::task<Response> rm_if(std::string const & key, std::string const & old_value);
/**
* Removes an existing key only if it has a specific modification index value. Fails if the key
* does not exists or the modification index of it differs from the expected one.
* @param key is the key to be deleted
* @param old_index is the expected index of the existing value
*/
pplx::task<Response> rm_if(std::string const & key, int old_index);
/**
* Gets a directory listing of the directory identified by the key.
* @param key is the key to be listed
*/
pplx::task<Response> ls(std::string const & key);
/**
* Creates a new directory node. Fails if the parent directory dos not exists or not a directory.
* @param key is the directory to be created to be listed
*/
pplx::task<Response> mkdir(std::string const & key);
/**
* Removes a directory node. Fails if the parent directory dos not exists or not a directory.
* @param key is the directory to be created to be listed
* @param recursive if true then delete a whole subtree, otherwise deletes only an empty directory.
*/
pplx::task<Response> rmdir(std::string const & key, bool recursive = false);
/**
* Watches for changes of a key or a subtree. Please note that if you watch e.g. "/testdir" and
* a new key is created, like "/testdir/newkey" then no change happened in the value of
* "/testdir" so your watch will not detect this. If you want to detect addition and deletion of
* directory entries then you have to do a recursive watch.
* @param key is the value or directory to be watched
* @param recursive if true watch a whole subtree
*/
pplx::task<Response> watch(std::string const & key, bool recursive = false);
/**
* Watches for changes of a key or a subtree from a specific index. The index value can be in the "past".
* @param key is the value or directory to be watched
* @param fromIndex the first index we are interested in
* @param recursive if true watch a whole subtree
*/
pplx::task<Response> watch(std::string const & key, int fromIndex, bool recursive = false);
protected:
pplx::task<Response> send_get_request(web::http::uri_builder & uri);
pplx::task<Response> send_del_request(web::http::uri_builder & uri);
pplx::task<Response> send_put_request(web::http::uri_builder & uri, std::string const & key, std::string const & value);
web::http::client::http_client client;
std::unique_ptr<KV::Stub> stub_;
pplx::task<etcd::Response> send_asyncput(const std::string& key, const std::string& value);
std::unique_ptr<Watch::Stub> watchServiceStub;
pplx::task<etcd::Response> send_asyncget(std::string const & key);
pplx::task<etcd::Response> send_asyncadd(std::string const & key, const std::string& value);
pplx::task<etcd::Response> send_asyncmodify(std::string const & key, std::string const & value);
<<<<<<< b05a30586ef0191ca0d81fb87d79d781fc89f341
pplx::task<etcd::Response> send_put(const std::string& key, const std::string& value);
pplx::task<etcd::Response> send_get(std::string const & key);
pplx::task<etcd::Response> send_asyncmodify_if(std::string const & key, std::string const & value, std::string const & old_value);
etcdv3::grpcClient grpcClient;
private:
pplx::task<Response> removeEntryWithKey(std::string const &entryKey);
pplx::task<Response> removeEntryWithKeyAndValue(std::string const &entryKey, std::string const &oldValue);
pplx::task<Response> removeEntryWithKeyAndIndex(std::string const &entryKey, int oldIndex);
pplx::task<Response> modifyEntryWithValueAndOldIndex(std::string const & key, std::string const & value, int old_index);
=======
pplx::task<etcd::Response> send_asyncmodify_if(std::string const & key, std::string const & value, std::string const & old_value);
>>>>>>> Use Txn
};
}
#endif

162
etcd/Client_BASE_12440.hpp Normal file
View File

@ -0,0 +1,162 @@
#ifndef __ETCD_CLIENT_HPP__
#define __ETCD_CLIENT_HPP__
#include "etcd/Response.hpp"
#include <cpprest/http_client.h>
#include <string>
#include <grpc++/grpc++.h>
#include "proto/rpc.grpc.pb.h"
#include "v3/include/AsyncRangeResponse.hpp"
#include "v3/include/grpcClient.hpp"
using grpc::Channel;
using etcdserverpb::PutRequest;
using etcdserverpb::RangeRequest;
using etcdserverpb::KV;
namespace etcd
{
/**
* Client is responsible for maintaining a connection towards an etcd server.
* Etcd operations can be reached via the methods of the client.
*/
class Client
{
public:
/**
* Constructs an etcd client object.
* @param etcd_url is the url of the etcd server to connect to, like "http://127.0.0.1:4001"
*/
Client(std::string const & etcd_url);
/**
* Sends a get request to the etcd server
* @param key is the key to be read
*/
pplx::task<Response> get(std::string const & key);
/**
* Sets the value of a key. The key will be modified if already exists or created
* if it does not exists.
* @param key is the key to be created or modified
* @param value is the new value to be set
*/
pplx::task<Response> set(std::string const & key, std::string const & value);
/**
* Creates a new key and sets it's value. Fails if the key already exists.
* @param key is the key to be created
* @param value is the value to be set
*/
pplx::task<Response> add(std::string const & key, std::string const & value);
/**
* Modifies an existing key. Fails if the key does not exists.
* @param key is the key to be modified
* @param value is the new value to be set
*/
pplx::task<Response> modify(std::string const & key, std::string const & value);
/**
* Modifies an existing key only if it has a specific value. Fails if the key does not exists
* or the original value differs from the expected one.
* @param key is the key to be modified
* @param value is the new value to be set
* @param old_value is the value to be replaced
*/
pplx::task<Response> modify_if(std::string const & key, std::string const & value, std::string const & old_value);
/**
* Modifies an existing key only if it has a specific modification index value. Fails if the key
* does not exists or the modification index of the previous value differs from the expected one.
* @param key is the key to be modified
* @param value is the new value to be set
* @param old_index is the expected index of the original value
*/
pplx::task<Response> modify_if(std::string const & key, std::string const & value, int old_index);
/**
* Removes a single key. The key has to point to a plain, non directory entry.
* @param key is the key to be deleted
*/
pplx::task<Response> rm(std::string const & key);
/**
* Removes a single key but only if it has a specific value. Fails if the key does not exists
* or the its value differs from the expected one.
* @param key is the key to be deleted
*/
pplx::task<Response> rm_if(std::string const & key, std::string const & old_value);
/**
* Removes an existing key only if it has a specific modification index value. Fails if the key
* does not exists or the modification index of it differs from the expected one.
* @param key is the key to be deleted
* @param old_index is the expected index of the existing value
*/
pplx::task<Response> rm_if(std::string const & key, int old_index);
/**
* Gets a directory listing of the directory identified by the key.
* @param key is the key to be listed
*/
pplx::task<Response> ls(std::string const & key);
/**
* Creates a new directory node. Fails if the parent directory dos not exists or not a directory.
* @param key is the directory to be created to be listed
*/
pplx::task<Response> mkdir(std::string const & key);
/**
* Removes a directory node. Fails if the parent directory dos not exists or not a directory.
* @param key is the directory to be created to be listed
* @param recursive if true then delete a whole subtree, otherwise deletes only an empty directory.
*/
pplx::task<Response> rmdir(std::string const & key, bool recursive = false);
/**
* Watches for changes of a key or a subtree. Please note that if you watch e.g. "/testdir" and
* a new key is created, like "/testdir/newkey" then no change happened in the value of
* "/testdir" so your watch will not detect this. If you want to detect addition and deletion of
* directory entries then you have to do a recursive watch.
* @param key is the value or directory to be watched
* @param recursive if true watch a whole subtree
*/
pplx::task<Response> watch(std::string const & key, bool recursive = false);
/**
* Watches for changes of a key or a subtree from a specific index. The index value can be in the "past".
* @param key is the value or directory to be watched
* @param fromIndex the first index we are interested in
* @param recursive if true watch a whole subtree
*/
pplx::task<Response> watch(std::string const & key, int fromIndex, bool recursive = false);
protected:
pplx::task<Response> send_get_request(web::http::uri_builder & uri);
pplx::task<Response> send_del_request(web::http::uri_builder & uri);
pplx::task<Response> send_put_request(web::http::uri_builder & uri, std::string const & key, std::string const & value);
web::http::client::http_client client;
pplx::task<etcd::Response> send_asyncput(const std::string& key, const std::string& value);
pplx::task<etcd::Response> send_asyncget(std::string const & key);
pplx::task<etcd::Response> send_asyncadd(std::string const & key, const std::string& value);
pplx::task<etcd::Response> send_asyncmodify(std::string const & key, std::string const & value);
pplx::task<etcd::Response> send_asyncmodify_if(std::string const & key, std::string const & value, std::string const & old_value);
etcdv3::grpcClient grpcClient;
};
}
#endif

179
etcd/Client_LOCAL_12440.hpp Normal file
View File

@ -0,0 +1,179 @@
#ifndef __ETCD_CLIENT_HPP__
#define __ETCD_CLIENT_HPP__
#include "etcd/Response.hpp"
#include <cpprest/http_client.h>
#include <string>
#include <grpc++/grpc++.h>
#include "proto/rpc.grpc.pb.h"
#include "v3/include/AsyncRangeResponse.hpp"
#include "v3/include/grpcClient.hpp"
using grpc::Channel;
using grpc::ClientAsyncResponseReader;
using grpc::ClientContext;
using grpc::CompletionQueue;
using grpc::Status;
using etcdserverpb::PutRequest;
using etcdserverpb::PutResponse;
using etcdserverpb::RangeRequest;
using etcdserverpb::RangeResponse;
using etcdserverpb::KV;
using etcdserverpb::Watch;
namespace etcd
{
/**
* Client is responsible for maintaining a connection towards an etcd server.
* Etcd operations can be reached via the methods of the client.
*/
class Client
{
public:
/**
* Constructs an etcd client object.
* @param etcd_url is the url of the etcd server to connect to, like "http://127.0.0.1:4001"
*/
Client(std::string const & etcd_url);
/**
* Sends a get request to the etcd server
* @param key is the key to be read
*/
pplx::task<Response> get(std::string const & key);
/**
* Sets the value of a key. The key will be modified if already exists or created
* if it does not exists.
* @param key is the key to be created or modified
* @param value is the new value to be set
*/
pplx::task<Response> set(std::string const & key, std::string const & value);
/**
* Creates a new key and sets it's value. Fails if the key already exists.
* @param key is the key to be created
* @param value is the value to be set
*/
pplx::task<Response> add(std::string const & key, std::string const & value);
/**
* Modifies an existing key. Fails if the key does not exists.
* @param key is the key to be modified
* @param value is the new value to be set
*/
pplx::task<Response> modify(std::string const & key, std::string const & value);
/**
* Modifies an existing key only if it has a specific value. Fails if the key does not exists
* or the original value differs from the expected one.
* @param key is the key to be modified
* @param value is the new value to be set
* @param old_value is the value to be replaced
*/
pplx::task<Response> modify_if(std::string const & key, std::string const & value, std::string const & old_value);
/**
* Modifies an existing key only if it has a specific modification index value. Fails if the key
* does not exists or the modification index of the previous value differs from the expected one.
* @param key is the key to be modified
* @param value is the new value to be set
* @param old_index is the expected index of the original value
*/
pplx::task<Response> modify_if(std::string const & key, std::string const & value, int old_index);
/**
* Removes a single key. The key has to point to a plain, non directory entry.
* @param key is the key to be deleted
*/
pplx::task<Response> rm(std::string const & key);
/**
* Removes a single key but only if it has a specific value. Fails if the key does not exists
* or the its value differs from the expected one.
* @param key is the key to be deleted
*/
pplx::task<Response> rm_if(std::string const & key, std::string const & old_value);
/**
* Removes an existing key only if it has a specific modification index value. Fails if the key
* does not exists or the modification index of it differs from the expected one.
* @param key is the key to be deleted
* @param old_index is the expected index of the existing value
*/
pplx::task<Response> rm_if(std::string const & key, int old_index);
/**
* Gets a directory listing of the directory identified by the key.
* @param key is the key to be listed
*/
pplx::task<Response> ls(std::string const & key);
/**
* Creates a new directory node. Fails if the parent directory dos not exists or not a directory.
* @param key is the directory to be created to be listed
*/
pplx::task<Response> mkdir(std::string const & key);
/**
* Removes a directory node. Fails if the parent directory dos not exists or not a directory.
* @param key is the directory to be created to be listed
* @param recursive if true then delete a whole subtree, otherwise deletes only an empty directory.
*/
pplx::task<Response> rmdir(std::string const & key, bool recursive = false);
/**
* Watches for changes of a key or a subtree. Please note that if you watch e.g. "/testdir" and
* a new key is created, like "/testdir/newkey" then no change happened in the value of
* "/testdir" so your watch will not detect this. If you want to detect addition and deletion of
* directory entries then you have to do a recursive watch.
* @param key is the value or directory to be watched
* @param recursive if true watch a whole subtree
*/
pplx::task<Response> watch(std::string const & key, bool recursive = false);
/**
* Watches for changes of a key or a subtree from a specific index. The index value can be in the "past".
* @param key is the value or directory to be watched
* @param fromIndex the first index we are interested in
* @param recursive if true watch a whole subtree
*/
pplx::task<Response> watch(std::string const & key, int fromIndex, bool recursive = false);
protected:
pplx::task<Response> send_get_request(web::http::uri_builder & uri);
pplx::task<Response> send_del_request(web::http::uri_builder & uri);
pplx::task<Response> send_put_request(web::http::uri_builder & uri, std::string const & key, std::string const & value);
web::http::client::http_client client;
std::unique_ptr<KV::Stub> stub_;
pplx::task<etcd::Response> send_asyncput(const std::string& key, const std::string& value);
std::unique_ptr<Watch::Stub> watchServiceStub;
pplx::task<etcd::Response> send_asyncget(std::string const & key);
pplx::task<etcd::Response> send_asyncadd(std::string const & key, const std::string& value);
pplx::task<etcd::Response> send_asyncmodify(std::string const & key, std::string const & value);
pplx::task<etcd::Response> send_put(const std::string& key, const std::string& value);
pplx::task<etcd::Response> send_get(std::string const & key);
pplx::task<etcd::Response> send_asyncmodify_if(std::string const & key, std::string const & value, std::string const & old_value);
etcdv3::grpcClient grpcClient;
private:
pplx::task<Response> removeEntryWithKey(std::string const &entryKey);
pplx::task<Response> removeEntryWithKeyAndValue(std::string const &entryKey, std::string const &oldValue);
pplx::task<Response> removeEntryWithKeyAndIndex(std::string const &entryKey, int oldIndex);
pplx::task<Response> modifyEntryWithValueAndOldIndex(std::string const & key, std::string const & value, int old_index);
};
}
#endif

View File

@ -0,0 +1,154 @@
#ifndef __ETCD_CLIENT_HPP__
#define __ETCD_CLIENT_HPP__
#include "etcd/Response.hpp"
#include <cpprest/http_client.h>
#include <string>
#include <grpc++/grpc++.h>
#include "proto/rpc.grpc.pb.h"
using etcdserverpb::KV;
namespace etcd
{
/**
* Client is responsible for maintaining a connection towards an etcd server.
* Etcd operations can be reached via the methods of the client.
*/
class Client
{
public:
/**
* Constructs an etcd client object.
* @param etcd_url is the url of the etcd server to connect to, like "http://127.0.0.1:4001"
*/
Client(std::string const & etcd_url);
/**
* Sends a get request to the etcd server
* @param key is the key to be read
*/
pplx::task<Response> get(std::string const & key);
/**
* Sets the value of a key. The key will be modified if already exists or created
* if it does not exists.
* @param key is the key to be created or modified
* @param value is the new value to be set
*/
pplx::task<Response> set(std::string const & key, std::string const & value);
/**
* Creates a new key and sets it's value. Fails if the key already exists.
* @param key is the key to be created
* @param value is the value to be set
*/
pplx::task<Response> add(std::string const & key, std::string const & value);
/**
* Modifies an existing key. Fails if the key does not exists.
* @param key is the key to be modified
* @param value is the new value to be set
*/
pplx::task<Response> modify(std::string const & key, std::string const & value);
/**
* Modifies an existing key only if it has a specific value. Fails if the key does not exists
* or the original value differs from the expected one.
* @param key is the key to be modified
* @param value is the new value to be set
* @param old_value is the value to be replaced
*/
pplx::task<Response> modify_if(std::string const & key, std::string const & value, std::string const & old_value);
/**
* Modifies an existing key only if it has a specific modification index value. Fails if the key
* does not exists or the modification index of the previous value differs from the expected one.
* @param key is the key to be modified
* @param value is the new value to be set
* @param old_index is the expected index of the original value
*/
pplx::task<Response> modify_if(std::string const & key, std::string const & value, int old_index);
/**
* Removes a single key. The key has to point to a plain, non directory entry.
* @param key is the key to be deleted
*/
pplx::task<Response> rm(std::string const & key);
/**
* Removes a single key but only if it has a specific value. Fails if the key does not exists
* or the its value differs from the expected one.
* @param key is the key to be deleted
*/
pplx::task<Response> rm_if(std::string const & key, std::string const & old_value);
/**
* Removes an existing key only if it has a specific modification index value. Fails if the key
* does not exists or the modification index of it differs from the expected one.
* @param key is the key to be deleted
* @param old_index is the expected index of the existing value
*/
pplx::task<Response> rm_if(std::string const & key, int old_index);
/**
* Gets a directory listing of the directory identified by the key.
* @param key is the key to be listed
*/
pplx::task<Response> ls(std::string const & key);
/**
* Creates a new directory node. Fails if the parent directory dos not exists or not a directory.
* @param key is the directory to be created to be listed
*/
pplx::task<Response> mkdir(std::string const & key);
/**
* Removes a directory node. Fails if the parent directory dos not exists or not a directory.
* @param key is the directory to be created to be listed
* @param recursive if true then delete a whole subtree, otherwise deletes only an empty directory.
*/
pplx::task<Response> rmdir(std::string const & key, bool recursive = false);
/**
* Watches for changes of a key or a subtree. Please note that if you watch e.g. "/testdir" and
* a new key is created, like "/testdir/newkey" then no change happened in the value of
* "/testdir" so your watch will not detect this. If you want to detect addition and deletion of
* directory entries then you have to do a recursive watch.
* @param key is the value or directory to be watched
* @param recursive if true watch a whole subtree
*/
pplx::task<Response> watch(std::string const & key, bool recursive = false);
/**
* Watches for changes of a key or a subtree from a specific index. The index value can be in the "past".
* @param key is the value or directory to be watched
* @param fromIndex the first index we are interested in
* @param recursive if true watch a whole subtree
*/
pplx::task<Response> watch(std::string const & key, int fromIndex, bool recursive = false);
protected:
pplx::task<Response> send_get_request(web::http::uri_builder & uri);
pplx::task<Response> send_del_request(web::http::uri_builder & uri);
pplx::task<Response> send_put_request(web::http::uri_builder & uri, std::string const & key, std::string const & value);
web::http::client::http_client client;
std::unique_ptr<KV::Stub> stub_;
pplx::task<etcd::Response> send_asyncput(const std::string& key, const std::string& value);
pplx::task<etcd::Response> send_asyncget(std::string const & key);
pplx::task<etcd::Response> send_asyncadd(std::string const & key, const std::string& value);
pplx::task<etcd::Response> send_asyncmodify(std::string const & key, std::string const & value);
pplx::task<etcd::Response> send_asyncmodify_if(std::string const & key, std::string const & value, std::string const & old_value);
};
}
#endif

131
etcd/Response.hpp.orig Normal file
View File

@ -0,0 +1,131 @@
#ifndef __ETCD_RESPONSE_HPP__
#define __ETCD_RESPONSE_HPP__
#include <cpprest/http_client.h>
#include <string>
#include <vector>
#include "etcd/Value.hpp"
#include <grpc++/grpc++.h>
#include "v3/include/V3Response.hpp"
#include <grpc++/grpc++.h>
#include <iostream>
namespace etcd
{
typedef std::vector<std::string> Keys;
/**
* The Reponse object received for the requests of etcd::Client
*/
class Response
{
public:
static pplx::task<Response> create(pplx::task<web::http::http_response> response_task);
<<<<<<< d262688a8e4d8413a46f5fac4225c549c3039c77
=======
static pplx::task<Response> createResponse(const etcdv3::V3Response& response);
>>>>>>> make templated create with shared_ptr arguement
template<typename T>static pplx::task<etcd::Response> create(std::shared_ptr<T> call)
{
return pplx::task<etcd::Response>([call]()
{
<<<<<<< d262688a8e4d8413a46f5fac4225c549c3039c77
etcd::Response resp;
call->waitForResponse();
=======
void* got_tag;
bool ok = false;
etcd::Response resp;
//blocking
call->cq_.Next(&got_tag, &ok);
GPR_ASSERT(got_tag == (void*)call.get());
>>>>>>> make templated create with shared_ptr arguement
auto v3resp = call->ParseResponse();
resp = etcd::Response(v3resp);
return resp;
});
};
Response();
/**
* Returns true if this is a successful response
*/
bool is_ok() const;
/**
* Returns the error code received from the etcd server. In case of success the error code is 0.
*/
int error_code() const;
/**
* Returns the string representation of the error code
*/
std::string const & error_message() const;
/**
* Returns the action type of the operation that this response belongs to.
*/
std::string const & action() const;
/**
* Returns the current index value of etcd
*/
int index() const;
/**
* Returns the value object of the response to a get/set/modify operation.
*/
Value const & value() const;
/**
* Returns the previous value object of the response to a set/modify/rm operation.
*/
Value const & prev_value() const;
/**
* Returns the index-th value of the response to an 'ls' operation. Equivalent to values()[index]
*/
Value const & value(int index) const;
/**
* Returns the vector of values in a directory in response to an 'ls' operation.
*/
Values const & values() const;
/**
* Returns the vector of keys in a directory in response to an 'ls' operation.
*/
Keys const & keys() const;
/**
* Returns the index-th key in a directory listing. Same as keys()[index]
*/
std::string const & key(int index) const;
protected:
Response(web::http::http_response http_response, web::json::value json_value);
Response(const etcdv3::V3Response& response);
int _error_code;
std::string _error_message;
int _index;
std::string _action;
Value _value;
Value _prev_value;
Values _values;
Keys _keys;
};
}
#endif

14
src/CMakeLists.txt.orig Normal file
View File

@ -0,0 +1,14 @@
<<<<<<< 18e11819d9a15bd08dcaf09c41fb91ae8cb0aa52
add_library(etcd-cpp-api SHARED ../proto/kv.pb.cc ../proto/auth.pb.cc ../proto/rpc.pb.cc ../proto/rpc.grpc.pb.cc ../v3/src/AsyncTxnResponse.cpp ../v3/src/AsyncRangeResponse.cpp ../v3/src/AsyncWatchResponse.cpp ../v3/src/Transaction.cpp Client.cpp Response.cpp Value.cpp json_constants.cpp)
=======
add_library(etcd-cpp-api SHARED ../proto/kv.pb.cc ../proto/auth.pb.cc ../proto/rpc.pb.cc ../proto/rpc.grpc.pb.cc ../v3/src/AsyncRangeResponse ../v3/src/AsyncTxnResponse.cpp Client.cpp Response.cpp Value.cpp json_constants.cpp)
>>>>>>> Added implementation for ls
set_property(TARGET etcd-cpp-api PROPERTY CXX_STANDARD 11)
target_link_libraries(etcd-cpp-api ${CPPREST_LIB} boost_system ssl crypto protobuf grpc++)
install (TARGETS etcd-cpp-api DESTINATION lib)
install (FILES ../etcd/Client.hpp
../etcd/Response.hpp
../etcd/Value.hpp
DESTINATION include/etcd)

553
src/Client.cpp.orig Normal file
View File

@ -0,0 +1,553 @@
#include <memory>
#include "etcd/Client.hpp"
#include "v3/include/AsyncTxnResponse.hpp"
#include "v3/include/AsyncRangeResponse.hpp"
#include "v3/include/AsyncWatchResponse.hpp"
#include "v3/include/Transaction.hpp"
#include <iostream>
using grpc::Channel;
using etcdserverpb::PutRequest;
using etcdserverpb::RangeRequest;
using etcdserverpb::TxnRequest;
using etcdserverpb::DeleteRangeRequest;
using etcdserverpb::Compare;
using etcdserverpb::RequestOp;
using grpc::ClientReaderWriter;
using etcdserverpb::WatchRequest;
using etcdserverpb::WatchResponse;
using etcdserverpb::WatchCreateRequest;
using grpc::Channel;
using etcdserverpb::PutRequest;
using etcdserverpb::RangeRequest;
using etcdserverpb::TxnRequest;
using etcdserverpb::DeleteRangeRequest;
using etcdserverpb::Compare;
using etcdserverpb::RequestOp;
using grpc::ClientReaderWriter;
using etcdserverpb::WatchRequest;
using etcdserverpb::WatchResponse;
using etcdserverpb::WatchCreateRequest;
etcd::Client::Client(std::string const & address)
{
std::string stripped_address(address);
std::string substr("http://");
std::string::size_type i = stripped_address.find(substr);
if(i != std::string::npos)
{
stripped_address.erase(i,substr.length());
}
std::shared_ptr<Channel> channel = grpc::CreateChannel(stripped_address, grpc::InsecureChannelCredentials());
stub_= KV::NewStub(channel);
<<<<<<< d262688a8e4d8413a46f5fac4225c549c3039c77
{
stripped_address.erase(i,substr.length());
}
std::shared_ptr<Channel> channel = grpc::CreateChannel(stripped_address, grpc::InsecureChannelCredentials());
stub_= KV::NewStub(channel);
watchServiceStub= Watch::NewStub(channel);
=======
stub1_= Watch::NewStub(channel);
>>>>>>> make templated create with shared_ptr arguement
}
pplx::task<etcd::Response> etcd::Client::get(std::string const & key)
{
return send_asyncget(key);
}
pplx::task<etcd::Response> etcd::Client::set(std::string const & key, std::string const & value)
{
return send_asyncput(key,value);
}
pplx::task<etcd::Response> etcd::Client::add(std::string const & key, std::string const & value)
{
return send_asyncadd(key,value);
}
pplx::task<etcd::Response> etcd::Client::modify(std::string const & key, std::string const & value)
{
return send_asyncmodify(key,value);
}
pplx::task<etcd::Response> etcd::Client::modify_if(std::string const & key, std::string const & value, std::string const & old_value)
{
return send_asyncmodify_if(key, value, old_value);
}
pplx::task<etcd::Response> etcd::Client::modify_if(std::string const & key, std::string const & value, int old_index)
{
return send_asyncmodify_if(key, value, old_index);
}
pplx::task<etcd::Response> etcd::Client::rm(std::string const & key)
{
return send_asyncdelete(key,false);
}
pplx::task<etcd::Response> etcd::Client::rm_if(std::string const & key, std::string const & old_value)
{
return send_asyncrm_if(key, old_value);
}
pplx::task<etcd::Response> etcd::Client::rm_if(std::string const & key, int old_index)
{
return send_asyncrm_if(key, old_index);
}
pplx::task<etcd::Response> etcd::Client::rmdir(std::string const & key, bool recursive)
{
return send_asyncdelete(key,recursive);
return send_asyncdelete(key,recursive);
}
pplx::task<etcd::Response> etcd::Client::ls(std::string const & key)
{
std::string range_end(key);
int ascii = (int)range_end[range_end.length()-1];
range_end.back() = ascii+1;
return send_asyncget(key,range_end);
}
pplx::task<etcd::Response> etcd::Client::watch(std::string const & key, bool recursive)
{
return send_asyncwatch(key,recursive);
}
pplx::task<etcd::Response> etcd::Client::watch(std::string const & key, int fromIndex, bool recursive)
{
return send_asyncwatch(key, fromIndex, recursive);
}
std::shared_ptr<etcdv3::AsyncTxnResponse> etcd::Client::initiate_transaction(const std::string &operation,
etcdv3::Transaction& transaction)
{
std::shared_ptr<etcdv3::AsyncTxnResponse> call(new etcdv3::AsyncTxnResponse(operation));
call->response_reader = stub_->AsyncTxn(&call->context, transaction.txn_request, &call->cq_);
call->response_reader->Finish(&call->reply, &call->status, (void*) (call.get()));
return call;
}
pplx::task<etcd::Response> etcd::Client::send_asyncadd(std::string const & key, std::string const & value)
{
etcdv3::Transaction transaction(key);
transaction.init_compare(Compare::CompareResult::Compare_CompareResult_EQUAL,
Compare::CompareTarget::Compare_CompareTarget_VERSION);
transaction.setup_basic_failure_operation(key);
transaction.setup_basic_create_sequence(key, value);
std::shared_ptr<etcdv3::AsyncTxnResponse> call = initiate_transaction("create", transaction);
return Response::create(call);
}
pplx::task<etcd::Response> etcd::Client::send_asyncmodify_if(std::string const & key, std::string const & value, std::string const & old_value)
{
etcdv3::Transaction transaction(key);
transaction.init_compare(old_value, Compare::CompareResult::Compare_CompareResult_EQUAL,
Compare::CompareTarget::Compare_CompareTarget_VALUE);
transaction.setup_basic_failure_operation(key);
transaction.setup_compare_and_swap_sequence(value);
std::shared_ptr<etcdv3::AsyncTxnResponse> call = initiate_transaction("compareAndSwap", transaction);
return Response::create(call);
}
put_request->set_value(value);
RequestOp* req_success = txn_request.add_success();
req_success->set_allocated_request_put(put_request.release());
get_request.reset(new RangeRequest());
get_request->set_key(key);
req_success = txn_request.add_success();
req_success->set_allocated_request_range(get_request.release());
std::shared_ptr<etcdv3::AsyncTxnResponse> call(new etcdv3::AsyncTxnResponse("create"));
call->response_reader = stub_->AsyncTxn(&call->context,txn_request,&call->cq_);
<<<<<<< d262688a8e4d8413a46f5fac4225c549c3039c77
=======
call->response_reader->Finish(&call->reply, &call->status, (void*)call.get());
>>>>>>> make templated create with shared_ptr arguement
pplx::task<etcd::Response> etcd::Client::send_asyncmodify_if(std::string const & key, std::string const & value, int old_index)
{
etcdv3::Transaction transaction(key);
transaction.init_compare(old_index, Compare::CompareResult::Compare_CompareResult_EQUAL,
Compare::CompareTarget::Compare_CompareTarget_MOD);
transaction.setup_basic_failure_operation(key);
transaction.setup_compare_and_swap_sequence(value);
std::shared_ptr<etcdv3::AsyncTxnResponse> call = initiate_transaction("compareAndSwap", transaction);
return Response::create(call);
}
pplx::task<etcd::Response> etcd::Client::send_asyncmodify(std::string const & key, std::string const & value)
{
etcdv3::Transaction transaction(key);
transaction.init_compare(Compare::CompareResult::Compare_CompareResult_GREATER,
Compare::CompareTarget::Compare_CompareTarget_VERSION);
transaction.setup_basic_failure_operation(key);
transaction.setup_compare_and_swap_sequence(value);
std::shared_ptr<etcdv3::AsyncTxnResponse> call = initiate_transaction("update", transaction);
return Response::create(call);
}
pplx::task<etcd::Response> etcd::Client::send_asyncget(std::string const & key, std::string const& range_end)
{
RangeRequest get_request;
get_request.set_key(key);
if(!range_end.empty())
{
get_request.set_range_end(range_end);
get_request.set_sort_target(RangeRequest::SortTarget::RangeRequest_SortTarget_KEY);
get_request.set_sort_order(RangeRequest::SortOrder::RangeRequest_SortOrder_ASCEND);
std::shared_ptr<etcdv3::AsyncRangeResponse> call(new etcdv3::AsyncRangeResponse());
call->response_reader = stub_->AsyncRange(&call->context,get_request,&call->cq_);
call->response_reader->Finish(&call->reply, &call->status, (void*)call.get());
compare->set_target(Compare::CompareTarget::Compare_CompareTarget_VALUE);
compare->set_key(key);
compare->set_value(old_value);
return Response::create(call);
}
get_request->set_key(key);
RequestOp* req_failure = txn_request.add_failure();
req_failure->set_allocated_request_range(get_request.release());
req_success->set_allocated_request_range(get_request.release());
pplx::task<etcd::Response> etcd::Client::send_asyncput(std::string const & key, std::string const & value)
{
etcdv3::Transaction transaction(key);
transaction.init_compare(Compare::CompareResult::Compare_CompareResult_EQUAL,
Compare::CompareTarget::Compare_CompareTarget_VERSION);
get_request.reset(new RangeRequest());
get_request->set_key(key);
req_success = txn_request.add_success();
req_success->set_allocated_request_range(get_request.release());
std::shared_ptr<etcdv3::AsyncTxnResponse> call(new etcdv3::AsyncTxnResponse("compareAndSwap"));
call->response_reader = stub_->AsyncTxn(&call->context,txn_request,&call->cq_);
<<<<<<< d262688a8e4d8413a46f5fac4225c549c3039c77
transaction.setup_set_failure_operation(key, value);
transaction.setup_basic_create_sequence(key, value);
=======
call->response_reader->Finish(&call->reply, &call->status, (void*)call.get());
>>>>>>> make templated create with shared_ptr arguement
std::shared_ptr<etcdv3::AsyncTxnResponse> call = initiate_transaction("set", transaction);
return Response::create(call);
}
pplx::task<etcd::Response> etcd::Client::send_asyncdelete(std::string const & key, bool recursive)
{
etcdv3::Transaction transaction(key);
transaction.init_compare(Compare::CompareResult::Compare_CompareResult_GREATER,
Compare::CompareTarget::Compare_CompareTarget_VERSION);
std::string range_end(key);
if(recursive)
compare->set_result(Compare::CompareResult::Compare_CompareResult_GREATER);
int ascii = (int)range_end[range_end.length()-1];
range_end.back() = ascii+1;
transaction.setup_delete_sequence(key, range_end, recursive);
transaction.setup_delete_failure_operation(key, range_end, recursive);
get_request->set_key(key);
RequestOp* req_failure = txn_request.add_failure();
req_failure->set_allocated_request_range(get_request.release());
std::shared_ptr<etcdv3::AsyncTxnResponse> call = initiate_transaction("delete", transaction);
return Response::create(call);
}
req_success->set_allocated_request_range(get_request.release());
pplx::task<etcd::Response> etcd::Client::send_asyncrm_if(std::string const &key, std::string const &old_value)
{
etcdv3::Transaction transaction(key);
transaction.init_compare(old_value, Compare::CompareResult::Compare_CompareResult_EQUAL,
Compare::CompareTarget::Compare_CompareTarget_VALUE);
req_success = txn_request.add_success();
req_success->set_allocated_request_put(put_request.release());
get_request.reset(new RangeRequest());
get_request->set_key(key);
req_success = txn_request.add_success();
req_success->set_allocated_request_range(get_request.release());
std::shared_ptr<etcdv3::AsyncTxnResponse> call(new etcdv3::AsyncTxnResponse("update"));
call->response_reader = stub_->AsyncTxn(&call->context,txn_request,&call->cq_);
<<<<<<< d262688a8e4d8413a46f5fac4225c549c3039c77
transaction.setup_compare_and_delete_operation(key);
transaction.setup_basic_failure_operation(key);
=======
call->response_reader->Finish(&call->reply, &call->status, (void*)call.get());
return Response::create(call);
>>>>>>> make templated create with shared_ptr arguement
std::shared_ptr<etcdv3::AsyncTxnResponse> call = initiate_transaction("compareAndDelete", transaction);
return Response::create(call);
}
pplx::task<etcd::Response> etcd::Client::send_asyncrm_if(std::string const &key, int old_index) {
etcdv3::Transaction transaction(key);
transaction.init_compare(old_index, Compare::CompareResult::Compare_CompareResult_EQUAL,
Compare::CompareTarget::Compare_CompareTarget_MOD);
if(!range_end.empty())
{
get_request.set_range_end(range_end);
get_request.set_sort_target(RangeRequest::SortTarget::RangeRequest_SortTarget_KEY);
get_request.set_sort_order(RangeRequest::SortOrder::RangeRequest_SortOrder_ASCEND);
}
std::shared_ptr<etcdv3::AsyncRangeResponse> call(new etcdv3::AsyncRangeResponse());
call->response_reader = stub_->AsyncRange(&call->context,get_request,&call->cq_);
<<<<<<< d262688a8e4d8413a46f5fac4225c549c3039c77
transaction.setup_compare_and_delete_operation(key);
transaction.setup_basic_failure_operation(key);
=======
call->response_reader->Finish(&call->reply, &call->status, (void*)call.get());
>>>>>>> make templated create with shared_ptr arguement
std::shared_ptr<etcdv3::AsyncTxnResponse> call = initiate_transaction("compareAndDelete", transaction);
return Response::create(call);
}
pplx::task<etcd::Response> etcd::Client::send_asyncwatch(std::string const & key, bool recursive)
{
<<<<<<< d262688a8e4d8413a46f5fac4225c549c3039c77
std::shared_ptr<etcdv3::AsyncWatchResponse> call(new etcdv3::AsyncWatchResponse());
call->stream = watchServiceStub->AsyncWatch(&call->context,&call->cq_,(void*)call.get());
=======
#if 0
//try watch here:
ClientContext context;
std::shared_ptr<ClientReaderWriter<WatchRequest,WatchResponse>> stream(stub1_->Watch(&context));
WatchRequest watch_req;
WatchCreateRequest watch_create_req;
watch_create_req.set_key(key);
watch_req.mutable_create_request()->CopyFrom(watch_create_req);
stream->Write(watch_req);
std::cout<< "write finished" << std::endl;
WatchResponse server_resp;
while(stream->Read(&server_resp))
{
std::cout<< "read...watch id: "<< server_resp.watch_id()<< std::endl;
if(server_resp.events_size())
{
std::cout << "event type: " << server_resp.events(0).type() << std::endl;
std::cout << "key: " << server_resp.events(0).kv().key() << std::endl;
std::cout << "value: " << server_resp.events(0).kv().value() << std::endl;
stream->WritesDone();
}
}
Status status = stream->Finish();
if(!status.ok())
{
std::cout << "rpc failed" << std::endl;
}
#endif
>>>>>>> make templated create with shared_ptr arguement
WatchRequest watch_req;
WatchCreateRequest watch_create_req;
watch_create_req.set_key(key);
compare->set_result(Compare::CompareResult::Compare_CompareResult_EQUAL);
compare->set_target(Compare::CompareTarget::Compare_CompareTarget_VERSION);
compare->set_key(key);
compare->set_version(0);
std::string range_end(key);
if(recursive)
RequestOp* req_failure = txn_request.add_failure();
int ascii = (int)range_end[range_end.length()-1];
range_end.back() = ascii+1;
watch_create_req.set_range_end(range_end);
put_request->set_value(value);
req_failure = txn_request.add_failure();
req_failure->set_allocated_request_put(put_request.release());
watch_req.mutable_create_request()->CopyFrom(watch_create_req);
call->stream->Write(watch_req, (void*)call.get());
call->stub_ = stub_.get();
req_failure->set_allocated_request_range(get_request.release());
return Response::create(call);
}
put_request.reset(new PutRequest());
put_request->set_key(key);
put_request->set_value(value);
RequestOp* req_success = txn_request.add_success();
req_success->set_allocated_request_put(put_request.release());
get_request.reset(new RangeRequest());
get_request->set_key(key);
req_success = txn_request.add_success();
req_success->set_allocated_request_range(get_request.release());
std::shared_ptr<etcdv3::AsyncTxnResponse> call(new etcdv3::AsyncTxnResponse("set"));
call->response_reader = stub_->AsyncTxn(&call->context,txn_request,&call->cq_);
call->response_reader->Finish(&call->reply, &call->status, (void*)call.get());
return Response::create(call);
}
pplx::task<etcd::Response> etcd::Client::send_asyncdelete(std::string const & key, bool recursive)
{
//check if key is present
TxnRequest txn_request;
Compare* compare = txn_request.add_compare();
compare->set_result(Compare::CompareResult::Compare_CompareResult_GREATER);
compare->set_target(Compare::CompareTarget::Compare_CompareTarget_VERSION);
compare->set_key(key);
compare->set_version(0);
std::string range_end(key);
if(recursive)
{
int ascii = (int)range_end[range_end.length()-1];
range_end.back() = ascii+1;
}
//if success, get key, delete
std::unique_ptr<RangeRequest> get_request(new RangeRequest());
get_request->set_key(key);
if(recursive)
{
get_request->set_range_end(range_end);
get_request->set_sort_target(RangeRequest::SortTarget::RangeRequest_SortTarget_KEY);
get_request->set_sort_order(RangeRequest::SortOrder::RangeRequest_SortOrder_ASCEND);
}
RequestOp* req_success = txn_request.add_success();
req_success->set_allocated_request_range(get_request.release());
std::unique_ptr<DeleteRangeRequest> del_request(new DeleteRangeRequest());
del_request->set_key(key);
if(recursive)
{
del_request->set_range_end(range_end);
}
req_success = txn_request.add_success();
req_success->set_allocated_request_delete_range(del_request.release());
//if success, get key, delete
get_request.reset(new RangeRequest());
get_request->set_key(key);
if(recursive)
{
get_request->set_range_end(range_end);
get_request->set_sort_target(RangeRequest::SortTarget::RangeRequest_SortTarget_KEY);
get_request->set_sort_order(RangeRequest::SortOrder::RangeRequest_SortOrder_ASCEND);
}
RequestOp* req_failure = txn_request.add_failure();
req_failure->set_allocated_request_range(get_request.release());
del_request.reset(new DeleteRangeRequest());
del_request->set_key(key);
if(recursive)
{
del_request->set_range_end(range_end);
}
req_failure = txn_request.add_failure();
req_failure->set_allocated_request_delete_range(del_request.release());
std::shared_ptr<etcdv3::AsyncTxnResponse> call(new etcdv3::AsyncTxnResponse("delete"));
call->response_reader = stub_->AsyncTxn(&call->context,txn_request,&call->cq_);
<<<<<<< d262688a8e4d8413a46f5fac4225c549c3039c77
pplx::task<etcd::Response> etcd::Client::send_asyncwatch(std::string const & key, int fromIndex, bool recursive)
{
std::shared_ptr<etcdv3::AsyncWatchResponse> call(new etcdv3::AsyncWatchResponse());
call->stream = watchServiceStub->AsyncWatch(&call->context,&call->cq_,(void*)call.get());
WatchRequest watch_req;
WatchCreateRequest watch_create_req;
watch_create_req.set_key(key);
watch_create_req.set_start_revision(fromIndex);
std::string range_end(key);
if(recursive)
{
int ascii = (int)range_end[range_end.length()-1];
range_end.back() = ascii+1;
watch_create_req.set_range_end(range_end);
}
=======
call->response_reader->Finish(&call->reply, &call->status, (void*)call.get());
return Response::create(call);
}
>>>>>>> make templated create with shared_ptr arguement
watch_req.mutable_create_request()->CopyFrom(watch_create_req);
call->stream->Write(watch_req, (void*)call.get());
call->stub_ = stub_.get();
call->fromIndex = fromIndex;
return Response::create(call);
}

417
src/Client_BACKUP_12044.cpp Normal file
View File

@ -0,0 +1,417 @@
#include "etcd/Client.hpp"
#include "v3/include/AsyncRangeResponse.hpp"
#include "v3/include/AsyncPutResponse.hpp"
<<<<<<< a1293c770afcde1996cd1d899b74fc622628c06c
#include "v3/include/AsyncDelResponse.hpp"
#include "v3/include/AsyncModifyResponse.hpp"
#include "v3/include/Utils.hpp"
#include <iostream>
=======
#include "v3/include/AsyncTxnResponse.hpp"
#include "v3/include/Utils.hpp"
#include <memory>
using etcdserverpb::TxnRequest;
using etcdserverpb::Compare;
using etcdserverpb::RequestOp;
>>>>>>> Use Txn for add()
etcd::Client::Client(std::string const & address)
: client(address), grpcClient(address)
{
}
pplx::task<etcd::Response> etcd::Client::send_get_request(web::http::uri_builder & uri)
{
return Response::create(client.request(web::http::methods::GET, uri.to_string()));
}
pplx::task<etcd::Response> etcd::Client::send_del_request(web::http::uri_builder & uri)
{
return Response::create(client.request(web::http::methods::DEL, uri.to_string()));
}
pplx::task<etcd::Response> etcd::Client::send_put_request(web::http::uri_builder & uri, std::string const & key, std::string const & value)
{
std::string data = key + "=" + value;
std::string content_type = "application/x-www-form-urlencoded; param=" + key;
return Response::create(client.request(web::http::methods::PUT, uri.to_string(), data.c_str(), content_type.c_str()));
}
pplx::task<etcd::Response> etcd::Client::get(std::string const & key)
{
return send_asyncget(key);
}
pplx::task<etcd::Response> etcd::Client::set(std::string const & key, std::string const & value)
{
return send_asyncput(key,value);
}
pplx::task<etcd::Response> etcd::Client::add(std::string const & key, std::string const & value)
{
return send_asyncadd(key,value);
}
pplx::task<etcd::Response> etcd::Client::modify(std::string const & key, std::string const & value)
{
return send_asyncmodify(key,value);
}
pplx::task<etcd::Response> etcd::Client::modify_if(std::string const & key, std::string const & value, std::string const & old_value)
{
return send_asyncmodify_if(key, value, old_value);
}
pplx::task<etcd::Response> etcd::Client::modifyEntryWithValueAndOldIndex(std::string const & key, std::string const & value, int old_index) {
etcdv3::AsyncRangeResponse* resp = etcdv3::Utils::getKey(key, grpcClient);
if(!resp->reply.kvs_size())
{
resp->error_code=100;
resp->error_message="Key not found";
return Response::createResponse(*resp);
}
else if(resp->reply.kvs(0).mod_revision() != old_index)
{
resp->error_code = 101;
resp->error_message = "Compare failed";
return Response::createResponse(*resp);
}
PutRequest put_request;
put_request.set_key(key);
put_request.set_value(value);
etcdv3::AsyncModifyResponse* call= new etcdv3::AsyncModifyResponse("compareAndSwap");
//below 2 lines can be removed once we are able to use Txn
call->prev_value = resp->reply.kvs(0);
call->client = &grpcClient;
call->key = key;
call->rpcInstance = grpcClient.stub_->AsyncPut(&call->context,put_request,&call->cq_);
call->rpcInstance->Finish(&call->putResponse, &call->status, (void*)call);
return Response::create(call);
}
pplx::task<etcd::Response> etcd::Client::modify_if(std::string const & key, std::string const & value, int old_index)
{
return modifyEntryWithValueAndOldIndex(key, value, old_index);
}
//note: this one seems to not need the parseResponse() method
pplx::task<etcd::Response> etcd::Client::removeEntryWithKey(std::string const & entryKey) {
etcdv3::AsyncRangeResponse* resp = etcdv3::Utils::getKey(entryKey, grpcClient);
if(!resp->reply.kvs_size())
{
std::cout << "nothing to delete" << std::endl;
resp->error_code = 100;
resp->error_message = "Nothing to delete";
return Response::createResponse(*resp);
}
etcdserverpb::DeleteRangeRequest deleteRangeRequest;
deleteRangeRequest.set_key(entryKey);
etcdv3::AsyncDelResponse* call = new etcdv3::AsyncDelResponse("delete");
//mano-mano
call->prev_value = resp->reply.kvs(0);
call->client = &grpcClient;
call->key = entryKey;
call->rpcInstance = grpcClient.stub_->AsyncDeleteRange(&call->context, deleteRangeRequest, &call->cq_);
call->rpcInstance->Finish(&call->deleteResponse, &call->status, (void*)call);
return Response::createResponse(*call);
}
pplx::task<etcd::Response> etcd::Client::rm(std::string const & key)
{
return removeEntryWithKey(key);
}
pplx::task<etcd::Response> etcd::Client::removeEntryWithKeyAndValue(std::string const &entryKey, std::string const &oldValue) {
etcdv3::AsyncRangeResponse *searchResult = etcdv3::Utils::getKey(entryKey, grpcClient);
if(!searchResult->reply.kvs_size()) {
searchResult->error_code = 100;
searchResult->error_message = "Key not Found";
return Response::createResponse(*searchResult);
}
else if(searchResult->reply.kvs(0).value() != oldValue) {
searchResult->error_code = 101;
searchResult->error_message = "Compare failed";
return Response::createResponse(*searchResult);
}
etcdserverpb::DeleteRangeRequest deleteRangeRequest;
deleteRangeRequest.set_key(entryKey);
etcdv3::AsyncDelResponse *deleteResponseCall = new etcdv3::AsyncDelResponse("compareAndDelete");
deleteResponseCall->prev_value = searchResult->reply.kvs(0);
deleteResponseCall->client = &grpcClient;
deleteResponseCall->key = entryKey;
deleteResponseCall->rpcInstance = grpcClient.stub_->AsyncDeleteRange(&deleteResponseCall->context, deleteRangeRequest, &deleteResponseCall->cq_);
deleteResponseCall->rpcInstance->Finish(&deleteResponseCall->deleteResponse, &deleteResponseCall->status, (void*)deleteResponseCall);
return Response::createResponse(*deleteResponseCall);
}
pplx::task<etcd::Response> etcd::Client::rm_if(std::string const & key, std::string const & old_value)
{
return removeEntryWithKeyAndValue(key, old_value);
}
pplx::task<etcd::Response> etcd::Client::removeEntryWithKeyAndIndex(std::string const &entryKey, int oldIndex) {
etcdv3::AsyncRangeResponse *searchResult = etcdv3::Utils::getKey(entryKey, grpcClient);
if(!searchResult->reply.kvs_size()) {
searchResult->error_code = 100;
searchResult->error_message = "Key not Found";
return Response::createResponse(*searchResult);
}
else if(searchResult->reply.kvs(0).create_revision() != oldIndex) {
searchResult->error_code = 101;
searchResult->error_message = "Compare failed";
return Response::createResponse(*searchResult);
}
etcdserverpb::DeleteRangeRequest deleteRangeRequest;
deleteRangeRequest.set_key(entryKey);
etcdv3::AsyncDelResponse *deleteResponseCall = new etcdv3::AsyncDelResponse("compareAndDelete");
deleteResponseCall->prev_value = searchResult->reply.kvs(0);
deleteResponseCall->client = &grpcClient;
deleteResponseCall->key = entryKey;
deleteResponseCall->rpcInstance = grpcClient.stub_->AsyncDeleteRange(&deleteResponseCall->context, deleteRangeRequest, &deleteResponseCall->cq_);
deleteResponseCall->rpcInstance->Finish(&deleteResponseCall->deleteResponse, &deleteResponseCall->status, (void*)deleteResponseCall);
return Response::createResponse(*deleteResponseCall);
}
pplx::task<etcd::Response> etcd::Client::rm_if(std::string const & key, int old_index)
{
<<<<<<< a1293c770afcde1996cd1d899b74fc622628c06c
return removeEntryWithKeyAndIndex(key, old_index);
=======
web::http::uri_builder uri("/v2/keys" + key);
uri.append_query("dir=false");
uri.append_query("prevIndex", old_index);
return send_del_request(uri);
>>>>>>> Use Txn for add()
}
pplx::task<etcd::Response> etcd::Client::mkdir(std::string const & key)
{
web::http::uri_builder uri("/v2/keys" + key);
return send_put_request(uri, "dir", "true");
}
pplx::task<etcd::Response> etcd::Client::rmdir(std::string const & key, bool recursive)
{
web::http::uri_builder uri("/v2/keys" + key);
uri.append_query("dir=true");
if (recursive)
uri.append_query("recursive=true");
return send_del_request(uri);
}
pplx::task<etcd::Response> etcd::Client::ls(std::string const & key)
{
web::http::uri_builder uri("/v2/keys" + key);
uri.append_query("sorted=true");
return send_get_request(uri);
}
pplx::task<etcd::Response> etcd::Client::watch(std::string const & key, bool recursive)
{
web::http::uri_builder uri("/v2/keys" + key);
uri.append_query("wait=true");
if (recursive)
uri.append_query("recursive=true");
return send_get_request(uri);
}
pplx::task<etcd::Response> etcd::Client::watch(std::string const & key, int fromIndex, bool recursive)
{
web::http::uri_builder uri("/v2/keys" + key);
uri.append_query("wait=true");
uri.append_query("waitIndex", fromIndex);
if (recursive)
uri.append_query("recursive=true");
return send_get_request(uri);
}
pplx::task<etcd::Response> etcd::Client::send_asyncadd(std::string const & key, std::string const & value)
{
//check if key is not present
TxnRequest txn_request;
Compare* compare = txn_request.add_compare();
compare->set_result(Compare::CompareResult::Compare_CompareResult_EQUAL);
compare->set_target(Compare::CompareTarget::Compare_CompareTarget_VERSION);
compare->set_key(key);
compare->set_version(0);
//get key whether success or failure
RangeRequest get_request1 = new RangeRequest();
get_request1->set_key(key);
RequestOp* req_failure = txn_request.add_failure();
req_failure->set_allocated_request_range(get_request1);
//if success, add key and then get new value of key
PutRequest* put_request = new PutRequest();
put_request->set_key(key);
put_request->set_value(value);
RequestOp* req_success2 = txn_request.add_success();
req_success2->set_allocated_request_put(put_request);
RangeRequest* get_request2 = new RangeRequest();
get_request2->set_key(key);
RequestOp* req_success3 = txn_request.add_success();
req_success3->set_allocated_request_range(get_request2);
etcdv3::AsyncTxnResponse* call= new etcdv3::AsyncTxnResponse("create");
call->response_reader = grpcClient.stub_->AsyncTxn(&call->context,txn_request,&call->cq_);
call->response_reader->Finish(&call->reply, &call->status, (void*)call);
return Response::create(call);
}
pplx::task<etcd::Response> etcd::Client::send_asyncmodify_if(std::string const & key, std::string const & value, std::string const & old_value)
{
//check current key is equal to old_value
etcdv3::AsyncRangeResponse* resp = etcdv3::Utils::getKey(key, grpcClient);
if(!resp->reply.kvs_size())
{
resp->error_code=100;
resp->error_message="Key not found";
return Response::createResponse(*resp);
}
else
{
if(resp->reply.kvs(0).value() != old_value)
{
resp->error_code=101;
resp->error_message="Compare failed";
return Response::createResponse(*resp);
}
}
PutRequest put_request;
put_request.set_key(key);
put_request.set_value(value);
etcdv3::AsyncModifyResponse* call= new etcdv3::AsyncModifyResponse("compareAndSwap");
//below 2 lines can be removed once we are able to use Txn
call->prev_value = resp->reply.kvs(0);
call->client = &grpcClient;
call->key = key;
call->rpcInstance = grpcClient.stub_->AsyncPut(&call->context,put_request,&call->cq_);
call->rpcInstance->Finish(&call->putResponse, &call->status, (void*)call);
return Response::create(call);
}
pplx::task<etcd::Response> etcd::Client::send_asyncmodify(std::string const & key, std::string const & value)
{
//check if key already exist
etcdv3::AsyncRangeResponse* resp = etcdv3::Utils::getKey(key, grpcClient);
if(!resp->reply.kvs_size())
{
resp->error_code=100;
resp->error_message="Key not found";
return Response::createResponse(*resp);
}
PutRequest put_request;
put_request.set_key(key);
put_request.set_value(value);
etcdv3::AsyncModifyResponse* call= new etcdv3::AsyncModifyResponse("update");
//below 2 lines can be removed once we are able to use Txn
call->prev_value = resp->reply.kvs(0);
call->client = &grpcClient;
call->key = key;
call->rpcInstance = grpcClient.stub_->AsyncPut(&call->context,put_request,&call->cq_);
call->rpcInstance->Finish(&call->putResponse, &call->status, (void*)call);
return Response::create(call);
}
pplx::task<etcd::Response> etcd::Client::send_asyncget(std::string const & key)
{
RangeRequest request;
request.set_key(key);
etcdv3::AsyncRangeResponse* call= new etcdv3::AsyncRangeResponse();
call->response_reader = grpcClient.stub_->AsyncRange(&call->context,request,&call->cq_);
call->response_reader->Finish(&call->reply, &call->status, (void*)call);
return Response::create(call);
}
pplx::task<etcd::Response> etcd::Client::send_asyncput(std::string const & key, std::string const & value)
{
PutRequest put_request;
put_request.set_key(key);
put_request.set_value(value);
etcdv3::AsyncPutResponse* call= new etcdv3::AsyncPutResponse("set");
//get current value
etcdv3::AsyncRangeResponse* resp = etcdv3::Utils::getKey(key, grpcClient);
if(resp->reply.kvs_size())
{
call->prev_value = resp->reply.kvs(0);
}
call->client = &grpcClient;
call->key = key;
call->response_reader = grpcClient.stub_->AsyncPut(&call->context,put_request,&call->cq_);
call->response_reader->Finish(&call->reply, &call->status, (void*)call);
return Response::create(call);
}

417
src/Client_BACKUP_9708.cpp Normal file
View File

@ -0,0 +1,417 @@
#include "etcd/Client.hpp"
#include "v3/include/AsyncRangeResponse.hpp"
#include "v3/include/AsyncPutResponse.hpp"
<<<<<<< a1293c770afcde1996cd1d899b74fc622628c06c
#include "v3/include/AsyncDelResponse.hpp"
#include "v3/include/AsyncModifyResponse.hpp"
#include "v3/include/Utils.hpp"
#include <iostream>
=======
#include "v3/include/AsyncTxnResponse.hpp"
#include "v3/include/Utils.hpp"
#include <memory>
using etcdserverpb::TxnRequest;
using etcdserverpb::Compare;
using etcdserverpb::RequestOp;
>>>>>>> Use Txn for add()
etcd::Client::Client(std::string const & address)
: client(address), grpcClient(address)
{
}
pplx::task<etcd::Response> etcd::Client::send_get_request(web::http::uri_builder & uri)
{
return Response::create(client.request(web::http::methods::GET, uri.to_string()));
}
pplx::task<etcd::Response> etcd::Client::send_del_request(web::http::uri_builder & uri)
{
return Response::create(client.request(web::http::methods::DEL, uri.to_string()));
}
pplx::task<etcd::Response> etcd::Client::send_put_request(web::http::uri_builder & uri, std::string const & key, std::string const & value)
{
std::string data = key + "=" + value;
std::string content_type = "application/x-www-form-urlencoded; param=" + key;
return Response::create(client.request(web::http::methods::PUT, uri.to_string(), data.c_str(), content_type.c_str()));
}
pplx::task<etcd::Response> etcd::Client::get(std::string const & key)
{
return send_asyncget(key);
}
pplx::task<etcd::Response> etcd::Client::set(std::string const & key, std::string const & value)
{
return send_asyncput(key,value);
}
pplx::task<etcd::Response> etcd::Client::add(std::string const & key, std::string const & value)
{
return send_asyncadd(key,value);
}
pplx::task<etcd::Response> etcd::Client::modify(std::string const & key, std::string const & value)
{
return send_asyncmodify(key,value);
}
pplx::task<etcd::Response> etcd::Client::modify_if(std::string const & key, std::string const & value, std::string const & old_value)
{
return send_asyncmodify_if(key, value, old_value);
}
pplx::task<etcd::Response> etcd::Client::modifyEntryWithValueAndOldIndex(std::string const & key, std::string const & value, int old_index) {
etcdv3::AsyncRangeResponse* resp = etcdv3::Utils::getKey(key, grpcClient);
if(!resp->reply.kvs_size())
{
resp->error_code=100;
resp->error_message="Key not found";
return Response::createResponse(*resp);
}
else if(resp->reply.kvs(0).mod_revision() != old_index)
{
resp->error_code = 101;
resp->error_message = "Compare failed";
return Response::createResponse(*resp);
}
PutRequest put_request;
put_request.set_key(key);
put_request.set_value(value);
etcdv3::AsyncModifyResponse* call= new etcdv3::AsyncModifyResponse("compareAndSwap");
//below 2 lines can be removed once we are able to use Txn
call->prev_value = resp->reply.kvs(0);
call->client = &grpcClient;
call->key = key;
call->rpcInstance = grpcClient.stub_->AsyncPut(&call->context,put_request,&call->cq_);
call->rpcInstance->Finish(&call->putResponse, &call->status, (void*)call);
return Response::create(call);
}
pplx::task<etcd::Response> etcd::Client::modify_if(std::string const & key, std::string const & value, int old_index)
{
return modifyEntryWithValueAndOldIndex(key, value, old_index);
}
//note: this one seems to not need the parseResponse() method
pplx::task<etcd::Response> etcd::Client::removeEntryWithKey(std::string const & entryKey) {
etcdv3::AsyncRangeResponse* resp = etcdv3::Utils::getKey(entryKey, grpcClient);
if(!resp->reply.kvs_size())
{
std::cout << "nothing to delete" << std::endl;
resp->error_code = 100;
resp->error_message = "Nothing to delete";
return Response::createResponse(*resp);
}
etcdserverpb::DeleteRangeRequest deleteRangeRequest;
deleteRangeRequest.set_key(entryKey);
etcdv3::AsyncDelResponse* call = new etcdv3::AsyncDelResponse("delete");
//mano-mano
call->prev_value = resp->reply.kvs(0);
call->client = &grpcClient;
call->key = entryKey;
call->rpcInstance = grpcClient.stub_->AsyncDeleteRange(&call->context, deleteRangeRequest, &call->cq_);
call->rpcInstance->Finish(&call->deleteResponse, &call->status, (void*)call);
return Response::createResponse(*call);
}
pplx::task<etcd::Response> etcd::Client::rm(std::string const & key)
{
return removeEntryWithKey(key);
}
pplx::task<etcd::Response> etcd::Client::removeEntryWithKeyAndValue(std::string const &entryKey, std::string const &oldValue) {
etcdv3::AsyncRangeResponse *searchResult = etcdv3::Utils::getKey(entryKey, grpcClient);
if(!searchResult->reply.kvs_size()) {
searchResult->error_code = 100;
searchResult->error_message = "Key not Found";
return Response::createResponse(*searchResult);
}
else if(searchResult->reply.kvs(0).value() != oldValue) {
searchResult->error_code = 101;
searchResult->error_message = "Compare failed";
return Response::createResponse(*searchResult);
}
etcdserverpb::DeleteRangeRequest deleteRangeRequest;
deleteRangeRequest.set_key(entryKey);
etcdv3::AsyncDelResponse *deleteResponseCall = new etcdv3::AsyncDelResponse("compareAndDelete");
deleteResponseCall->prev_value = searchResult->reply.kvs(0);
deleteResponseCall->client = &grpcClient;
deleteResponseCall->key = entryKey;
deleteResponseCall->rpcInstance = grpcClient.stub_->AsyncDeleteRange(&deleteResponseCall->context, deleteRangeRequest, &deleteResponseCall->cq_);
deleteResponseCall->rpcInstance->Finish(&deleteResponseCall->deleteResponse, &deleteResponseCall->status, (void*)deleteResponseCall);
return Response::createResponse(*deleteResponseCall);
}
pplx::task<etcd::Response> etcd::Client::rm_if(std::string const & key, std::string const & old_value)
{
return removeEntryWithKeyAndValue(key, old_value);
}
pplx::task<etcd::Response> etcd::Client::removeEntryWithKeyAndIndex(std::string const &entryKey, int oldIndex) {
etcdv3::AsyncRangeResponse *searchResult = etcdv3::Utils::getKey(entryKey, grpcClient);
if(!searchResult->reply.kvs_size()) {
searchResult->error_code = 100;
searchResult->error_message = "Key not Found";
return Response::createResponse(*searchResult);
}
else if(searchResult->reply.kvs(0).create_revision() != oldIndex) {
searchResult->error_code = 101;
searchResult->error_message = "Compare failed";
return Response::createResponse(*searchResult);
}
etcdserverpb::DeleteRangeRequest deleteRangeRequest;
deleteRangeRequest.set_key(entryKey);
etcdv3::AsyncDelResponse *deleteResponseCall = new etcdv3::AsyncDelResponse("compareAndDelete");
deleteResponseCall->prev_value = searchResult->reply.kvs(0);
deleteResponseCall->client = &grpcClient;
deleteResponseCall->key = entryKey;
deleteResponseCall->rpcInstance = grpcClient.stub_->AsyncDeleteRange(&deleteResponseCall->context, deleteRangeRequest, &deleteResponseCall->cq_);
deleteResponseCall->rpcInstance->Finish(&deleteResponseCall->deleteResponse, &deleteResponseCall->status, (void*)deleteResponseCall);
return Response::createResponse(*deleteResponseCall);
}
pplx::task<etcd::Response> etcd::Client::rm_if(std::string const & key, int old_index)
{
<<<<<<< a1293c770afcde1996cd1d899b74fc622628c06c
return removeEntryWithKeyAndIndex(key, old_index);
=======
web::http::uri_builder uri("/v2/keys" + key);
uri.append_query("dir=false");
uri.append_query("prevIndex", old_index);
return send_del_request(uri);
>>>>>>> Use Txn for add()
}
pplx::task<etcd::Response> etcd::Client::mkdir(std::string const & key)
{
web::http::uri_builder uri("/v2/keys" + key);
return send_put_request(uri, "dir", "true");
}
pplx::task<etcd::Response> etcd::Client::rmdir(std::string const & key, bool recursive)
{
web::http::uri_builder uri("/v2/keys" + key);
uri.append_query("dir=true");
if (recursive)
uri.append_query("recursive=true");
return send_del_request(uri);
}
pplx::task<etcd::Response> etcd::Client::ls(std::string const & key)
{
web::http::uri_builder uri("/v2/keys" + key);
uri.append_query("sorted=true");
return send_get_request(uri);
}
pplx::task<etcd::Response> etcd::Client::watch(std::string const & key, bool recursive)
{
web::http::uri_builder uri("/v2/keys" + key);
uri.append_query("wait=true");
if (recursive)
uri.append_query("recursive=true");
return send_get_request(uri);
}
pplx::task<etcd::Response> etcd::Client::watch(std::string const & key, int fromIndex, bool recursive)
{
web::http::uri_builder uri("/v2/keys" + key);
uri.append_query("wait=true");
uri.append_query("waitIndex", fromIndex);
if (recursive)
uri.append_query("recursive=true");
return send_get_request(uri);
}
pplx::task<etcd::Response> etcd::Client::send_asyncadd(std::string const & key, std::string const & value)
{
//check if key is not present
TxnRequest txn_request;
Compare* compare = txn_request.add_compare();
compare->set_result(Compare::CompareResult::Compare_CompareResult_EQUAL);
compare->set_target(Compare::CompareTarget::Compare_CompareTarget_VERSION);
compare->set_key(key);
compare->set_version(0);
//get key whether success or failure
RangeRequest get_request1 = new RangeRequest();
get_request1->set_key(key);
RequestOp* req_failure = txn_request.add_failure();
req_failure->set_allocated_request_range(get_request1);
//if success, add key and then get new value of key
PutRequest* put_request = new PutRequest();
put_request->set_key(key);
put_request->set_value(value);
RequestOp* req_success2 = txn_request.add_success();
req_success2->set_allocated_request_put(put_request);
RangeRequest* get_request2 = new RangeRequest();
get_request2->set_key(key);
RequestOp* req_success3 = txn_request.add_success();
req_success3->set_allocated_request_range(get_request2);
etcdv3::AsyncTxnResponse* call= new etcdv3::AsyncTxnResponse("create");
call->response_reader = grpcClient.stub_->AsyncTxn(&call->context,txn_request,&call->cq_);
call->response_reader->Finish(&call->reply, &call->status, (void*)call);
return Response::create(call);
}
pplx::task<etcd::Response> etcd::Client::send_asyncmodify_if(std::string const & key, std::string const & value, std::string const & old_value)
{
//check current key is equal to old_value
etcdv3::AsyncRangeResponse* resp = etcdv3::Utils::getKey(key, grpcClient);
if(!resp->reply.kvs_size())
{
resp->error_code=100;
resp->error_message="Key not found";
return Response::createResponse(*resp);
}
else
{
if(resp->reply.kvs(0).value() != old_value)
{
resp->error_code=101;
resp->error_message="Compare failed";
return Response::createResponse(*resp);
}
}
PutRequest put_request;
put_request.set_key(key);
put_request.set_value(value);
etcdv3::AsyncModifyResponse* call= new etcdv3::AsyncModifyResponse("compareAndSwap");
//below 2 lines can be removed once we are able to use Txn
call->prev_value = resp->reply.kvs(0);
call->client = &grpcClient;
call->key = key;
call->rpcInstance = grpcClient.stub_->AsyncPut(&call->context,put_request,&call->cq_);
call->rpcInstance->Finish(&call->putResponse, &call->status, (void*)call);
return Response::create(call);
}
pplx::task<etcd::Response> etcd::Client::send_asyncmodify(std::string const & key, std::string const & value)
{
//check if key already exist
etcdv3::AsyncRangeResponse* resp = etcdv3::Utils::getKey(key, grpcClient);
if(!resp->reply.kvs_size())
{
resp->error_code=100;
resp->error_message="Key not found";
return Response::createResponse(*resp);
}
PutRequest put_request;
put_request.set_key(key);
put_request.set_value(value);
etcdv3::AsyncModifyResponse* call= new etcdv3::AsyncModifyResponse("update");
//below 2 lines can be removed once we are able to use Txn
call->prev_value = resp->reply.kvs(0);
call->client = &grpcClient;
call->key = key;
call->rpcInstance = grpcClient.stub_->AsyncPut(&call->context,put_request,&call->cq_);
call->rpcInstance->Finish(&call->putResponse, &call->status, (void*)call);
return Response::create(call);
}
pplx::task<etcd::Response> etcd::Client::send_asyncget(std::string const & key)
{
RangeRequest request;
request.set_key(key);
etcdv3::AsyncRangeResponse* call= new etcdv3::AsyncRangeResponse();
call->response_reader = grpcClient.stub_->AsyncRange(&call->context,request,&call->cq_);
call->response_reader->Finish(&call->reply, &call->status, (void*)call);
return Response::create(call);
}
pplx::task<etcd::Response> etcd::Client::send_asyncput(std::string const & key, std::string const & value)
{
PutRequest put_request;
put_request.set_key(key);
put_request.set_value(value);
etcdv3::AsyncPutResponse* call= new etcdv3::AsyncPutResponse("set");
//get current value
etcdv3::AsyncRangeResponse* resp = etcdv3::Utils::getKey(key, grpcClient);
if(resp->reply.kvs_size())
{
call->prev_value = resp->reply.kvs(0);
}
call->client = &grpcClient;
call->key = key;
call->response_reader = grpcClient.stub_->AsyncPut(&call->context,put_request,&call->cq_);
call->response_reader->Finish(&call->reply, &call->status, (void*)call);
return Response::create(call);
}

272
src/Client_BASE_12044.cpp Normal file
View File

@ -0,0 +1,272 @@
#include "etcd/Client.hpp"
#include "v3/include/AsyncRangeResponse.hpp"
#include "v3/include/AsyncPutResponse.hpp"
#include "v3/include/Utils.hpp"
etcd::Client::Client(std::string const & address)
: client(address), grpcClient(address)
{
}
pplx::task<etcd::Response> etcd::Client::send_get_request(web::http::uri_builder & uri)
{
return Response::create(client.request(web::http::methods::GET, uri.to_string()));
}
pplx::task<etcd::Response> etcd::Client::send_del_request(web::http::uri_builder & uri)
{
return Response::create(client.request(web::http::methods::DEL, uri.to_string()));
}
pplx::task<etcd::Response> etcd::Client::send_put_request(web::http::uri_builder & uri, std::string const & key, std::string const & value)
{
std::string data = key + "=" + value;
std::string content_type = "application/x-www-form-urlencoded; param=" + key;
return Response::create(client.request(web::http::methods::PUT, uri.to_string(), data.c_str(), content_type.c_str()));
}
pplx::task<etcd::Response> etcd::Client::get(std::string const & key)
{
return send_asyncget(key);
}
pplx::task<etcd::Response> etcd::Client::set(std::string const & key, std::string const & value)
{
return send_asyncput(key,value);
}
pplx::task<etcd::Response> etcd::Client::add(std::string const & key, std::string const & value)
{
return send_asyncadd(key,value);
}
pplx::task<etcd::Response> etcd::Client::modify(std::string const & key, std::string const & value)
{
return send_asyncmodify(key,value);
}
pplx::task<etcd::Response> etcd::Client::modify_if(std::string const & key, std::string const & value, std::string const & old_value)
{
return send_asyncmodify_if(key, value, old_value);
}
pplx::task<etcd::Response> etcd::Client::modify_if(std::string const & key, std::string const & value, int old_index)
{
web::http::uri_builder uri("/v2/keys" + key);
uri.append_query("prevIndex", old_index);
return send_put_request(uri, "value", value);
}
pplx::task<etcd::Response> etcd::Client::rm(std::string const & key)
{
web::http::uri_builder uri("/v2/keys" + key);
uri.append_query("dir=false");
return Response::create(client.request("DELETE", uri.to_string()));
}
pplx::task<etcd::Response> etcd::Client::rm_if(std::string const & key, std::string const & old_value)
{
web::http::uri_builder uri("/v2/keys" + key);
uri.append_query("dir=false");
uri.append_query("prevValue", old_value);
return send_del_request(uri);
}
pplx::task<etcd::Response> etcd::Client::rm_if(std::string const & key, int old_index)
{
web::http::uri_builder uri("/v2/keys" + key);
uri.append_query("dir=false");
uri.append_query("prevIndex", old_index);
return send_del_request(uri);
}
pplx::task<etcd::Response> etcd::Client::mkdir(std::string const & key)
{
web::http::uri_builder uri("/v2/keys" + key);
return send_put_request(uri, "dir", "true");
}
pplx::task<etcd::Response> etcd::Client::rmdir(std::string const & key, bool recursive)
{
web::http::uri_builder uri("/v2/keys" + key);
uri.append_query("dir=true");
if (recursive)
uri.append_query("recursive=true");
return send_del_request(uri);
}
pplx::task<etcd::Response> etcd::Client::ls(std::string const & key)
{
web::http::uri_builder uri("/v2/keys" + key);
uri.append_query("sorted=true");
return send_get_request(uri);
}
pplx::task<etcd::Response> etcd::Client::watch(std::string const & key, bool recursive)
{
web::http::uri_builder uri("/v2/keys" + key);
uri.append_query("wait=true");
if (recursive)
uri.append_query("recursive=true");
return send_get_request(uri);
}
pplx::task<etcd::Response> etcd::Client::watch(std::string const & key, int fromIndex, bool recursive)
{
web::http::uri_builder uri("/v2/keys" + key);
uri.append_query("wait=true");
uri.append_query("waitIndex", fromIndex);
if (recursive)
uri.append_query("recursive=true");
return send_get_request(uri);
}
pplx::task<etcd::Response> etcd::Client::send_asyncadd(std::string const & key, std::string const & value)
{
//check if key already exist
etcdv3::AsyncRangeResponse* resp = etcdv3::Utils::getKey(key, grpcClient);
if(resp->reply.kvs_size())
{
resp->error_code=105;
resp->error_message="Key already exists";
return Response::createResponse(*resp);
}
PutRequest put_request;
put_request.set_key(key);
put_request.set_value(value);
etcdv3::AsyncPutResponse* call= new etcdv3::AsyncPutResponse("create");
//below 2 lines can be removed once we are able to use Txn
call->client = &grpcClient;
call->key = key;
call->response_reader = grpcClient.stub_->AsyncPut(&call->context,put_request,&call->cq_);
call->response_reader->Finish(&call->reply, &call->status, (void*)call);
return Response::create(call);
}
pplx::task<etcd::Response> etcd::Client::send_asyncmodify_if(std::string const & key, std::string const & value, std::string const & old_value)
{
//check current key is equal to old_value
etcdv3::AsyncRangeResponse* resp = etcdv3::Utils::getKey(key, grpcClient);
if(!resp->reply.kvs_size())
{
resp->error_code=100;
resp->error_message="Key not found";
return Response::createResponse(*resp);
}
else
{
if(resp->reply.kvs(0).value() != old_value)
{
resp->error_code=101;
resp->error_message="Compare failed";
return Response::createResponse(*resp);
}
}
PutRequest put_request;
put_request.set_key(key);
put_request.set_value(value);
etcdv3::AsyncPutResponse* call= new etcdv3::AsyncPutResponse("compareAndSwap");
//below 2 lines can be removed once we are able to use Txn
call->prev_value = resp->reply.kvs(0);
call->client = &grpcClient;
call->key = key;
call->response_reader = grpcClient.stub_->AsyncPut(&call->context,put_request,&call->cq_);
call->response_reader->Finish(&call->reply, &call->status, (void*)call);
return Response::create(call);
}
pplx::task<etcd::Response> etcd::Client::send_asyncmodify(std::string const & key, std::string const & value)
{
//check if key already exist
etcdv3::AsyncRangeResponse* resp = etcdv3::Utils::getKey(key, grpcClient);
if(!resp->reply.kvs_size())
{
resp->error_code=100;
resp->error_message="Key not found";
return Response::createResponse(*resp);
}
PutRequest put_request;
put_request.set_key(key);
put_request.set_value(value);
etcdv3::AsyncPutResponse* call= new etcdv3::AsyncPutResponse("update");
//below 2 lines can be removed once we are able to use Txn
call->prev_value = resp->reply.kvs(0);
call->client = &grpcClient;
call->key = key;
call->response_reader = grpcClient.stub_->AsyncPut(&call->context,put_request,&call->cq_);
call->response_reader->Finish(&call->reply, &call->status, (void*)call);
return Response::create(call);
}
pplx::task<etcd::Response> etcd::Client::send_asyncget(std::string const & key)
{
RangeRequest request;
request.set_key(key);
etcdv3::AsyncRangeResponse* call= new etcdv3::AsyncRangeResponse();
call->response_reader = grpcClient.stub_->AsyncRange(&call->context,request,&call->cq_);
call->response_reader->Finish(&call->reply, &call->status, (void*)call);
return Response::create(call);
}
pplx::task<etcd::Response> etcd::Client::send_asyncput(std::string const & key, std::string const & value)
{
PutRequest put_request;
put_request.set_key(key);
put_request.set_value(value);
etcdv3::AsyncPutResponse* call= new etcdv3::AsyncPutResponse("set");
//get current value
etcdv3::AsyncRangeResponse* resp = etcdv3::Utils::getKey(key, grpcClient);
if(resp->reply.kvs_size())
{
call->prev_value = resp->reply.kvs(0);
}
call->client = &grpcClient;
call->key = key;
call->response_reader = grpcClient.stub_->AsyncPut(&call->context,put_request,&call->cq_);
call->response_reader->Finish(&call->reply, &call->status, (void*)call);
return Response::create(call);
}

272
src/Client_BASE_9708.cpp Normal file
View File

@ -0,0 +1,272 @@
#include "etcd/Client.hpp"
#include "v3/include/AsyncRangeResponse.hpp"
#include "v3/include/AsyncPutResponse.hpp"
#include "v3/include/Utils.hpp"
etcd::Client::Client(std::string const & address)
: client(address), grpcClient(address)
{
}
pplx::task<etcd::Response> etcd::Client::send_get_request(web::http::uri_builder & uri)
{
return Response::create(client.request(web::http::methods::GET, uri.to_string()));
}
pplx::task<etcd::Response> etcd::Client::send_del_request(web::http::uri_builder & uri)
{
return Response::create(client.request(web::http::methods::DEL, uri.to_string()));
}
pplx::task<etcd::Response> etcd::Client::send_put_request(web::http::uri_builder & uri, std::string const & key, std::string const & value)
{
std::string data = key + "=" + value;
std::string content_type = "application/x-www-form-urlencoded; param=" + key;
return Response::create(client.request(web::http::methods::PUT, uri.to_string(), data.c_str(), content_type.c_str()));
}
pplx::task<etcd::Response> etcd::Client::get(std::string const & key)
{
return send_asyncget(key);
}
pplx::task<etcd::Response> etcd::Client::set(std::string const & key, std::string const & value)
{
return send_asyncput(key,value);
}
pplx::task<etcd::Response> etcd::Client::add(std::string const & key, std::string const & value)
{
return send_asyncadd(key,value);
}
pplx::task<etcd::Response> etcd::Client::modify(std::string const & key, std::string const & value)
{
return send_asyncmodify(key,value);
}
pplx::task<etcd::Response> etcd::Client::modify_if(std::string const & key, std::string const & value, std::string const & old_value)
{
return send_asyncmodify_if(key, value, old_value);
}
pplx::task<etcd::Response> etcd::Client::modify_if(std::string const & key, std::string const & value, int old_index)
{
web::http::uri_builder uri("/v2/keys" + key);
uri.append_query("prevIndex", old_index);
return send_put_request(uri, "value", value);
}
pplx::task<etcd::Response> etcd::Client::rm(std::string const & key)
{
web::http::uri_builder uri("/v2/keys" + key);
uri.append_query("dir=false");
return Response::create(client.request("DELETE", uri.to_string()));
}
pplx::task<etcd::Response> etcd::Client::rm_if(std::string const & key, std::string const & old_value)
{
web::http::uri_builder uri("/v2/keys" + key);
uri.append_query("dir=false");
uri.append_query("prevValue", old_value);
return send_del_request(uri);
}
pplx::task<etcd::Response> etcd::Client::rm_if(std::string const & key, int old_index)
{
web::http::uri_builder uri("/v2/keys" + key);
uri.append_query("dir=false");
uri.append_query("prevIndex", old_index);
return send_del_request(uri);
}
pplx::task<etcd::Response> etcd::Client::mkdir(std::string const & key)
{
web::http::uri_builder uri("/v2/keys" + key);
return send_put_request(uri, "dir", "true");
}
pplx::task<etcd::Response> etcd::Client::rmdir(std::string const & key, bool recursive)
{
web::http::uri_builder uri("/v2/keys" + key);
uri.append_query("dir=true");
if (recursive)
uri.append_query("recursive=true");
return send_del_request(uri);
}
pplx::task<etcd::Response> etcd::Client::ls(std::string const & key)
{
web::http::uri_builder uri("/v2/keys" + key);
uri.append_query("sorted=true");
return send_get_request(uri);
}
pplx::task<etcd::Response> etcd::Client::watch(std::string const & key, bool recursive)
{
web::http::uri_builder uri("/v2/keys" + key);
uri.append_query("wait=true");
if (recursive)
uri.append_query("recursive=true");
return send_get_request(uri);
}
pplx::task<etcd::Response> etcd::Client::watch(std::string const & key, int fromIndex, bool recursive)
{
web::http::uri_builder uri("/v2/keys" + key);
uri.append_query("wait=true");
uri.append_query("waitIndex", fromIndex);
if (recursive)
uri.append_query("recursive=true");
return send_get_request(uri);
}
pplx::task<etcd::Response> etcd::Client::send_asyncadd(std::string const & key, std::string const & value)
{
//check if key already exist
etcdv3::AsyncRangeResponse* resp = etcdv3::Utils::getKey(key, grpcClient);
if(resp->reply.kvs_size())
{
resp->error_code=105;
resp->error_message="Key already exists";
return Response::createResponse(*resp);
}
PutRequest put_request;
put_request.set_key(key);
put_request.set_value(value);
etcdv3::AsyncPutResponse* call= new etcdv3::AsyncPutResponse("create");
//below 2 lines can be removed once we are able to use Txn
call->client = &grpcClient;
call->key = key;
call->response_reader = grpcClient.stub_->AsyncPut(&call->context,put_request,&call->cq_);
call->response_reader->Finish(&call->reply, &call->status, (void*)call);
return Response::create(call);
}
pplx::task<etcd::Response> etcd::Client::send_asyncmodify_if(std::string const & key, std::string const & value, std::string const & old_value)
{
//check current key is equal to old_value
etcdv3::AsyncRangeResponse* resp = etcdv3::Utils::getKey(key, grpcClient);
if(!resp->reply.kvs_size())
{
resp->error_code=100;
resp->error_message="Key not found";
return Response::createResponse(*resp);
}
else
{
if(resp->reply.kvs(0).value() != old_value)
{
resp->error_code=101;
resp->error_message="Compare failed";
return Response::createResponse(*resp);
}
}
PutRequest put_request;
put_request.set_key(key);
put_request.set_value(value);
etcdv3::AsyncPutResponse* call= new etcdv3::AsyncPutResponse("compareAndSwap");
//below 2 lines can be removed once we are able to use Txn
call->prev_value = resp->reply.kvs(0);
call->client = &grpcClient;
call->key = key;
call->response_reader = grpcClient.stub_->AsyncPut(&call->context,put_request,&call->cq_);
call->response_reader->Finish(&call->reply, &call->status, (void*)call);
return Response::create(call);
}
pplx::task<etcd::Response> etcd::Client::send_asyncmodify(std::string const & key, std::string const & value)
{
//check if key already exist
etcdv3::AsyncRangeResponse* resp = etcdv3::Utils::getKey(key, grpcClient);
if(!resp->reply.kvs_size())
{
resp->error_code=100;
resp->error_message="Key not found";
return Response::createResponse(*resp);
}
PutRequest put_request;
put_request.set_key(key);
put_request.set_value(value);
etcdv3::AsyncPutResponse* call= new etcdv3::AsyncPutResponse("update");
//below 2 lines can be removed once we are able to use Txn
call->prev_value = resp->reply.kvs(0);
call->client = &grpcClient;
call->key = key;
call->response_reader = grpcClient.stub_->AsyncPut(&call->context,put_request,&call->cq_);
call->response_reader->Finish(&call->reply, &call->status, (void*)call);
return Response::create(call);
}
pplx::task<etcd::Response> etcd::Client::send_asyncget(std::string const & key)
{
RangeRequest request;
request.set_key(key);
etcdv3::AsyncRangeResponse* call= new etcdv3::AsyncRangeResponse();
call->response_reader = grpcClient.stub_->AsyncRange(&call->context,request,&call->cq_);
call->response_reader->Finish(&call->reply, &call->status, (void*)call);
return Response::create(call);
}
pplx::task<etcd::Response> etcd::Client::send_asyncput(std::string const & key, std::string const & value)
{
PutRequest put_request;
put_request.set_key(key);
put_request.set_value(value);
etcdv3::AsyncPutResponse* call= new etcdv3::AsyncPutResponse("set");
//get current value
etcdv3::AsyncRangeResponse* resp = etcdv3::Utils::getKey(key, grpcClient);
if(resp->reply.kvs_size())
{
call->prev_value = resp->reply.kvs(0);
}
call->client = &grpcClient;
call->key = key;
call->response_reader = grpcClient.stub_->AsyncPut(&call->context,put_request,&call->cq_);
call->response_reader->Finish(&call->reply, &call->status, (void*)call);
return Response::create(call);
}

384
src/Client_LOCAL_12044.cpp Normal file
View File

@ -0,0 +1,384 @@
#include "etcd/Client.hpp"
#include "v3/include/AsyncRangeResponse.hpp"
#include "v3/include/AsyncPutResponse.hpp"
#include "v3/include/AsyncDelResponse.hpp"
#include "v3/include/AsyncModifyResponse.hpp"
#include "v3/include/Utils.hpp"
#include <iostream>
etcd::Client::Client(std::string const & address)
: client(address), grpcClient(address)
{
}
pplx::task<etcd::Response> etcd::Client::send_get_request(web::http::uri_builder & uri)
{
return Response::create(client.request(web::http::methods::GET, uri.to_string()));
}
pplx::task<etcd::Response> etcd::Client::send_del_request(web::http::uri_builder & uri)
{
return Response::create(client.request(web::http::methods::DEL, uri.to_string()));
}
pplx::task<etcd::Response> etcd::Client::send_put_request(web::http::uri_builder & uri, std::string const & key, std::string const & value)
{
std::string data = key + "=" + value;
std::string content_type = "application/x-www-form-urlencoded; param=" + key;
return Response::create(client.request(web::http::methods::PUT, uri.to_string(), data.c_str(), content_type.c_str()));
}
pplx::task<etcd::Response> etcd::Client::get(std::string const & key)
{
return send_asyncget(key);
}
pplx::task<etcd::Response> etcd::Client::set(std::string const & key, std::string const & value)
{
return send_asyncput(key,value);
}
pplx::task<etcd::Response> etcd::Client::add(std::string const & key, std::string const & value)
{
return send_asyncadd(key,value);
}
pplx::task<etcd::Response> etcd::Client::modify(std::string const & key, std::string const & value)
{
return send_asyncmodify(key,value);
}
pplx::task<etcd::Response> etcd::Client::modify_if(std::string const & key, std::string const & value, std::string const & old_value)
{
return send_asyncmodify_if(key, value, old_value);
}
pplx::task<etcd::Response> etcd::Client::modifyEntryWithValueAndOldIndex(std::string const & key, std::string const & value, int old_index) {
etcdv3::AsyncRangeResponse* resp = etcdv3::Utils::getKey(key, grpcClient);
if(!resp->reply.kvs_size())
{
resp->error_code=100;
resp->error_message="Key not found";
return Response::createResponse(*resp);
}
else if(resp->reply.kvs(0).mod_revision() != old_index)
{
resp->error_code = 101;
resp->error_message = "Compare failed";
return Response::createResponse(*resp);
}
PutRequest put_request;
put_request.set_key(key);
put_request.set_value(value);
etcdv3::AsyncModifyResponse* call= new etcdv3::AsyncModifyResponse("compareAndSwap");
//below 2 lines can be removed once we are able to use Txn
call->prev_value = resp->reply.kvs(0);
call->client = &grpcClient;
call->key = key;
call->rpcInstance = grpcClient.stub_->AsyncPut(&call->context,put_request,&call->cq_);
call->rpcInstance->Finish(&call->putResponse, &call->status, (void*)call);
return Response::create(call);
}
pplx::task<etcd::Response> etcd::Client::modify_if(std::string const & key, std::string const & value, int old_index)
{
return modifyEntryWithValueAndOldIndex(key, value, old_index);
}
//note: this one seems to not need the parseResponse() method
pplx::task<etcd::Response> etcd::Client::removeEntryWithKey(std::string const & entryKey) {
etcdv3::AsyncRangeResponse* resp = etcdv3::Utils::getKey(entryKey, grpcClient);
if(!resp->reply.kvs_size())
{
std::cout << "nothing to delete" << std::endl;
resp->error_code = 100;
resp->error_message = "Nothing to delete";
return Response::createResponse(*resp);
}
etcdserverpb::DeleteRangeRequest deleteRangeRequest;
deleteRangeRequest.set_key(entryKey);
etcdv3::AsyncDelResponse* call = new etcdv3::AsyncDelResponse("delete");
//mano-mano
call->prev_value = resp->reply.kvs(0);
call->client = &grpcClient;
call->key = entryKey;
call->rpcInstance = grpcClient.stub_->AsyncDeleteRange(&call->context, deleteRangeRequest, &call->cq_);
call->rpcInstance->Finish(&call->deleteResponse, &call->status, (void*)call);
return Response::createResponse(*call);
}
pplx::task<etcd::Response> etcd::Client::rm(std::string const & key)
{
return removeEntryWithKey(key);
}
pplx::task<etcd::Response> etcd::Client::removeEntryWithKeyAndValue(std::string const &entryKey, std::string const &oldValue) {
etcdv3::AsyncRangeResponse *searchResult = etcdv3::Utils::getKey(entryKey, grpcClient);
if(!searchResult->reply.kvs_size()) {
searchResult->error_code = 100;
searchResult->error_message = "Key not Found";
return Response::createResponse(*searchResult);
}
else if(searchResult->reply.kvs(0).value() != oldValue) {
searchResult->error_code = 101;
searchResult->error_message = "Compare failed";
return Response::createResponse(*searchResult);
}
etcdserverpb::DeleteRangeRequest deleteRangeRequest;
deleteRangeRequest.set_key(entryKey);
etcdv3::AsyncDelResponse *deleteResponseCall = new etcdv3::AsyncDelResponse("compareAndDelete");
deleteResponseCall->prev_value = searchResult->reply.kvs(0);
deleteResponseCall->client = &grpcClient;
deleteResponseCall->key = entryKey;
deleteResponseCall->rpcInstance = grpcClient.stub_->AsyncDeleteRange(&deleteResponseCall->context, deleteRangeRequest, &deleteResponseCall->cq_);
deleteResponseCall->rpcInstance->Finish(&deleteResponseCall->deleteResponse, &deleteResponseCall->status, (void*)deleteResponseCall);
return Response::createResponse(*deleteResponseCall);
}
pplx::task<etcd::Response> etcd::Client::rm_if(std::string const & key, std::string const & old_value)
{
return removeEntryWithKeyAndValue(key, old_value);
}
pplx::task<etcd::Response> etcd::Client::removeEntryWithKeyAndIndex(std::string const &entryKey, int oldIndex) {
etcdv3::AsyncRangeResponse *searchResult = etcdv3::Utils::getKey(entryKey, grpcClient);
if(!searchResult->reply.kvs_size()) {
searchResult->error_code = 100;
searchResult->error_message = "Key not Found";
return Response::createResponse(*searchResult);
}
else if(searchResult->reply.kvs(0).create_revision() != oldIndex) {
searchResult->error_code = 101;
searchResult->error_message = "Compare failed";
return Response::createResponse(*searchResult);
}
etcdserverpb::DeleteRangeRequest deleteRangeRequest;
deleteRangeRequest.set_key(entryKey);
etcdv3::AsyncDelResponse *deleteResponseCall = new etcdv3::AsyncDelResponse("compareAndDelete");
deleteResponseCall->prev_value = searchResult->reply.kvs(0);
deleteResponseCall->client = &grpcClient;
deleteResponseCall->key = entryKey;
deleteResponseCall->rpcInstance = grpcClient.stub_->AsyncDeleteRange(&deleteResponseCall->context, deleteRangeRequest, &deleteResponseCall->cq_);
deleteResponseCall->rpcInstance->Finish(&deleteResponseCall->deleteResponse, &deleteResponseCall->status, (void*)deleteResponseCall);
return Response::createResponse(*deleteResponseCall);
}
pplx::task<etcd::Response> etcd::Client::rm_if(std::string const & key, int old_index)
{
return removeEntryWithKeyAndIndex(key, old_index);
}
pplx::task<etcd::Response> etcd::Client::mkdir(std::string const & key)
{
web::http::uri_builder uri("/v2/keys" + key);
return send_put_request(uri, "dir", "true");
}
pplx::task<etcd::Response> etcd::Client::rmdir(std::string const & key, bool recursive)
{
web::http::uri_builder uri("/v2/keys" + key);
uri.append_query("dir=true");
if (recursive)
uri.append_query("recursive=true");
return send_del_request(uri);
}
pplx::task<etcd::Response> etcd::Client::ls(std::string const & key)
{
web::http::uri_builder uri("/v2/keys" + key);
uri.append_query("sorted=true");
return send_get_request(uri);
}
pplx::task<etcd::Response> etcd::Client::watch(std::string const & key, bool recursive)
{
web::http::uri_builder uri("/v2/keys" + key);
uri.append_query("wait=true");
if (recursive)
uri.append_query("recursive=true");
return send_get_request(uri);
}
pplx::task<etcd::Response> etcd::Client::watch(std::string const & key, int fromIndex, bool recursive)
{
web::http::uri_builder uri("/v2/keys" + key);
uri.append_query("wait=true");
uri.append_query("waitIndex", fromIndex);
if (recursive)
uri.append_query("recursive=true");
return send_get_request(uri);
}
pplx::task<etcd::Response> etcd::Client::send_asyncadd(std::string const & key, std::string const & value)
{
//check if key already exist
etcdv3::AsyncRangeResponse* resp = etcdv3::Utils::getKey(key, grpcClient);
if(resp->reply.kvs_size())
{
resp->error_code=105;
resp->error_message="Key already exists";
return Response::createResponse(*resp);
}
PutRequest put_request;
put_request.set_key(key);
put_request.set_value(value);
etcdv3::AsyncPutResponse* call= new etcdv3::AsyncPutResponse("create");
//below 2 lines can be removed once we are able to use Txn
call->client = &grpcClient;
call->key = key;
call->response_reader = grpcClient.stub_->AsyncPut(&call->context,put_request,&call->cq_);
call->response_reader->Finish(&call->reply, &call->status, (void*)call);
return Response::create(call);
}
pplx::task<etcd::Response> etcd::Client::send_asyncmodify_if(std::string const & key, std::string const & value, std::string const & old_value)
{
//check current key is equal to old_value
etcdv3::AsyncRangeResponse* resp = etcdv3::Utils::getKey(key, grpcClient);
if(!resp->reply.kvs_size())
{
resp->error_code=100;
resp->error_message="Key not found";
return Response::createResponse(*resp);
}
else
{
if(resp->reply.kvs(0).value() != old_value)
{
resp->error_code=101;
resp->error_message="Compare failed";
return Response::createResponse(*resp);
}
}
PutRequest put_request;
put_request.set_key(key);
put_request.set_value(value);
etcdv3::AsyncModifyResponse* call= new etcdv3::AsyncModifyResponse("compareAndSwap");
//below 2 lines can be removed once we are able to use Txn
call->prev_value = resp->reply.kvs(0);
call->client = &grpcClient;
call->key = key;
call->rpcInstance = grpcClient.stub_->AsyncPut(&call->context,put_request,&call->cq_);
call->rpcInstance->Finish(&call->putResponse, &call->status, (void*)call);
return Response::create(call);
}
pplx::task<etcd::Response> etcd::Client::send_asyncmodify(std::string const & key, std::string const & value)
{
//check if key already exist
etcdv3::AsyncRangeResponse* resp = etcdv3::Utils::getKey(key, grpcClient);
if(!resp->reply.kvs_size())
{
resp->error_code=100;
resp->error_message="Key not found";
return Response::createResponse(*resp);
}
PutRequest put_request;
put_request.set_key(key);
put_request.set_value(value);
etcdv3::AsyncModifyResponse* call= new etcdv3::AsyncModifyResponse("update");
//below 2 lines can be removed once we are able to use Txn
call->prev_value = resp->reply.kvs(0);
call->client = &grpcClient;
call->key = key;
call->rpcInstance = grpcClient.stub_->AsyncPut(&call->context,put_request,&call->cq_);
call->rpcInstance->Finish(&call->putResponse, &call->status, (void*)call);
return Response::create(call);
}
pplx::task<etcd::Response> etcd::Client::send_asyncget(std::string const & key)
{
RangeRequest request;
request.set_key(key);
etcdv3::AsyncRangeResponse* call= new etcdv3::AsyncRangeResponse();
call->response_reader = grpcClient.stub_->AsyncRange(&call->context,request,&call->cq_);
call->response_reader->Finish(&call->reply, &call->status, (void*)call);
return Response::create(call);
}
pplx::task<etcd::Response> etcd::Client::send_asyncput(std::string const & key, std::string const & value)
{
PutRequest put_request;
put_request.set_key(key);
put_request.set_value(value);
etcdv3::AsyncPutResponse* call= new etcdv3::AsyncPutResponse("set");
//get current value
etcdv3::AsyncRangeResponse* resp = etcdv3::Utils::getKey(key, grpcClient);
if(resp->reply.kvs_size())
{
call->prev_value = resp->reply.kvs(0);
}
call->client = &grpcClient;
call->key = key;
call->response_reader = grpcClient.stub_->AsyncPut(&call->context,put_request,&call->cq_);
call->response_reader->Finish(&call->reply, &call->status, (void*)call);
return Response::create(call);
}

384
src/Client_LOCAL_9708.cpp Normal file
View File

@ -0,0 +1,384 @@
#include "etcd/Client.hpp"
#include "v3/include/AsyncRangeResponse.hpp"
#include "v3/include/AsyncPutResponse.hpp"
#include "v3/include/AsyncDelResponse.hpp"
#include "v3/include/AsyncModifyResponse.hpp"
#include "v3/include/Utils.hpp"
#include <iostream>
etcd::Client::Client(std::string const & address)
: client(address), grpcClient(address)
{
}
pplx::task<etcd::Response> etcd::Client::send_get_request(web::http::uri_builder & uri)
{
return Response::create(client.request(web::http::methods::GET, uri.to_string()));
}
pplx::task<etcd::Response> etcd::Client::send_del_request(web::http::uri_builder & uri)
{
return Response::create(client.request(web::http::methods::DEL, uri.to_string()));
}
pplx::task<etcd::Response> etcd::Client::send_put_request(web::http::uri_builder & uri, std::string const & key, std::string const & value)
{
std::string data = key + "=" + value;
std::string content_type = "application/x-www-form-urlencoded; param=" + key;
return Response::create(client.request(web::http::methods::PUT, uri.to_string(), data.c_str(), content_type.c_str()));
}
pplx::task<etcd::Response> etcd::Client::get(std::string const & key)
{
return send_asyncget(key);
}
pplx::task<etcd::Response> etcd::Client::set(std::string const & key, std::string const & value)
{
return send_asyncput(key,value);
}
pplx::task<etcd::Response> etcd::Client::add(std::string const & key, std::string const & value)
{
return send_asyncadd(key,value);
}
pplx::task<etcd::Response> etcd::Client::modify(std::string const & key, std::string const & value)
{
return send_asyncmodify(key,value);
}
pplx::task<etcd::Response> etcd::Client::modify_if(std::string const & key, std::string const & value, std::string const & old_value)
{
return send_asyncmodify_if(key, value, old_value);
}
pplx::task<etcd::Response> etcd::Client::modifyEntryWithValueAndOldIndex(std::string const & key, std::string const & value, int old_index) {
etcdv3::AsyncRangeResponse* resp = etcdv3::Utils::getKey(key, grpcClient);
if(!resp->reply.kvs_size())
{
resp->error_code=100;
resp->error_message="Key not found";
return Response::createResponse(*resp);
}
else if(resp->reply.kvs(0).mod_revision() != old_index)
{
resp->error_code = 101;
resp->error_message = "Compare failed";
return Response::createResponse(*resp);
}
PutRequest put_request;
put_request.set_key(key);
put_request.set_value(value);
etcdv3::AsyncModifyResponse* call= new etcdv3::AsyncModifyResponse("compareAndSwap");
//below 2 lines can be removed once we are able to use Txn
call->prev_value = resp->reply.kvs(0);
call->client = &grpcClient;
call->key = key;
call->rpcInstance = grpcClient.stub_->AsyncPut(&call->context,put_request,&call->cq_);
call->rpcInstance->Finish(&call->putResponse, &call->status, (void*)call);
return Response::create(call);
}
pplx::task<etcd::Response> etcd::Client::modify_if(std::string const & key, std::string const & value, int old_index)
{
return modifyEntryWithValueAndOldIndex(key, value, old_index);
}
//note: this one seems to not need the parseResponse() method
pplx::task<etcd::Response> etcd::Client::removeEntryWithKey(std::string const & entryKey) {
etcdv3::AsyncRangeResponse* resp = etcdv3::Utils::getKey(entryKey, grpcClient);
if(!resp->reply.kvs_size())
{
std::cout << "nothing to delete" << std::endl;
resp->error_code = 100;
resp->error_message = "Nothing to delete";
return Response::createResponse(*resp);
}
etcdserverpb::DeleteRangeRequest deleteRangeRequest;
deleteRangeRequest.set_key(entryKey);
etcdv3::AsyncDelResponse* call = new etcdv3::AsyncDelResponse("delete");
//mano-mano
call->prev_value = resp->reply.kvs(0);
call->client = &grpcClient;
call->key = entryKey;
call->rpcInstance = grpcClient.stub_->AsyncDeleteRange(&call->context, deleteRangeRequest, &call->cq_);
call->rpcInstance->Finish(&call->deleteResponse, &call->status, (void*)call);
return Response::createResponse(*call);
}
pplx::task<etcd::Response> etcd::Client::rm(std::string const & key)
{
return removeEntryWithKey(key);
}
pplx::task<etcd::Response> etcd::Client::removeEntryWithKeyAndValue(std::string const &entryKey, std::string const &oldValue) {
etcdv3::AsyncRangeResponse *searchResult = etcdv3::Utils::getKey(entryKey, grpcClient);
if(!searchResult->reply.kvs_size()) {
searchResult->error_code = 100;
searchResult->error_message = "Key not Found";
return Response::createResponse(*searchResult);
}
else if(searchResult->reply.kvs(0).value() != oldValue) {
searchResult->error_code = 101;
searchResult->error_message = "Compare failed";
return Response::createResponse(*searchResult);
}
etcdserverpb::DeleteRangeRequest deleteRangeRequest;
deleteRangeRequest.set_key(entryKey);
etcdv3::AsyncDelResponse *deleteResponseCall = new etcdv3::AsyncDelResponse("compareAndDelete");
deleteResponseCall->prev_value = searchResult->reply.kvs(0);
deleteResponseCall->client = &grpcClient;
deleteResponseCall->key = entryKey;
deleteResponseCall->rpcInstance = grpcClient.stub_->AsyncDeleteRange(&deleteResponseCall->context, deleteRangeRequest, &deleteResponseCall->cq_);
deleteResponseCall->rpcInstance->Finish(&deleteResponseCall->deleteResponse, &deleteResponseCall->status, (void*)deleteResponseCall);
return Response::createResponse(*deleteResponseCall);
}
pplx::task<etcd::Response> etcd::Client::rm_if(std::string const & key, std::string const & old_value)
{
return removeEntryWithKeyAndValue(key, old_value);
}
pplx::task<etcd::Response> etcd::Client::removeEntryWithKeyAndIndex(std::string const &entryKey, int oldIndex) {
etcdv3::AsyncRangeResponse *searchResult = etcdv3::Utils::getKey(entryKey, grpcClient);
if(!searchResult->reply.kvs_size()) {
searchResult->error_code = 100;
searchResult->error_message = "Key not Found";
return Response::createResponse(*searchResult);
}
else if(searchResult->reply.kvs(0).create_revision() != oldIndex) {
searchResult->error_code = 101;
searchResult->error_message = "Compare failed";
return Response::createResponse(*searchResult);
}
etcdserverpb::DeleteRangeRequest deleteRangeRequest;
deleteRangeRequest.set_key(entryKey);
etcdv3::AsyncDelResponse *deleteResponseCall = new etcdv3::AsyncDelResponse("compareAndDelete");
deleteResponseCall->prev_value = searchResult->reply.kvs(0);
deleteResponseCall->client = &grpcClient;
deleteResponseCall->key = entryKey;
deleteResponseCall->rpcInstance = grpcClient.stub_->AsyncDeleteRange(&deleteResponseCall->context, deleteRangeRequest, &deleteResponseCall->cq_);
deleteResponseCall->rpcInstance->Finish(&deleteResponseCall->deleteResponse, &deleteResponseCall->status, (void*)deleteResponseCall);
return Response::createResponse(*deleteResponseCall);
}
pplx::task<etcd::Response> etcd::Client::rm_if(std::string const & key, int old_index)
{
return removeEntryWithKeyAndIndex(key, old_index);
}
pplx::task<etcd::Response> etcd::Client::mkdir(std::string const & key)
{
web::http::uri_builder uri("/v2/keys" + key);
return send_put_request(uri, "dir", "true");
}
pplx::task<etcd::Response> etcd::Client::rmdir(std::string const & key, bool recursive)
{
web::http::uri_builder uri("/v2/keys" + key);
uri.append_query("dir=true");
if (recursive)
uri.append_query("recursive=true");
return send_del_request(uri);
}
pplx::task<etcd::Response> etcd::Client::ls(std::string const & key)
{
web::http::uri_builder uri("/v2/keys" + key);
uri.append_query("sorted=true");
return send_get_request(uri);
}
pplx::task<etcd::Response> etcd::Client::watch(std::string const & key, bool recursive)
{
web::http::uri_builder uri("/v2/keys" + key);
uri.append_query("wait=true");
if (recursive)
uri.append_query("recursive=true");
return send_get_request(uri);
}
pplx::task<etcd::Response> etcd::Client::watch(std::string const & key, int fromIndex, bool recursive)
{
web::http::uri_builder uri("/v2/keys" + key);
uri.append_query("wait=true");
uri.append_query("waitIndex", fromIndex);
if (recursive)
uri.append_query("recursive=true");
return send_get_request(uri);
}
pplx::task<etcd::Response> etcd::Client::send_asyncadd(std::string const & key, std::string const & value)
{
//check if key already exist
etcdv3::AsyncRangeResponse* resp = etcdv3::Utils::getKey(key, grpcClient);
if(resp->reply.kvs_size())
{
resp->error_code=105;
resp->error_message="Key already exists";
return Response::createResponse(*resp);
}
PutRequest put_request;
put_request.set_key(key);
put_request.set_value(value);
etcdv3::AsyncPutResponse* call= new etcdv3::AsyncPutResponse("create");
//below 2 lines can be removed once we are able to use Txn
call->client = &grpcClient;
call->key = key;
call->response_reader = grpcClient.stub_->AsyncPut(&call->context,put_request,&call->cq_);
call->response_reader->Finish(&call->reply, &call->status, (void*)call);
return Response::create(call);
}
pplx::task<etcd::Response> etcd::Client::send_asyncmodify_if(std::string const & key, std::string const & value, std::string const & old_value)
{
//check current key is equal to old_value
etcdv3::AsyncRangeResponse* resp = etcdv3::Utils::getKey(key, grpcClient);
if(!resp->reply.kvs_size())
{
resp->error_code=100;
resp->error_message="Key not found";
return Response::createResponse(*resp);
}
else
{
if(resp->reply.kvs(0).value() != old_value)
{
resp->error_code=101;
resp->error_message="Compare failed";
return Response::createResponse(*resp);
}
}
PutRequest put_request;
put_request.set_key(key);
put_request.set_value(value);
etcdv3::AsyncModifyResponse* call= new etcdv3::AsyncModifyResponse("compareAndSwap");
//below 2 lines can be removed once we are able to use Txn
call->prev_value = resp->reply.kvs(0);
call->client = &grpcClient;
call->key = key;
call->rpcInstance = grpcClient.stub_->AsyncPut(&call->context,put_request,&call->cq_);
call->rpcInstance->Finish(&call->putResponse, &call->status, (void*)call);
return Response::create(call);
}
pplx::task<etcd::Response> etcd::Client::send_asyncmodify(std::string const & key, std::string const & value)
{
//check if key already exist
etcdv3::AsyncRangeResponse* resp = etcdv3::Utils::getKey(key, grpcClient);
if(!resp->reply.kvs_size())
{
resp->error_code=100;
resp->error_message="Key not found";
return Response::createResponse(*resp);
}
PutRequest put_request;
put_request.set_key(key);
put_request.set_value(value);
etcdv3::AsyncModifyResponse* call= new etcdv3::AsyncModifyResponse("update");
//below 2 lines can be removed once we are able to use Txn
call->prev_value = resp->reply.kvs(0);
call->client = &grpcClient;
call->key = key;
call->rpcInstance = grpcClient.stub_->AsyncPut(&call->context,put_request,&call->cq_);
call->rpcInstance->Finish(&call->putResponse, &call->status, (void*)call);
return Response::create(call);
}
pplx::task<etcd::Response> etcd::Client::send_asyncget(std::string const & key)
{
RangeRequest request;
request.set_key(key);
etcdv3::AsyncRangeResponse* call= new etcdv3::AsyncRangeResponse();
call->response_reader = grpcClient.stub_->AsyncRange(&call->context,request,&call->cq_);
call->response_reader->Finish(&call->reply, &call->status, (void*)call);
return Response::create(call);
}
pplx::task<etcd::Response> etcd::Client::send_asyncput(std::string const & key, std::string const & value)
{
PutRequest put_request;
put_request.set_key(key);
put_request.set_value(value);
etcdv3::AsyncPutResponse* call= new etcdv3::AsyncPutResponse("set");
//get current value
etcdv3::AsyncRangeResponse* resp = etcdv3::Utils::getKey(key, grpcClient);
if(resp->reply.kvs_size())
{
call->prev_value = resp->reply.kvs(0);
}
call->client = &grpcClient;
call->key = key;
call->response_reader = grpcClient.stub_->AsyncPut(&call->context,put_request,&call->cq_);
call->response_reader->Finish(&call->reply, &call->status, (void*)call);
return Response::create(call);
}

294
src/Client_REMOTE_12044.cpp Normal file
View File

@ -0,0 +1,294 @@
#include "etcd/Client.hpp"
#include "v3/include/AsyncRangeResponse.hpp"
#include "v3/include/AsyncPutResponse.hpp"
#include "v3/include/AsyncTxnResponse.hpp"
#include "v3/include/Utils.hpp"
#include <memory>
using etcdserverpb::TxnRequest;
using etcdserverpb::Compare;
using etcdserverpb::RequestOp;
etcd::Client::Client(std::string const & address)
: client(address), grpcClient(address)
{
}
pplx::task<etcd::Response> etcd::Client::send_get_request(web::http::uri_builder & uri)
{
return Response::create(client.request(web::http::methods::GET, uri.to_string()));
}
pplx::task<etcd::Response> etcd::Client::send_del_request(web::http::uri_builder & uri)
{
return Response::create(client.request(web::http::methods::DEL, uri.to_string()));
}
pplx::task<etcd::Response> etcd::Client::send_put_request(web::http::uri_builder & uri, std::string const & key, std::string const & value)
{
std::string data = key + "=" + value;
std::string content_type = "application/x-www-form-urlencoded; param=" + key;
return Response::create(client.request(web::http::methods::PUT, uri.to_string(), data.c_str(), content_type.c_str()));
}
pplx::task<etcd::Response> etcd::Client::get(std::string const & key)
{
return send_asyncget(key);
}
pplx::task<etcd::Response> etcd::Client::set(std::string const & key, std::string const & value)
{
return send_asyncput(key,value);
}
pplx::task<etcd::Response> etcd::Client::add(std::string const & key, std::string const & value)
{
return send_asyncadd(key,value);
}
pplx::task<etcd::Response> etcd::Client::modify(std::string const & key, std::string const & value)
{
return send_asyncmodify(key,value);
}
pplx::task<etcd::Response> etcd::Client::modify_if(std::string const & key, std::string const & value, std::string const & old_value)
{
return send_asyncmodify_if(key, value, old_value);
}
pplx::task<etcd::Response> etcd::Client::modify_if(std::string const & key, std::string const & value, int old_index)
{
web::http::uri_builder uri("/v2/keys" + key);
uri.append_query("prevIndex", old_index);
return send_put_request(uri, "value", value);
}
pplx::task<etcd::Response> etcd::Client::rm(std::string const & key)
{
web::http::uri_builder uri("/v2/keys" + key);
uri.append_query("dir=false");
return Response::create(client.request("DELETE", uri.to_string()));
}
pplx::task<etcd::Response> etcd::Client::rm_if(std::string const & key, std::string const & old_value)
{
web::http::uri_builder uri("/v2/keys" + key);
uri.append_query("dir=false");
uri.append_query("prevValue", old_value);
return send_del_request(uri);
}
pplx::task<etcd::Response> etcd::Client::rm_if(std::string const & key, int old_index)
{
web::http::uri_builder uri("/v2/keys" + key);
uri.append_query("dir=false");
uri.append_query("prevIndex", old_index);
return send_del_request(uri);
}
pplx::task<etcd::Response> etcd::Client::mkdir(std::string const & key)
{
web::http::uri_builder uri("/v2/keys" + key);
return send_put_request(uri, "dir", "true");
}
pplx::task<etcd::Response> etcd::Client::rmdir(std::string const & key, bool recursive)
{
web::http::uri_builder uri("/v2/keys" + key);
uri.append_query("dir=true");
if (recursive)
uri.append_query("recursive=true");
return send_del_request(uri);
}
pplx::task<etcd::Response> etcd::Client::ls(std::string const & key)
{
web::http::uri_builder uri("/v2/keys" + key);
uri.append_query("sorted=true");
return send_get_request(uri);
}
pplx::task<etcd::Response> etcd::Client::watch(std::string const & key, bool recursive)
{
web::http::uri_builder uri("/v2/keys" + key);
uri.append_query("wait=true");
if (recursive)
uri.append_query("recursive=true");
return send_get_request(uri);
}
pplx::task<etcd::Response> etcd::Client::watch(std::string const & key, int fromIndex, bool recursive)
{
web::http::uri_builder uri("/v2/keys" + key);
uri.append_query("wait=true");
uri.append_query("waitIndex", fromIndex);
if (recursive)
uri.append_query("recursive=true");
return send_get_request(uri);
}
pplx::task<etcd::Response> etcd::Client::send_asyncadd(std::string const & key, std::string const & value)
{
//check if key is not present
TxnRequest txn_request;
Compare* compare = txn_request.add_compare();
compare->set_result(Compare::CompareResult::Compare_CompareResult_EQUAL);
compare->set_target(Compare::CompareTarget::Compare_CompareTarget_VERSION);
compare->set_key(key);
compare->set_version(0);
//get key whether success or failure
RangeRequest get_request1 = new RangeRequest();
get_request1->set_key(key);
RequestOp* req_failure = txn_request.add_failure();
req_failure->set_allocated_request_range(get_request1);
//if success, add key and then get new value of key
PutRequest* put_request = new PutRequest();
put_request->set_key(key);
put_request->set_value(value);
RequestOp* req_success2 = txn_request.add_success();
req_success2->set_allocated_request_put(put_request);
RangeRequest* get_request2 = new RangeRequest();
get_request2->set_key(key);
RequestOp* req_success3 = txn_request.add_success();
req_success3->set_allocated_request_range(get_request2);
etcdv3::AsyncTxnResponse* call= new etcdv3::AsyncTxnResponse("create");
call->response_reader = grpcClient.stub_->AsyncTxn(&call->context,txn_request,&call->cq_);
call->response_reader->Finish(&call->reply, &call->status, (void*)call);
return Response::create(call);
}
pplx::task<etcd::Response> etcd::Client::send_asyncmodify_if(std::string const & key, std::string const & value, std::string const & old_value)
{
//check current key is equal to old_value
etcdv3::AsyncRangeResponse* resp = etcdv3::Utils::getKey(key, grpcClient);
if(!resp->reply.kvs_size())
{
resp->error_code=100;
resp->error_message="Key not found";
return Response::createResponse(*resp);
}
else
{
if(resp->reply.kvs(0).value() != old_value)
{
resp->error_code=101;
resp->error_message="Compare failed";
return Response::createResponse(*resp);
}
}
PutRequest put_request;
put_request.set_key(key);
put_request.set_value(value);
etcdv3::AsyncPutResponse* call= new etcdv3::AsyncPutResponse("compareAndSwap");
//below 2 lines can be removed once we are able to use Txn
call->prev_value = resp->reply.kvs(0);
call->client = &grpcClient;
call->key = key;
call->response_reader = grpcClient.stub_->AsyncPut(&call->context,put_request,&call->cq_);
call->response_reader->Finish(&call->reply, &call->status, (void*)call);
return Response::create(call);
}
pplx::task<etcd::Response> etcd::Client::send_asyncmodify(std::string const & key, std::string const & value)
{
//check if key already exist
etcdv3::AsyncRangeResponse* resp = etcdv3::Utils::getKey(key, grpcClient);
if(!resp->reply.kvs_size())
{
resp->error_code=100;
resp->error_message="Key not found";
return Response::createResponse(*resp);
}
PutRequest put_request;
put_request.set_key(key);
put_request.set_value(value);
etcdv3::AsyncPutResponse* call= new etcdv3::AsyncPutResponse("update");
//below 2 lines can be removed once we are able to use Txn
call->prev_value = resp->reply.kvs(0);
call->client = &grpcClient;
call->key = key;
call->response_reader = grpcClient.stub_->AsyncPut(&call->context,put_request,&call->cq_);
call->response_reader->Finish(&call->reply, &call->status, (void*)call);
return Response::create(call);
}
pplx::task<etcd::Response> etcd::Client::send_asyncget(std::string const & key)
{
RangeRequest request;
request.set_key(key);
etcdv3::AsyncRangeResponse* call= new etcdv3::AsyncRangeResponse();
call->response_reader = grpcClient.stub_->AsyncRange(&call->context,request,&call->cq_);
call->response_reader->Finish(&call->reply, &call->status, (void*)call);
return Response::create(call);
}
pplx::task<etcd::Response> etcd::Client::send_asyncput(std::string const & key, std::string const & value)
{
PutRequest put_request;
put_request.set_key(key);
put_request.set_value(value);
etcdv3::AsyncPutResponse* call= new etcdv3::AsyncPutResponse("set");
//get current value
etcdv3::AsyncRangeResponse* resp = etcdv3::Utils::getKey(key, grpcClient);
if(resp->reply.kvs_size())
{
call->prev_value = resp->reply.kvs(0);
}
call->client = &grpcClient;
call->key = key;
call->response_reader = grpcClient.stub_->AsyncPut(&call->context,put_request,&call->cq_);
call->response_reader->Finish(&call->reply, &call->status, (void*)call);
return Response::create(call);
}

294
src/Client_REMOTE_9708.cpp Normal file
View File

@ -0,0 +1,294 @@
#include "etcd/Client.hpp"
#include "v3/include/AsyncRangeResponse.hpp"
#include "v3/include/AsyncPutResponse.hpp"
#include "v3/include/AsyncTxnResponse.hpp"
#include "v3/include/Utils.hpp"
#include <memory>
using etcdserverpb::TxnRequest;
using etcdserverpb::Compare;
using etcdserverpb::RequestOp;
etcd::Client::Client(std::string const & address)
: client(address), grpcClient(address)
{
}
pplx::task<etcd::Response> etcd::Client::send_get_request(web::http::uri_builder & uri)
{
return Response::create(client.request(web::http::methods::GET, uri.to_string()));
}
pplx::task<etcd::Response> etcd::Client::send_del_request(web::http::uri_builder & uri)
{
return Response::create(client.request(web::http::methods::DEL, uri.to_string()));
}
pplx::task<etcd::Response> etcd::Client::send_put_request(web::http::uri_builder & uri, std::string const & key, std::string const & value)
{
std::string data = key + "=" + value;
std::string content_type = "application/x-www-form-urlencoded; param=" + key;
return Response::create(client.request(web::http::methods::PUT, uri.to_string(), data.c_str(), content_type.c_str()));
}
pplx::task<etcd::Response> etcd::Client::get(std::string const & key)
{
return send_asyncget(key);
}
pplx::task<etcd::Response> etcd::Client::set(std::string const & key, std::string const & value)
{
return send_asyncput(key,value);
}
pplx::task<etcd::Response> etcd::Client::add(std::string const & key, std::string const & value)
{
return send_asyncadd(key,value);
}
pplx::task<etcd::Response> etcd::Client::modify(std::string const & key, std::string const & value)
{
return send_asyncmodify(key,value);
}
pplx::task<etcd::Response> etcd::Client::modify_if(std::string const & key, std::string const & value, std::string const & old_value)
{
return send_asyncmodify_if(key, value, old_value);
}
pplx::task<etcd::Response> etcd::Client::modify_if(std::string const & key, std::string const & value, int old_index)
{
web::http::uri_builder uri("/v2/keys" + key);
uri.append_query("prevIndex", old_index);
return send_put_request(uri, "value", value);
}
pplx::task<etcd::Response> etcd::Client::rm(std::string const & key)
{
web::http::uri_builder uri("/v2/keys" + key);
uri.append_query("dir=false");
return Response::create(client.request("DELETE", uri.to_string()));
}
pplx::task<etcd::Response> etcd::Client::rm_if(std::string const & key, std::string const & old_value)
{
web::http::uri_builder uri("/v2/keys" + key);
uri.append_query("dir=false");
uri.append_query("prevValue", old_value);
return send_del_request(uri);
}
pplx::task<etcd::Response> etcd::Client::rm_if(std::string const & key, int old_index)
{
web::http::uri_builder uri("/v2/keys" + key);
uri.append_query("dir=false");
uri.append_query("prevIndex", old_index);
return send_del_request(uri);
}
pplx::task<etcd::Response> etcd::Client::mkdir(std::string const & key)
{
web::http::uri_builder uri("/v2/keys" + key);
return send_put_request(uri, "dir", "true");
}
pplx::task<etcd::Response> etcd::Client::rmdir(std::string const & key, bool recursive)
{
web::http::uri_builder uri("/v2/keys" + key);
uri.append_query("dir=true");
if (recursive)
uri.append_query("recursive=true");
return send_del_request(uri);
}
pplx::task<etcd::Response> etcd::Client::ls(std::string const & key)
{
web::http::uri_builder uri("/v2/keys" + key);
uri.append_query("sorted=true");
return send_get_request(uri);
}
pplx::task<etcd::Response> etcd::Client::watch(std::string const & key, bool recursive)
{
web::http::uri_builder uri("/v2/keys" + key);
uri.append_query("wait=true");
if (recursive)
uri.append_query("recursive=true");
return send_get_request(uri);
}
pplx::task<etcd::Response> etcd::Client::watch(std::string const & key, int fromIndex, bool recursive)
{
web::http::uri_builder uri("/v2/keys" + key);
uri.append_query("wait=true");
uri.append_query("waitIndex", fromIndex);
if (recursive)
uri.append_query("recursive=true");
return send_get_request(uri);
}
pplx::task<etcd::Response> etcd::Client::send_asyncadd(std::string const & key, std::string const & value)
{
//check if key is not present
TxnRequest txn_request;
Compare* compare = txn_request.add_compare();
compare->set_result(Compare::CompareResult::Compare_CompareResult_EQUAL);
compare->set_target(Compare::CompareTarget::Compare_CompareTarget_VERSION);
compare->set_key(key);
compare->set_version(0);
//get key whether success or failure
RangeRequest get_request1 = new RangeRequest();
get_request1->set_key(key);
RequestOp* req_failure = txn_request.add_failure();
req_failure->set_allocated_request_range(get_request1);
//if success, add key and then get new value of key
PutRequest* put_request = new PutRequest();
put_request->set_key(key);
put_request->set_value(value);
RequestOp* req_success2 = txn_request.add_success();
req_success2->set_allocated_request_put(put_request);
RangeRequest* get_request2 = new RangeRequest();
get_request2->set_key(key);
RequestOp* req_success3 = txn_request.add_success();
req_success3->set_allocated_request_range(get_request2);
etcdv3::AsyncTxnResponse* call= new etcdv3::AsyncTxnResponse("create");
call->response_reader = grpcClient.stub_->AsyncTxn(&call->context,txn_request,&call->cq_);
call->response_reader->Finish(&call->reply, &call->status, (void*)call);
return Response::create(call);
}
pplx::task<etcd::Response> etcd::Client::send_asyncmodify_if(std::string const & key, std::string const & value, std::string const & old_value)
{
//check current key is equal to old_value
etcdv3::AsyncRangeResponse* resp = etcdv3::Utils::getKey(key, grpcClient);
if(!resp->reply.kvs_size())
{
resp->error_code=100;
resp->error_message="Key not found";
return Response::createResponse(*resp);
}
else
{
if(resp->reply.kvs(0).value() != old_value)
{
resp->error_code=101;
resp->error_message="Compare failed";
return Response::createResponse(*resp);
}
}
PutRequest put_request;
put_request.set_key(key);
put_request.set_value(value);
etcdv3::AsyncPutResponse* call= new etcdv3::AsyncPutResponse("compareAndSwap");
//below 2 lines can be removed once we are able to use Txn
call->prev_value = resp->reply.kvs(0);
call->client = &grpcClient;
call->key = key;
call->response_reader = grpcClient.stub_->AsyncPut(&call->context,put_request,&call->cq_);
call->response_reader->Finish(&call->reply, &call->status, (void*)call);
return Response::create(call);
}
pplx::task<etcd::Response> etcd::Client::send_asyncmodify(std::string const & key, std::string const & value)
{
//check if key already exist
etcdv3::AsyncRangeResponse* resp = etcdv3::Utils::getKey(key, grpcClient);
if(!resp->reply.kvs_size())
{
resp->error_code=100;
resp->error_message="Key not found";
return Response::createResponse(*resp);
}
PutRequest put_request;
put_request.set_key(key);
put_request.set_value(value);
etcdv3::AsyncPutResponse* call= new etcdv3::AsyncPutResponse("update");
//below 2 lines can be removed once we are able to use Txn
call->prev_value = resp->reply.kvs(0);
call->client = &grpcClient;
call->key = key;
call->response_reader = grpcClient.stub_->AsyncPut(&call->context,put_request,&call->cq_);
call->response_reader->Finish(&call->reply, &call->status, (void*)call);
return Response::create(call);
}
pplx::task<etcd::Response> etcd::Client::send_asyncget(std::string const & key)
{
RangeRequest request;
request.set_key(key);
etcdv3::AsyncRangeResponse* call= new etcdv3::AsyncRangeResponse();
call->response_reader = grpcClient.stub_->AsyncRange(&call->context,request,&call->cq_);
call->response_reader->Finish(&call->reply, &call->status, (void*)call);
return Response::create(call);
}
pplx::task<etcd::Response> etcd::Client::send_asyncput(std::string const & key, std::string const & value)
{
PutRequest put_request;
put_request.set_key(key);
put_request.set_value(value);
etcdv3::AsyncPutResponse* call= new etcdv3::AsyncPutResponse("set");
//get current value
etcdv3::AsyncRangeResponse* resp = etcdv3::Utils::getKey(key, grpcClient);
if(resp->reply.kvs_size())
{
call->prev_value = resp->reply.kvs(0);
}
call->client = &grpcClient;
call->key = key;
call->response_reader = grpcClient.stub_->AsyncPut(&call->context,put_request,&call->cq_);
call->response_reader->Finish(&call->reply, &call->status, (void*)call);
return Response::create(call);
}

143
src/Response.cpp.orig Normal file
View File

@ -0,0 +1,143 @@
#include "etcd/Response.hpp"
#include "json_constants.hpp"
#include <iostream>
pplx::task<etcd::Response> etcd::Response::create(pplx::task<web::http::http_response> response_task)
{
return pplx::task<etcd::Response> (
[response_task]()
{
auto json_task = response_task.get().extract_json();
return etcd::Response(response_task.get(), json_task.get());
}
);
}
etcd::Response::Response(const etcdv3::V3Response& reply)
{
_index = reply.index;
_error_code = reply.error_code;
_error_message = reply.error_message;
_action = reply.action;
int size = reply.values.size();
if(size > 1)
{
for(int index = 0; index < size; index++)
{
_values.push_back(Value(reply.values[index]));
_keys.push_back(reply.values[index].key());
}
}
else if(size == 1)
{
_value = Value(reply.values[0]);
}
if(reply.prev_values.size() == 1)
<<<<<<< 4adff1a7552b34d6c98def525fa38351e37bf47d
{
_prev_value = Value(reply.prev_values[0]);
}
=======
_prev_value = Value(reply.prev_values[0]);
>>>>>>> made prev_values a vector.
}
etcd::Response::Response()
: _error_code(0),
_index(0)
{
}
etcd::Response::Response(web::http::http_response http_response, web::json::value json_value)
: _error_code(0),
_index(0)
{
if (http_response.headers().has(JSON_ETCD_INDEX))
_index = atoi(http_response.headers()[JSON_ETCD_INDEX].c_str());
if (json_value.has_field(JSON_ERROR_CODE))
{
_error_code = json_value[JSON_ERROR_CODE].as_number().to_int64();
_error_message = json_value[JSON_MESSAGE].as_string();
}
if (json_value.has_field(JSON_ACTION))
_action = json_value[JSON_ACTION].as_string();
if (json_value.has_field(JSON_NODE))
{
if (json_value[JSON_NODE].has_field(JSON_NODES))
{
std::string prefix = json_value[JSON_NODE][JSON_KEY].as_string();
for (auto & node : json_value[JSON_NODE][JSON_NODES].as_array())
{
_values.push_back(Value(node));
_keys.push_back(node[JSON_KEY].as_string().substr(prefix.length() + 1));
}
}
else
_value = Value(json_value.at(JSON_NODE));
}
if (json_value.has_field(JSON_PREV_NODE))
_prev_value = Value(json_value.at(JSON_PREV_NODE));
}
int etcd::Response::error_code() const
{
return _error_code;
}
std::string const & etcd::Response::error_message() const
{
return _error_message;
}
int etcd::Response::index() const
{
return _index;
}
std::string const & etcd::Response::action() const
{
return _action;
}
bool etcd::Response::is_ok() const
{
return error_code() == 0;
}
etcd::Value const & etcd::Response::value() const
{
return _value;
}
etcd::Value const & etcd::Response::prev_value() const
{
return _prev_value;
}
etcd::Values const & etcd::Response::values() const
{
return _values;
}
etcd::Value const & etcd::Response::value(int index) const
{
return _values[index];
}
etcd::Keys const & etcd::Response::keys() const
{
return _keys;
}
std::string const & etcd::Response::key(int index) const
{
return _keys[index];
}

304
tst/EtcdTest.cpp.orig Normal file
View File

@ -0,0 +1,304 @@
#define CATCH_CONFIG_MAIN
#include <catch.hpp>
#include <iostream>
#include "etcd/Client.hpp"
TEST_CASE("setup")
{
etcd::Client etcd("http://127.0.0.1:2379");
<<<<<<< 12282f826d6973d5bfdb24a44b076a9cdeca21e8
etcd.rmdir("/test", true).wait();
=======
//etcd.rmdir("/test", true).wait();
>>>>>>> Use Txn
}
TEST_CASE("add a new key")
{
<<<<<<< 12282f826d6973d5bfdb24a44b076a9cdeca21e8
=======
>>>>>>> Use Txn
etcd::Client etcd("http://127.0.0.1:2379");
etcd::Response resp = etcd.add("/test/key1", "42").get();
REQUIRE(0 == resp.error_code());
CHECK("create" == resp.action());
etcd::Value const & val = resp.value();
CHECK("42" == val.as_string());
CHECK("/test/key1" == val.key());
CHECK(!val.is_dir());
CHECK(0 < val.created_index());
CHECK(0 < val.modified_index());
CHECK(0 < resp.index()); // X-Etcd-Index header value
CHECK(105 == 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("Key already exists" == etcd.add("/test/key1", "42").get().error_message());
}
TEST_CASE("read a value from etcd")
{
etcd::Client etcd("http://127.0.0.1:2379");
etcd::Response resp = etcd.get("/test/key1").get();
CHECK("get" == resp.action());
REQUIRE(resp.is_ok());
REQUIRE(0 == resp.error_code());
CHECK("42" == resp.value().as_string());
CHECK("" == etcd.get("/test").get().value().as_string()); // key points to a directory
}
TEST_CASE("simplified read")
{
etcd::Client etcd("http://127.0.0.1:2379");
CHECK("42" == etcd.get("/test/key1").get().value().as_string());
CHECK(100 == etcd.get("/test/key2").get().error_code()); // Key not found
}
TEST_CASE("modify a key")
{
etcd::Client etcd("http://127.0.0.1:2379");
etcd::Response resp = etcd.modify("/test/key1", "43").get();
REQUIRE(0 == resp.error_code()); // overwrite
CHECK("update" == resp.action());
CHECK(100 == etcd.modify("/test/key2", "43").get().error_code()); // Key not found
CHECK("43" == etcd.modify("/test/key1", "42").get().prev_value().as_string());
}
TEST_CASE("set a key")
{
etcd::Client etcd("http://127.0.0.1:2379");
etcd::Response resp = etcd.set("/test/key1", "43").get();
REQUIRE(0 == resp.error_code()); // overwrite
CHECK("set" == resp.action());
CHECK(0 == etcd.set("/test/key2", "43").get().error_code()); // create new
CHECK("43" == etcd.set("/test/key2", "44").get().prev_value().as_string());
CHECK("" == etcd.set("/test/key3", "44").get().prev_value().as_string());
CHECK(0 == etcd.set("/test", "42").get().error_code()); // Not a file
}
TEST_CASE("atomic compare-and-swap")
{
etcd::Client etcd("http://127.0.0.1:2379");
etcd.set("/test/key1", "42").wait();
// modify success
etcd::Response res = etcd.modify_if("/test/key1", "43", "42").get();
int index = res.index();
REQUIRE(res.is_ok());
CHECK("compareAndSwap" == res.action());
CHECK("43" == res.value().as_string());
// modify fails the second time
res = etcd.modify_if("/test/key1", "44", "42").get();
CHECK(!res.is_ok());
CHECK(101 == res.error_code());
CHECK("Compare failed" == res.error_message());
}
<<<<<<< 12282f826d6973d5bfdb24a44b076a9cdeca21e8
=======
#if 0
>>>>>>> Use Txn
TEST_CASE("delete a value")
{
etcd::Client etcd("http://127.0.0.1:2379");
etcd::Response resp = etcd.rm("/test/key1").get();
CHECK("43" == resp.prev_value().as_string());
CHECK("delete" == resp.action());
}
TEST_CASE("atomic compare-and-delete based on prevValue")
{
etcd::Client etcd("http://127.0.0.1:2379");
etcd.set("/test/key1", "42").wait();
etcd::Response res = etcd.rm_if("/test/key1", "43").get();
CHECK(!res.is_ok());
CHECK(101 == res.error_code());
CHECK("Compare failed" == res.error_message());
res = etcd.rm_if("/test/key1", "42").get();
REQUIRE(res.is_ok());
CHECK("compareAndDelete" == res.action());
CHECK("42" == res.prev_value().as_string());
}
TEST_CASE("atomic compare-and-delete based on prevIndex")
{
etcd::Client etcd("http://127.0.0.1:2379");
int index = etcd.set("/test/key1", "42").get().index();
etcd::Response res = etcd.rm_if("/test/key1", index - 1).get();
CHECK(!res.is_ok());
CHECK(101 == res.error_code());
CHECK("Compare failed" == res.error_message());
res = etcd.rm_if("/test/key1", index).get();
REQUIRE(res.is_ok());
CHECK("compareAndDelete" == res.action());
CHECK("42" == res.prev_value().as_string());
}
TEST_CASE("deep atomic compare-and-swap")
{
etcd::Client etcd("http://127.0.0.1:2379");
etcd.set("/test/key1", "42").wait();
// modify success
etcd::Response res = etcd.modify_if("/test/key1", "43", "42").get();
int index = res.index();
REQUIRE(res.is_ok());
CHECK("compareAndSwap" == res.action());
CHECK("43" == res.value().as_string());
// modify fails the second time
res = etcd.modify_if("/test/key1", "44", "42").get();
CHECK(!res.is_ok());
CHECK(101 == res.error_code());
CHECK("Compare failed" == res.error_message());
// succes with the correct index
res = etcd.modify_if("/test/key1", "44", index).get();
REQUIRE(res.is_ok());
CHECK("compareAndSwap" == res.action());
CHECK("44" == res.value().as_string());
// index changes so second modify fails
res = etcd.modify_if("/test/key1", "45", index).get();
CHECK(!res.is_ok());
CHECK(101 == res.error_code());
CHECK("Compare failed" == res.error_message());
}
//skip this test case
/*
TEST_CASE("create a directory")
{
etcd::Client etcd("http://127.0.0.1:4001");
etcd::Response resp = etcd.mkdir("/test/new_dir").get();
CHECK("set" == resp.action());
CHECK(resp.value().is_dir());
}
*/
TEST_CASE("list a directory")
{
etcd::Client etcd("http://127.0.0.1:2379");
CHECK(0 == etcd.ls("/test/new_dir").get().keys().size());
etcd.set("/test/new_dir/key1", "value1").wait();
etcd.set("/test/new_dir/key2", "value2").wait();
etcd.set("/test/new_dir/sub_dir", "value3").wait();
etcd::Response resp = etcd.ls("/test/new_dir").get();
CHECK("get" == resp.action());
REQUIRE(3 == resp.keys().size());
CHECK("/test/new_dir/key1" == resp.key(0));
CHECK("/test/new_dir/key2" == resp.key(1));
CHECK("/test/new_dir/sub_dir" == resp.key(2));
CHECK("value1" == resp.value(0).as_string());
CHECK("value2" == resp.value(1).as_string());
CHECK(resp.values()[2].is_dir() == 0);
CHECK(0 == etcd.ls("/test/new_dir/key1").get().error_code());
}
TEST_CASE("delete a directory")
{
etcd::Client etcd("http://127.0.0.1:2379");
//CHECK(108 == etcd.rmdir("/test/new_dir").get().error_code()); // Directory not empty
CHECK(0 == etcd.rmdir("/test/new_dir", true).get().error_code());
}
TEST_CASE("wait for a value change")
{
etcd::Client etcd("http://127.0.0.1:2379");
etcd.set("/test/key1", "42").wait();
pplx::task<etcd::Response> res = etcd.watch("/test/key1");
CHECK(!res.is_done());
sleep(1);
CHECK(!res.is_done());
etcd.set("/test/key1", "43").get();
sleep(1);
REQUIRE(res.is_done());
REQUIRE("set" == res.get().action());
CHECK("43" == res.get().value().as_string());
}
TEST_CASE("wait for a directory change")
{
etcd::Client etcd("http://127.0.0.1:2379");
pplx::task<etcd::Response> res = etcd.watch("/test", true);
CHECK(!res.is_done());
sleep(1);
CHECK(!res.is_done());
etcd.add("/test/key4", "44").wait();
sleep(1);
REQUIRE(res.is_done());
CHECK("create" == res.get().action());
CHECK("44" == res.get().value().as_string());
pplx::task<etcd::Response> res2 = etcd.watch("/test", true);
CHECK(!res2.is_done());
sleep(1);
CHECK(!res2.is_done());
etcd.set("/test/key4", "45").wait();
sleep(1);
REQUIRE(res2.is_done());
CHECK("set" == res2.get().action());
CHECK("45" == res2.get().value().as_string());
}
TEST_CASE("watch changes in the past")
{
etcd::Client etcd("http://127.0.0.1:2379");
int index = etcd.set("/test/key1", "42").get().index();
etcd.set("/test/key1", "43").wait();
etcd.set("/test/key1", "44").wait();
etcd.set("/test/key1", "45").wait();
etcd::Response res = etcd.watch("/test/key1", ++index).get();
CHECK("set" == res.action());
CHECK("43" == res.value().as_string());
res = etcd.watch("/test/key1", ++index).get();
CHECK("set" == res.action());
CHECK("44" == res.value().as_string());
res = etcd.watch("/test", ++index, true).get();
CHECK("set" == res.action());
CHECK("45" == res.value().as_string());
}
TEST_CASE("cleanup")
{
etcd::Client etcd("http://127.0.0.1:2379");
REQUIRE(0 == etcd.rmdir("/test", true).get().error_code());
}

View File

@ -0,0 +1,36 @@
#ifndef __ASYNC_RANGERESPONSE_HPP__
#define __ASYNC_RANGERESPONSE_HPP__
#include <grpc++/grpc++.h>
#include "proto/rpc.grpc.pb.h"
#include "v3/include/V3Response.hpp"
using grpc::ClientAsyncResponseReader;
using grpc::ClientContext;
using grpc::CompletionQueue;
using grpc::Status;
using etcdserverpb::RangeResponse;
namespace etcdv3
{
class AsyncRangeResponse : public etcdv3::V3Response
{
public:
AsyncRangeResponse(){action = "get";};
AsyncRangeResponse(const AsyncRangeResponse& other);
AsyncRangeResponse& operator=(const AsyncRangeResponse& other);
AsyncRangeResponse& ParseResponse();
void waitForResponse();
RangeResponse reply;
Status status;
ClientContext context;
CompletionQueue cq_;
std::unique_ptr<ClientAsyncResponseReader<RangeResponse>> response_reader;
<<<<<<< a592ce75a199b4e275a50c5f29992aa7dc0ff8d1
=======
AsyncRangeResponse& ParseResponse();
>>>>>>> Added delete
};
}
#endif

View File

@ -0,0 +1,46 @@
#ifndef __ASYNC_TXNRESPONSE_HPP__
#define __ASYNC_TXNRESPONSE_HPP__
#include <grpc++/grpc++.h>
#include "proto/rpc.grpc.pb.h"
#include "v3/include/V3Response.hpp"
<<<<<<< 0cb5bd762aca24c5a8d9e959c5f72590d85ad2b4
=======
#include "v3/include/grpcClient.hpp"
>>>>>>> Use Txn for add()
using grpc::ClientAsyncResponseReader;
using grpc::ClientContext;
using grpc::CompletionQueue;
using grpc::Status;
using etcdserverpb::TxnResponse;
namespace etcdv3
{
class AsyncTxnResponse : public etcdv3::V3Response
{
public:
AsyncTxnResponse(){};
AsyncTxnResponse(const std::string act){action = act;};
AsyncTxnResponse(const AsyncTxnResponse& other);
AsyncTxnResponse& operator=(const AsyncTxnResponse& other);
<<<<<<< 0cb5bd762aca24c5a8d9e959c5f72590d85ad2b4
AsyncTxnResponse& ParseResponse();
void waitForResponse();
=======
>>>>>>> Use Txn for add()
TxnResponse reply;
Status status;
ClientContext context;
CompletionQueue cq_;
std::unique_ptr<ClientAsyncResponseReader<TxnResponse>> response_reader;
<<<<<<< 0cb5bd762aca24c5a8d9e959c5f72590d85ad2b4
=======
AsyncTxnResponse& ParseResponse();
>>>>>>> Use Txn for add()
};
}
#endif

View File

@ -0,0 +1,49 @@
#include "v3/include/AsyncPutResponse.hpp"
#include "v3/include/Utils.hpp"
#include <iostream>
using etcdserverpb::PutRequest;
using etcdserverpb::PutRequest;
etcdv3::AsyncPutResponse::AsyncPutResponse(const etcdv3::AsyncPutResponse& other)
{
error_code = other.error_code;
error_message = other.error_message;
index = other.index;
action = other.action;
values = other.values;
prev_value.set_key(other.prev_value.key());
prev_value.set_value(other.prev_value.value());
prev_value.set_create_revision(other.prev_value.create_revision());
prev_value.set_mod_revision(other.prev_value.mod_revision());
}
etcdv3::AsyncPutResponse& etcdv3::AsyncPutResponse::operator=(const etcdv3::AsyncPutResponse& other)
{
error_code = other.error_code;
error_message = other.error_message;
index = other.index;
action = other.action;
values = other.values;
prev_value.set_key(other.prev_value.key());
prev_value.set_value(other.prev_value.value());
prev_value.set_create_revision(other.prev_value.create_revision());
prev_value.set_mod_revision(other.prev_value.mod_revision());
return *this;
}
etcdv3::AsyncPutResponse& etcdv3::AsyncPutResponse::ParseResponse()
{
etcdv3::AsyncRangeResponse* resp = etcdv3::Utils::getKey(key, *client);
if(resp->reply.kvs_size())
{
values.push_back(resp->reply.kvs(0));
index = resp->reply.kvs(0).create_revision();
}
else
index = resp->reply.header().revision();
return *this;
}

View File

@ -0,0 +1,75 @@
#include "v3/include/AsyncRangeResponse.hpp"
etcdv3::AsyncRangeResponse::AsyncRangeResponse(const etcdv3::AsyncRangeResponse& other)
{
error_code = other.error_code;
error_message = other.error_message;
index = other.index;
action = other.action;
values = other.values;
prev_values = other.prev_values;
}
etcdv3::AsyncRangeResponse& etcdv3::AsyncRangeResponse::operator=(const etcdv3::AsyncRangeResponse& other)
{
error_code = other.error_code;
error_message = other.error_message;
index = other.index;
action = other.action;
values = other.values;
prev_values = other.prev_values;
return *this;
}
void etcdv3::AsyncRangeResponse::waitForResponse()
{
void* got_tag;
bool ok = false;
cq_.Next(&got_tag, &ok);
GPR_ASSERT(got_tag == (void*)this);
}
etcdv3::AsyncRangeResponse& etcdv3::AsyncRangeResponse::ParseResponse()
{
index = reply.header().revision();
if(!status.ok())
{
error_code = status.error_code();
error_message = status.error_message();
}
else
{
<<<<<<< a592ce75a199b4e275a50c5f29992aa7dc0ff8d1
=======
if(reply.kvs_size() == 0)
{
error_code=100;
error_message="Key not found";
}
for(int index=0; index < reply.kvs_size(); index++)
{
std::cout << "key: " << reply.kvs(index).key() << std::endl;
std::cout << "value: " << reply.kvs(index).value()<< std::endl;
values.push_back(reply.kvs(index));
}
}
>>>>>>> Added delete
if(reply.kvs_size() == 0)
{
error_code=100;
error_message="Key not found";
}
for(int index=0; index < reply.kvs_size(); index++)
{
values.push_back(reply.kvs(index));
}
}
index = reply.header().revision();
return *this;
}

View File

@ -0,0 +1,153 @@
#include "v3/include/AsyncTxnResponse.hpp"
#include "v3/include/AsyncRangeResponse.hpp"
using etcdserverpb::ResponseOp;
etcdv3::AsyncTxnResponse::AsyncTxnResponse(const etcdv3::AsyncTxnResponse& other)
{
error_code = other.error_code;
error_message = other.error_message;
index = other.index;
action = other.action;
values = other.values;
prev_values = other.prev_values;
}
etcdv3::AsyncTxnResponse& etcdv3::AsyncTxnResponse::operator=(const etcdv3::AsyncTxnResponse& other)
{
error_code = other.error_code;
error_message = other.error_message;
index = other.index;
action = other.action;
values = other.values;
prev_values = other.prev_values;
return *this;
}
void etcdv3::AsyncTxnResponse::waitForResponse()
{
void* got_tag;
bool ok = false;
cq_.Next(&got_tag, &ok);
GPR_ASSERT(got_tag == (void*)this);
}
etcdv3::AsyncTxnResponse& etcdv3::AsyncTxnResponse::ParseResponse()
{
index = reply.header().revision();
if(!status.ok())
if(reply.succeeded())
error_code = status.error_code();
error_message = status.error_message();
}
else
{
std::vector<mvccpb::KeyValue> range_kvs;
std::vector<mvccpb::KeyValue> prev_range_kvs;
for(int index=0; index < reply.responses_size(); index++)
{
auto resp = reply.responses(index);
if(ResponseOp::ResponseCase::kResponseRange == resp.response_case())
{
AsyncRangeResponse response;
response.reply = resp.response_range();
auto v3resp = response.ParseResponse();
error_code = v3resp.error_code;
error_message = v3resp.error_message;
if(!v3resp.values.empty())
{
prev_range_kvs=range_kvs;
range_kvs = v3resp.values;
<<<<<<< 4adff1a7552b34d6c98def525fa38351e37bf47d
}
=======
}
}
>>>>>>> made prev_values a vector.
else if(ResponseOp::ResponseCase::kResponseDeleteRange == resp.response_case())
{
//do nothing yet
}
if(!reply.succeeded())
{
if(action == "create")
{
error_code=105;
error_message="Key already exists";
}
else if(action == "compareAndSwap" || action == "compareAndDelete")
{
if(!error_code)
{
error_code=101;
error_message="Compare failed";
}
}
prev_values = prev_range_kvs;
values = range_kvs;
error_message = v3resp.error_message;
if(action == "delete" || action == "compareAndDelete")
range_kvs.insert(range_kvs.end(), v3resp.values.begin(), v3resp.values.end());
}
}
}
if(!reply.succeeded())
{
prev_values = values;
{
}
else if(action == "compareAndSwap")
{
error_code=101;
error_message="Compare failed";
}
}
<<<<<<< 4adff1a7552b34d6c98def525fa38351e37bf47d
//find previous value of key
//retain only the last value gotten as the final value.
if(action == "set" || action == "create" || action == "compareAndSwap" || action == "update")
{
if(range_kvs.size() > 1)
{
prev_value = range_kvs.front();
values.push_back(range_kvs.back());
}
else
{
values = range_kvs;
}
}
else
{
values = range_kvs;
}
}
=======
prev_values = prev_range_kvs;
values = range_kvs;
if(action == "delete")
{
prev_values = values;
}
}
>>>>>>> made prev_values a vector.
return *this;
}