#ifndef __ETCD_CLIENT_HPP__ #define __ETCD_CLIENT_HPP__ #include "etcd/Response.hpp" #include #include "proto/rpc.grpc.pb.h" #include "proto/v3lock.grpc.pb.h" #include using etcdserverpb::Auth; using etcdserverpb::KV; using etcdserverpb::Lease; using etcdserverpb::Watch; using v3lockpb::Lock; namespace etcdv3 { class Transaction; } namespace etcd { class Watcher; /** * 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:2379", or multiple url, seperated by ',' or ';'. * @param load_balancer is the load balance strategy, can be one of * round_robin/pick_first/grpclb/xds. */ Client(std::string const &etcd_url, std::string const &load_balancer = "round_robin"); /** * Constructs an etcd client object. * * @param etcd_url is the url of the etcd server to connect to, like * "http://127.0.0.1:2379", or multiple url, seperated by ',' or ';'. * @param username username of etcd auth * @param password password of etcd auth * @param load_balancer is the load balance strategy, can be one of * round_robin/pick_first/grpclb/xds. */ Client(std::string const &etcd_url, std::string const &username, std::string const &password, std::string const &load_balancer = "round_robin"); /** * Sends a get request to the etcd server * @param key is the key to be read */ pplx::task 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 set(std::string const &key, std::string const &value, int ttl = 0); /** * 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 * @param leaseId is the lease attached to the key */ pplx::task set(std::string const &key, std::string const &value, int64_t leaseId); /** * 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 add(std::string const &key, std::string const &value, int ttl = 0); /** * 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 * @param leaseId is the lease attached to the key */ pplx::task add(std::string const &key, std::string const &value, int64_t leaseId); /** * 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 modify(std::string const &key, std::string const &value, int ttl = 0); /** * 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 * @param leaseId is the lease attached to the key */ pplx::task modify(std::string const &key, std::string const &value, int64_t leaseId); /** * 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 modify_if(std::string const &key, std::string const &value, std::string const &old_value, int ttl = 0); /** * 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 * @param leaseId is the lease attached to the key */ pplx::task modify_if(std::string const &key, std::string const &value, std::string const &old_value, int64_t leaseId); /** * 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 modify_if(std::string const &key, std::string const &value, int old_index, int ttl = 0); /** * 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 * @param leaseId is the lease attached to the key */ pplx::task modify_if(std::string const &key, std::string const &value, int old_index, int64_t leaseId); /** * 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 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 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 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 ls(std::string const &key); /** * Gets a directory listing of the directory identified by the key. * @param key is the key to be listed * @param limit is the size limit of results to be listed, we don't use * default parameters to ensure backwards binary compatibility. */ pplx::task ls(std::string const &key, size_t const limit); /** * 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 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 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 watch(std::string const &key, int fromIndex, bool recursive = false); /** * Grants a lease. * @param ttl is the time to live of the lease (in seconds) */ pplx::task leasegrant(int ttl); /** * Gets the list of existing leases */ pplx::task listleases(); /** * Renews a lease. * @param lease_id is the id of of the lease */ pplx::task leasekeepalive(int64_t lease_id); /** * Revokes a lease. * @param lease_id is the id of of the lease */ pplx::task leaserevoke(int64_t lease_id); /** * Gets the TTL of an existing lease * @param lease_id is the id of of the lease */ pplx::task leasettl(int64_t lease_id, bool keys); /** * Gains a lock at a key. * @param key is the key to be used to request the lock. */ pplx::task lock(std::string const &key); /** * Releases a lock at a key. * @param key is the lock key to release. */ pplx::task unlock(std::string const &key); /** * Execute a etcd transaction. * @param txn is the transaction object to be executed. */ pplx::task txn(etcdv3::Transaction const &txn); private: std::shared_ptr channel; std::string auth_token; std::unique_ptr kvServiceStub; std::unique_ptr watchServiceStub; std::unique_ptr leaseServiceStub; std::unique_ptr lockServiceStub; friend class Watcher; friend class KeepAlive; }; } // namespace etcd #endif