From fe5396e437c125b3b10cc30047075aee4f768768 Mon Sep 17 00:00:00 2001 From: lampayan Date: Tue, 21 Jun 2016 15:33:11 +0200 Subject: [PATCH] Refactored Client class to remove boilerplate code. Responsibility of boilerplate work is transfered to its own class (Transaction). UT for watch are temporarily commented out as they are not supported yet --- src/CMakeLists.txt | 2 +- src/Client.cpp | 350 ++++++------------------------------- tst/EtcdTest.cpp | 130 +++++++------- v3/include/Transaction.hpp | 43 +++++ v3/src/Transaction.cpp | 178 +++++++++++++++++++ 5 files changed, 342 insertions(+), 361 deletions(-) create mode 100644 v3/include/Transaction.hpp create mode 100644 v3/src/Transaction.cpp diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 08ade3f..45966fd 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,4 +1,4 @@ -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/Utils.cpp ../v3/src/grpcClient.cpp ../v3/src/AsyncTxnResponse.cpp ../v3/src/AsyncRangeResponse.cpp ../v3/src/AsyncPutResponse.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/Utils.cpp ../v3/src/grpcClient.cpp ../v3/src/AsyncTxnResponse.cpp ../v3/src/AsyncRangeResponse.cpp ../v3/src/AsyncPutResponse.cpp ../v3/src/Transaction.cpp Client.cpp Response.cpp Value.cpp json_constants.cpp) set_property(TARGET etcd-cpp-api PROPERTY CXX_STANDARD 11) target_link_libraries(etcd-cpp-api ${CPPREST_LIB} boost_system ssl crypto protobuf grpc++) diff --git a/src/Client.cpp b/src/Client.cpp index 5bcc0ea..0f6eded 100644 --- a/src/Client.cpp +++ b/src/Client.cpp @@ -3,6 +3,7 @@ #include "v3/include/AsyncTxnResponse.hpp" #include "v3/include/AsyncRangeResponse.hpp" #include "v3/include/Utils.hpp" +#include "v3/include/Transaction.hpp" #include using grpc::Channel; @@ -139,84 +140,33 @@ pplx::task etcd::Client::watch(std::string const & key, int from pplx::task 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); - //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); + transaction.setup_basic_failure_operation(key); + transaction.setup_basic_create_sequence(key, value); - //get key on failure - std::unique_ptr get_request(new RangeRequest()); - get_request->set_key(key); - RequestOp* req_failure = txn_request.add_failure(); - req_failure->set_allocated_request_range(get_request.release()); - - - //if success, add key and then get new value of key - std::unique_ptr put_request(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 call(new etcdv3::AsyncTxnResponse("create")); - - call->response_reader = stub_->AsyncTxn(&call->context,txn_request,&call->cq_); - + //to be done in one method, where txn_request is a field of a class + std::shared_ptr call(new etcdv3::AsyncTxnResponse("create")); + call->response_reader = stub_->AsyncTxn(&call->context,transaction.txn_request,&call->cq_); call->response_reader->Finish(&call->reply, &call->status, (void*)call.get()); return Response::create(call); - } pplx::task etcd::Client::send_asyncmodify_if(std::string const & key, std::string const & value, std::string const & old_value) { - //check key value is equal to old_value - TxnRequest txn_request; - Compare* compare = txn_request.add_compare(); - compare->set_result(Compare::CompareResult::Compare_CompareResult_EQUAL); - compare->set_target(Compare::CompareTarget::Compare_CompareTarget_VALUE); - compare->set_key(key); - compare->set_value(old_value); + etcdv3::Transaction transaction(key); + transaction.init_compare(old_value, Compare::CompareResult::Compare_CompareResult_EQUAL, + Compare::CompareTarget::Compare_CompareTarget_VALUE); - //get key on failure - std::unique_ptr get_request(new RangeRequest()); - get_request->set_key(key); - RequestOp* req_failure = txn_request.add_failure(); - req_failure->set_allocated_request_range(get_request.release()); - - //on success get key value then modify and get new value - get_request.reset(new RangeRequest()); - get_request->set_key(key); - RequestOp* req_success = txn_request.add_success(); - req_success->set_allocated_request_range(get_request.release()); - - std::unique_ptr put_request(new PutRequest()); - put_request->set_key(key); - put_request->set_value(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()); + transaction.setup_basic_failure_operation(key); + transaction.setup_compare_and_swap_sequence(value); std::shared_ptr call(new etcdv3::AsyncTxnResponse("compareAndSwap")); - - call->response_reader = stub_->AsyncTxn(&call->context,txn_request,&call->cq_); - + call->response_reader = stub_->AsyncTxn(&call->context,transaction.txn_request,&call->cq_); call->response_reader->Finish(&call->reply, &call->status, (void*)call.get()); return Response::create(call); @@ -224,41 +174,15 @@ pplx::task etcd::Client::send_asyncmodify_if(std::string const & pplx::task etcd::Client::send_asyncmodify_if(std::string const & key, std::string const & value, int old_index) { - //check key value is equal to old_value - TxnRequest txn_request; - Compare* compare = txn_request.add_compare(); - compare->set_result(Compare::CompareResult::Compare_CompareResult_EQUAL); - compare->set_target(Compare::CompareTarget::Compare_CompareTarget_MOD); - compare->set_key(key); - compare->set_mod_revision(old_index); + etcdv3::Transaction transaction(key); + transaction.init_compare(old_index, Compare::CompareResult::Compare_CompareResult_EQUAL, + Compare::CompareTarget::Compare_CompareTarget_MOD); - //get key on failure - std::unique_ptr get_request(new RangeRequest()); - get_request->set_key(key); - RequestOp* req_failure = txn_request.add_failure(); - req_failure->set_allocated_request_range(get_request.release()); - - //on success get key value then modify and get new value - get_request.reset(new RangeRequest()); - get_request->set_key(key); - RequestOp* req_success = txn_request.add_success(); - req_success->set_allocated_request_range(get_request.release()); - - std::unique_ptr put_request(new PutRequest()); - put_request->set_key(key); - put_request->set_value(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()); + transaction.setup_basic_failure_operation(key); + transaction.setup_compare_and_swap_sequence(value); std::shared_ptr call(new etcdv3::AsyncTxnResponse("compareAndSwap")); - - call->response_reader = stub_->AsyncTxn(&call->context,txn_request,&call->cq_); - + call->response_reader = stub_->AsyncTxn(&call->context,transaction.txn_request,&call->cq_); call->response_reader->Finish(&call->reply, &call->status, (void*)call.get()); return Response::create(call); @@ -267,44 +191,15 @@ pplx::task etcd::Client::send_asyncmodify_if(std::string const & pplx::task etcd::Client::send_asyncmodify(std::string const & key, std::string const & value) { - //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); + etcdv3::Transaction transaction(key); + transaction.init_compare(Compare::CompareResult::Compare_CompareResult_GREATER, + Compare::CompareTarget::Compare_CompareTarget_VERSION); - //success or failure - //get key value before modification - std::unique_ptr get_request(new RangeRequest()); - get_request->set_key(key); - RequestOp* req_failure = txn_request.add_failure(); - req_failure->set_allocated_request_range(get_request.release()); - - get_request.reset(new RangeRequest()); - get_request->set_key(key); - RequestOp* req_success = txn_request.add_success(); - req_success->set_allocated_request_range(get_request.release()); - - //if success, modify key and then get new value of key - std::unique_ptr put_request(new PutRequest()); - put_request->set_key(key); - put_request->set_value(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()); + transaction.setup_basic_failure_operation(key); + transaction.setup_compare_and_swap_sequence(value); - std::shared_ptr call(new etcdv3::AsyncTxnResponse("update")); - - call->response_reader = stub_->AsyncTxn(&call->context,txn_request,&call->cq_); - + call->response_reader = stub_->AsyncTxn(&call->context,transaction.txn_request,&call->cq_); call->response_reader->Finish(&call->reply, &call->status, (void*)call.get()); return Response::create(call); @@ -323,9 +218,7 @@ pplx::task etcd::Client::send_asyncget(std::string const & key, } std::shared_ptr 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()); return Response::create(call); @@ -334,48 +227,15 @@ pplx::task etcd::Client::send_asyncget(std::string const & key, pplx::task etcd::Client::send_asyncput(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); + etcdv3::Transaction transaction(key); + transaction.init_compare(Compare::CompareResult::Compare_CompareResult_EQUAL, + Compare::CompareTarget::Compare_CompareTarget_VERSION); - - //get key on failure, get key before put, modify and then get updated key - std::unique_ptr get_request(new RangeRequest()); - get_request->set_key(key); - RequestOp* req_failure = txn_request.add_failure(); - req_failure->set_allocated_request_range(get_request.release()); - - std::unique_ptr put_request(new PutRequest()); - put_request->set_key(key); - put_request->set_value(value); - req_failure = txn_request.add_failure(); - req_failure->set_allocated_request_put(put_request.release()); - - get_request.reset(new RangeRequest()); - get_request->set_key(key); - req_failure = txn_request.add_failure(); - req_failure->set_allocated_request_range(get_request.release()); - - //if success, put key and then get new value of key - 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()); + transaction.setup_set_failure_operation(key, value); + transaction.setup_basic_create_sequence(key, value); std::shared_ptr call(new etcdv3::AsyncTxnResponse("set")); - - call->response_reader = stub_->AsyncTxn(&call->context,txn_request,&call->cq_); - + call->response_reader = stub_->AsyncTxn(&call->context,transaction.txn_request,&call->cq_); call->response_reader->Finish(&call->reply, &call->status, (void*)call.get()); return Response::create(call); @@ -383,14 +243,9 @@ pplx::task etcd::Client::send_asyncput(std::string const & key, pplx::task 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); + etcdv3::Transaction transaction(key); + transaction.init_compare(Compare::CompareResult::Compare_CompareResult_GREATER, + Compare::CompareTarget::Compare_CompareTarget_VERSION); std::string range_end(key); if(recursive) @@ -399,57 +254,11 @@ pplx::task etcd::Client::send_asyncdelete(std::string const & ke range_end.back() = ascii+1; } - //if success, get key, delete - std::unique_ptr 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 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 fail, 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()); - + transaction.setup_delete_sequence(key, range_end, recursive); + transaction.setup_delete_failure_operation(key, range_end, recursive); std::shared_ptr call(new etcdv3::AsyncTxnResponse("delete")); - - call->response_reader = stub_->AsyncTxn(&call->context,txn_request,&call->cq_); - + call->response_reader = stub_->AsyncTxn(&call->context,transaction.txn_request,&call->cq_); call->response_reader->Finish(&call->reply, &call->status, (void*)call.get()); return Response::create(call); @@ -457,82 +266,33 @@ pplx::task etcd::Client::send_asyncdelete(std::string const & ke pplx::task 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); - //check if key's value is equl to oldvalue - TxnRequest txn_request; - Compare* compare = txn_request.add_compare(); - compare->set_result(Compare::CompareResult::Compare_CompareResult_EQUAL); - compare->set_target(Compare::CompareTarget::Compare_CompareTarget_VALUE); - compare->set_key(key); - compare->set_value(old_value); - - - //if success, get key, delete - std::unique_ptr get_request(new RangeRequest()); - get_request->set_key(key); - RequestOp* req_success = txn_request.add_success(); - req_success->set_allocated_request_range(get_request.release()); - - std::unique_ptr del_request(new DeleteRangeRequest()); - del_request->set_key(key); - req_success = txn_request.add_success(); - req_success->set_allocated_request_delete_range(del_request.release()); - - - //if fail, get key - get_request.reset(new RangeRequest()); - get_request->set_key(key); - RequestOp* req_failure = txn_request.add_failure(); - req_failure->set_allocated_request_range(get_request.release()); - + transaction.setup_compare_and_delete_operation(key); + transaction.setup_basic_failure_operation(key); std::shared_ptr call(new etcdv3::AsyncTxnResponse("compareAndDelete")); - - call->response_reader = stub_->AsyncTxn(&call->context,txn_request,&call->cq_); - + call->response_reader = stub_->AsyncTxn(&call->context,transaction.txn_request,&call->cq_); call->response_reader->Finish(&call->reply, &call->status, (void*)call.get()); return Response::create(call); } -pplx::task etcd::Client::send_asyncrm_if(std::string const &key, int old_index) -{ +pplx::task 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); - //check if key's mod revision is equal to old index - TxnRequest txn_request; - Compare* compare = txn_request.add_compare(); - compare->set_result(Compare::CompareResult::Compare_CompareResult_EQUAL); - compare->set_target(Compare::CompareTarget::Compare_CompareTarget_MOD); - compare->set_key(key); - compare->set_mod_revision(old_index); + transaction.setup_compare_and_delete_operation(key); + transaction.setup_basic_failure_operation(key); + std::shared_ptr call(new etcdv3::AsyncTxnResponse("compareAndDelete")); + call->response_reader = stub_->AsyncTxn(&call->context,transaction.txn_request,&call->cq_); + call->response_reader->Finish(&call->reply, &call->status, (void*)call.get()); - //if success, get key, delete - std::unique_ptr get_request(new RangeRequest()); - get_request->set_key(key); - RequestOp* req_success = txn_request.add_success(); - req_success->set_allocated_request_range(get_request.release()); - - std::unique_ptr del_request(new DeleteRangeRequest()); - del_request->set_key(key); - req_success = txn_request.add_success(); - req_success->set_allocated_request_delete_range(del_request.release()); - - - //if fail, get key - get_request.reset(new RangeRequest()); - get_request->set_key(key); - RequestOp* req_failure = txn_request.add_failure(); - req_failure->set_allocated_request_range(get_request.release()); - - - std::shared_ptr call(new etcdv3::AsyncTxnResponse("compareAndDelete")); - - 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); + return Response::create(call); } diff --git a/tst/EtcdTest.cpp b/tst/EtcdTest.cpp index cb2ecc7..93d48b4 100644 --- a/tst/EtcdTest.cpp +++ b/tst/EtcdTest.cpp @@ -213,71 +213,71 @@ TEST_CASE("delete a directory") } -TEST_CASE("wait for a value change") -{ - etcd::Client etcd("http://127.0.0.1:2379"); - etcd.set("/test/key1", "42").wait(); - - pplx::task 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:4001"); - - pplx::task 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 res2 = etcd.watch("/test", true); - CHECK(!res2.is_done()); - sleep(1); - CHECK(!res2.is_done()); - - etcd.set("/test/key4", "45").wait(); - 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:4001"); - - 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("wait for a value change") +//{ +// etcd::Client etcd("http://127.0.0.1:2379"); +// etcd.set("/test/key1", "42").wait(); +// +// pplx::task 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:4001"); +// +// pplx::task 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 res2 = etcd.watch("/test", true); +// CHECK(!res2.is_done()); +// sleep(1); +// CHECK(!res2.is_done()); +// +// etcd.set("/test/key4", "45").wait(); +// 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:4001"); +// +// 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") diff --git a/v3/include/Transaction.hpp b/v3/include/Transaction.hpp new file mode 100644 index 0000000..6c394e3 --- /dev/null +++ b/v3/include/Transaction.hpp @@ -0,0 +1,43 @@ +/* + * Transaction.hpp + * + * Created on: Jun 21, 2016 + * Author: ubuntu + */ + +#ifndef V3_SRC_TRANSACTION_HPP_ +#define V3_SRC_TRANSACTION_HPP_ + +#include +#include "proto/rpc.grpc.pb.h" + +#include + +namespace etcdv3 { + +class Transaction { +public: + Transaction(); + Transaction(std::string const&); + virtual ~Transaction(); + void init_compare(etcdserverpb::Compare::CompareResult, etcdserverpb::Compare::CompareTarget); + void init_compare(std::string const &, etcdserverpb::Compare::CompareResult, etcdserverpb::Compare::CompareTarget); + void init_compare(int, etcdserverpb::Compare::CompareResult, etcdserverpb::Compare::CompareTarget); + + void setup_basic_failure_operation(std::string const &key); + void setup_set_failure_operation(std::string const &key, std::string const &value); + void setup_basic_create_sequence(std::string const &key, std::string const &value); + void setup_compare_and_swap_sequence(std::string const &valueToSwap); + void setup_delete_sequence(std::string const &key, std::string const &range_end, bool recursive); + void setup_delete_failure_operation(std::string const &key, std::string const &range_end, bool recursive); + void setup_compare_and_delete_operation(std::string const& key); + + etcdserverpb::TxnRequest txn_request; + +private: + std::string key; +}; + +} /* namespace etcdv3 */ + +#endif /* V3_SRC_TRANSACTION_HPP_ */ diff --git a/v3/src/Transaction.cpp b/v3/src/Transaction.cpp new file mode 100644 index 0000000..5afc947 --- /dev/null +++ b/v3/src/Transaction.cpp @@ -0,0 +1,178 @@ +/* + * Transaction.cpp + * + * Created on: Jun 21, 2016 + * Author: ubuntu + */ + +#include "v3/include/Transaction.hpp" + +using etcdserverpb::Compare; +using etcdserverpb::RangeRequest; +using etcdserverpb::PutRequest; +using etcdserverpb::RequestOp; +using etcdserverpb::DeleteRangeRequest; + +etcdv3::Transaction::Transaction() { + // TODO Auto-generated constructor stub + +} + +etcdv3::Transaction::Transaction(const std::string& key) : key(key) { + +} + +void etcdv3::Transaction::init_compare(Compare::CompareResult result, Compare::CompareTarget target){ + Compare* compare = txn_request.add_compare(); + compare->set_result(result); + compare->set_target(target); + compare->set_key(key); + + compare->set_version(0); +} + +void etcdv3::Transaction::init_compare(std::string const& old_value, Compare::CompareResult result, Compare::CompareTarget target){ + Compare* compare = txn_request.add_compare(); + compare->set_result(result); + compare->set_target(target); + compare->set_key(key); + + compare->set_value(old_value); +} + +void etcdv3::Transaction::init_compare(int old_index, Compare::CompareResult result, Compare::CompareTarget target){ + Compare* compare = txn_request.add_compare(); + compare->set_result(result); + compare->set_target(target); + compare->set_key(key); + + compare->set_mod_revision(old_index); +} + +void etcdv3::Transaction::setup_basic_failure_operation(std::string const& key) { + std::unique_ptr get_request(new RangeRequest()); //then this can be just a raw pointer + get_request->set_key(key); + RequestOp* req_failure = txn_request.add_failure(); + req_failure->set_allocated_request_range(get_request.release()); //why not get()? +} + +void etcdv3::Transaction::setup_set_failure_operation(std::string const &key, std::string const &value) { + std::unique_ptr get_request(new RangeRequest()); + get_request->set_key(key); + RequestOp* req_failure = txn_request.add_failure(); + req_failure->set_allocated_request_range(get_request.release()); + + std::unique_ptr put_request(new PutRequest()); + put_request->set_key(key); + put_request->set_value(value); + req_failure = txn_request.add_failure(); + req_failure->set_allocated_request_put(put_request.release()); + + get_request.reset(new RangeRequest()); + get_request->set_key(key); + req_failure = txn_request.add_failure(); + req_failure->set_allocated_request_range(get_request.release()); +} + +void etcdv3::Transaction::setup_delete_failure_operation(std::string const &key, std::string const &range_end, bool recursive) { + std::unique_ptr get_request(new RangeRequest()); + std::unique_ptr del_request(new DeleteRangeRequest()); + 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()); +} + +/** + * add key and then get new value of key + */ +void etcdv3::Transaction::setup_basic_create_sequence(std::string const& key, std::string const& value) { + std::unique_ptr get_request(new RangeRequest()); + std::unique_ptr put_request(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->set_key(key); + req_success = txn_request.add_success(); + req_success->set_allocated_request_range(get_request.release()); +} + +/** + * get key value then modify and get new value + */ +void etcdv3::Transaction::setup_compare_and_swap_sequence(std::string const& value) { + std::unique_ptr get_request(new RangeRequest()); + get_request.reset(new RangeRequest()); + get_request->set_key(key); + RequestOp* req_success = txn_request.add_success(); + req_success->set_allocated_request_range(get_request.release()); + + std::unique_ptr put_request(new PutRequest()); + put_request->set_key(key); + put_request->set_value(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()); +} + +void etcdv3::Transaction::setup_delete_sequence(std::string const &key, std::string const &range_end, bool recursive) { + std::unique_ptr 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 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()); +} + +void etcdv3::Transaction::setup_compare_and_delete_operation(std::string const& key) { + std::unique_ptr get_request(new RangeRequest()); + get_request->set_key(key); + RequestOp* req_success = txn_request.add_success(); + req_success->set_allocated_request_range(get_request.release()); + + std::unique_ptr del_request(new DeleteRangeRequest()); + del_request->set_key(key); + req_success = txn_request.add_success(); + req_success->set_allocated_request_delete_range(del_request.release()); +} + + +etcdv3::Transaction::~Transaction() { + // TODO Auto-generated destructor stub +}