Giter Club home page Giter Club logo

conservator's Introduction

Overview

Conservator is a Zookeeper Client library written in C++. It's not a direct port of Apache Curator but tries to mirror the simplicity and fluent nature of the CuratorFramework API.

Installing

Instructions for installing with a fresh trusty64 instance

sudo apt-get install ant
sudo apt-get install openjdk-7-jdk

Follow instructions for installing the Zookeeper C Bindings. https://zookeeper.apache.org/doc/r3.4.6/zookeeperProgrammers.html#C+Binding

ant compile_jute
cd src/c
sudo apt-get install autoconf
sudo apt-get install libcppunit-dev
sudo apt-get install libtool
autoreconf -if
./configure
make; make install

This will install the zookeeper libraries into /usr/local/lib

vagrant@vagrant-ubuntu-trusty-64:~/zookeeper-3.4.6/src/c$ ls /usr/local/lib/ | grep zoo
libzookeeper_mt.a
libzookeeper_mt.la
libzookeeper_mt.so
libzookeeper_mt.so.2
libzookeeper_mt.so.2.0.0
libzookeeper_st.a
libzookeeper_st.la
libzookeeper_st.so
libzookeeper_st.so.2
libzookeeper_st.so.2.0.0
sudo apt-get install check
  • Install the latest version of CMake

Building

To build simply cd into conservator run cmake . and make and libconservator-framework.a will be installed in the build directory.

rjenkins@rjenkins-VirtualBox:~/conservator$ cmake .
-- Configuring done
-- Generating done
-- Build files have been written to: /home/rjenkins/conservator
rjenkins@rjenkins-VirtualBox:~/conservator$ make
[  9%] Building CXX object CMakeFiles/conservator-framework.dir/conservator-framework/src/ConservatorFramework.cpp.o
[ 18%] Building CXX object CMakeFiles/conservator-framework.dir/conservator-framework/src/ConservatorFrameworkFactory.cpp.o
[ 27%] Building CXX object CMakeFiles/conservator-framework.dir/conservator-framework/src/GetDataBuilderImpl.cpp.o
[ 36%] Building CXX object CMakeFiles/conservator-framework.dir/conservator-framework/src/ExistsBuilderImpl.cpp.o
[ 45%] Building CXX object CMakeFiles/conservator-framework.dir/conservator-framework/src/CreateBuilderImpl.cpp.o
[ 54%] Building CXX object CMakeFiles/conservator-framework.dir/conservator-framework/src/DeleteBuilderImpl.cpp.o
[ 63%] Building CXX object CMakeFiles/conservator-framework.dir/conservator-framework/src/SetDataBuilderImpl.cpp.o
[ 72%] Building CXX object CMakeFiles/conservator-framework.dir/conservator-framework/src/GetChildrenBuilderImpl.cpp.o
[ 81%] Building CXX object CMakeFiles/conservator-framework.dir/conservator-framework/src/GetACLBuilderImpl.cpp.o
[ 90%] Building CXX object CMakeFiles/conservator-framework.dir/conservator-framework/src/SetACLBuilderImpl.cpp.o
Linking CXX static library build/libconservator-framework.a
[ 90%] Built target conservator-framework
[100%] Building CXX object conservator-framework/tests/CMakeFiles/ConservatorFrameworkFactoryTest.dir/ConservatorFrameworkFactoryTest.cpp.o
Linking CXX executable ../../build/ConservatorFrameworkFactoryTest
[100%] Built target ConservatorFrameworkFactoryTest

Testing

In order to run unit tests run make test.

rjenkins@rjenkins-VirtualBox:~/conservator$ make test
Running tests...
Test project /home/rjenkins/conservator
    Start 1: ConservatorFrameworkFactoryTest
1/1 Test #1: ConservatorFrameworkFactoryTest ...   Passed    5.19 sec

100% tests passed, 0 tests failed out of 1

Total Test time (real) =   5.19 sec

Usage and API

To use simply link to the static libconservator-framework.a library.

You can obtain a ConservatorFramework instance by using the ConservatorFrameworkFactory.

ConservatorFrameworkFactory factory = ConservatorFrameworkFactory();
ConservatorFramework framework = factory.newClient("localhost:2181");
framework.start();

Make sure to close the framework when you're done with the framework.close() command.

Once you've obtained a ConservatorFramework instance all of the standard zookeeper related operations are availble from this interface, with optional parameters being added with additional fluent calls.

unique_ptr<GetDataBuilder<string>> getData();
unique_ptr<ExistsBuilder<int>> checkExists();
unique_ptr<CreateBuilder<int>> create();
unique_ptr<DeleteBuilder<int>> deleteNode();
unique_ptr<SetDataBuilder<int>> setData();
unique_ptr<GetChildrenBuilder<string>> getChildren();
unique_ptr<GetACLBuilder<int>> getACL(ACL_vector *vector);
unique_ptr<SetACLBuilder<int>> setACL(ACL_vector *vector);

Below are some examples, if you don't see your use case here be sure to read the unit tests contained with ConservatorFrameworkFactoryTest they are fairly comprehensive and provide example of how to use the entire API.

  • Creating a znode
 ConservatorFrameworkFactory factory = ConservatorFrameworkFactory();
 ConservatorFramework framework = factory.newClient("localhost:2181");
 framework.start();
 int result = framework.create()->forPath("/foo", (char *) "bar");
  • Creating an ephemeral znode
ConservatorFrameworkFactory factory = ConservatorFrameworkFactory();
ConservatorFramework framework = factory.newClient("localhost:2181");
framework.start();
ck_assert_int_eq(ZOK, framework.create()->withFlags(ZOO_EPHEMERAL)->forPath("/foo"));
  • Checking for the existance of a znode
ConservatorFrameworkFactory factory = ConservatorFrameworkFactory();
ConservatorFramework framework = factory.newClient("localhost:2181");
framework.start();
framework.create()->forPath("/foo");
ck_assert_int_eq(ZOK, framework.checkExists()->forPath("/foo"));
  • Getting the contents of a znode
ConservatorFrameworkFactory factory = ConservatorFrameworkFactory();
ConservatorFramework framework = factory.newClient("localhost:2181");
framework.start();
framework.create()->forPath("/foo", (char *) "bar");
ck_assert_str_eq("bar", framework.getData()->forPath("/foo").c_str());
  • Getting a znode and setting a watch
void get_watcher_fn(zhandle_t *zh, int type,
                       int state, const char *path,void *watcherCtx) {
    cout << "get watcher function called" << endl;
    get_watcher_called++;
    // reset the watch
    ConservatorFramework* framework = (ConservatorFramework *) watcherCtx;
    if(framework->checkExists()->forPath(path)) {
        framework->getData()->withWatcher(get_watcher_fn, framework)->forPath(path);
    }
}

START_TEST(framework_getdata_with_watch) {
    ConservatorFrameworkFactory factory = ConservatorFrameworkFactory();
    ConservatorFramework framework = factory.newClient("localhost:2181");
    framework.start();
    framework.create()->forPath("/foo", (char *) "bar");
    string r = framework.getData()->withWatcher(get_watcher_fn, ((void *) &framework))->forPath("/foo");
    ck_assert_str_eq("bar", r.c_str());
    framework.setData()->forPath("/foo", (char *) "bar");
    ck_assert_int_eq(1, get_watcher_called);
}
END_TEST
  • Setting a znode and setting a znode while checking for version modifications
START_TEST(framework_setdata) {
    ConservatorFrameworkFactory factory = ConservatorFrameworkFactory();
    ConservatorFramework framework = factory.newClient("localhost:2181");
    framework.start();
    framework.create()->forPath("/foo", (char *) "bar");
    ck_assert_int_eq(ZOK, framework.setData()->forPath("/foo", (char *) "moo"));
    ck_assert_str_eq("moo", framework.get("/foo").c_str());
}
END_TEST

START_TEST(framework_setdata_version) {
    ConservatorFrameworkFactory factory = ConservatorFrameworkFactory();
    ConservatorFramework framework = factory.newClient("localhost:2181");
    framework.start();
    framework.create()->forPath("/foo");
    struct Stat stat;
    framework.getData()->storingStatIn(&stat)->forPath("/foo");
    ck_assert_int_eq(ZBADVERSION, framework.setData()->withVersion(100)->forPath("/foo", (char *) "bar"));
    ck_assert_int_eq(ZOK, framework.setData()->withVersion(stat.version)->forPath("/foo", (char *) "bar"));
}
END_TEST
  • Deleting a znode or deleting a znode and all it's children.
START_TEST(framework_getdata) {
    ConservatorFrameworkFactory factory = ConservatorFrameworkFactory();
    ConservatorFramework framework = factory.newClient("localhost:2181");
    framework.start();
    framework.create()->forPath("/foo", (char *) "bar");
    ck_assert_str_eq("bar", framework.getData()->forPath("/foo").c_str());
}
END_TEST

START_TEST(framework_delete_children) {
    ConservatorFrameworkFactory factory = ConservatorFrameworkFactory();
    ConservatorFramework framework = factory.newClient("localhost:2181");
    framework.start();
    framework.create()->forPath("/flintstones");
    framework.create()->forPath("/flintstones/fred");
    framework.create()->forPath("/flintstones/barney");
    vector<string> children = framework.getChildren()->forPath("/flintstones");
    ck_assert_int_eq(2, children.size());
    ck_assert_str_eq("barney", children.at(0).c_str());
    ck_assert_str_eq("fred", children.at(1).c_str());
    framework.deleteNode()->deletingChildren()->forPath("/flintstones");
    ck_assert_int_eq(ZNONODE, framework.checkExists()->forPath("/flintstones"));

}
END_TEST
  • Getting a znode's children
START_TEST(framework_getchildren)
{
    ConservatorFrameworkFactory factory = ConservatorFrameworkFactory();
    ConservatorFramework framework = factory.newClient("localhost:2181");
    framework.start();
    framework.create()->forPath("/flintstones");
    framework.create()->forPath("/flintstones/fred");
    framework.create()->forPath("/flintstones/barney");
    vector<string> children = framework.getChildren()->forPath("/flintstones");
    ck_assert_int_eq(2, children.size());
    ck_assert_str_eq("barney", children.at(0).c_str());
    ck_assert_str_eq("fred", children.at(1).c_str());
}
END_TEST

TODO

  • Add support for the zookeeper.h zoo_a* asynchronous calls
  • Add support for the zoo_*2 calls that allow for setting Stat structs.
  • Add support for blocking on connect for framework.start()
  • Better error detection and recovery handling.

conservator's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

conservator's Issues

Some points

1 In ConservatorFramework.cpp, the watcher function has some minor problem with lock---wait---notify. There is a chance the wait operation may never be wake up.

2 There is lack of code to handle session timeout which may result in invalid zhandler.

Have ConservatorFrameworkFactory construct ConservatorFramework

As it stands now it is difficult to have a ConservatorFramework reference as a private class member as there is no empty constructor. The current model of constructing with the ConservatorFrameworkFactory doesn't leave the option of a delayed initialization of the framework.

One suggestion would be to have ConservatorFrameworkFactory.newClient() allocate the framework and return a unique_ptr<ConservatorFramework> meaning the initial class member can be initialized to a nullptr.

Expose error->string service via zerror()

Given conservator returns the ZK lib error code values from multiple functions, it would be valuable to have an int code->string msg lookup service. This could be just a wrapper around zerror() in the underlying ZK lib.

For now consumers can just call zerror(), but it is an abstraction leak.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.