Skip to content

Commit

Permalink
Need API to create/delete zookeeper node.
Browse files Browse the repository at this point in the history
Solution:
   Added zookeeper client code to create/delete znode.
   Znode type of child is ephemeral(parent bening persistent) because at
   end of session which created the znode, we want to delete it.

expand zookeeper C++ API to support:
  Create node
  Delete node
  Check node exist or not
  Shutdown session

Use Case:
    Contrail collector publishing collector ip list to zookeeper
    which alarmgen/analytics_api can use.

Change-Id: I4090bbe68614c5e4fa673ba3ceb065cc4c2e6be3
Partial-bug: 1733027
  • Loading branch information
ZhiqiangCui committed Oct 10, 2018
1 parent fb9fa8d commit d1e0ff0
Show file tree
Hide file tree
Showing 5 changed files with 106 additions and 4 deletions.
2 changes: 2 additions & 0 deletions zookeeper/test/zookeeper_client_test.cc
Expand Up @@ -38,6 +38,8 @@ class ZookeeperMockInterface : public ZookeeperInterface {
int version));
MOCK_METHOD6(ZooGet, int(zhandle_t *zh, const char *path, int watch,
char *buffer, int* buffer_len, struct Stat *stat));
MOCK_METHOD4(ZooExists, int(zhandle_t *zh, const char *path, int watch,
struct Stat *stat));
};

class ZookeeperClientTest : public ::testing::Test {
Expand Down
89 changes: 86 additions & 3 deletions zookeeper/zookeeper_client.cc
Expand Up @@ -62,6 +62,10 @@ class ZookeeperCBindings : public ZookeeperInterface {
char *buffer, int* buffer_len, struct Stat *stat) {
return zoo_get(zh, path, watch, buffer, buffer_len, stat);
}
virtual int ZooExists(zhandle_t *zh, const char *path, int watch,
struct Stat *stat) {
return zoo_exists(zh, path, watch, stat);
}
};

} // namespace interface
Expand Down Expand Up @@ -150,12 +154,12 @@ static inline bool IsZooErrorUnrecoverable(int zerror) {
}

int ZookeeperClientImpl::CreateNodeSync(const char *path, const char *value,
int *err) {
int *err, int flag) {
int rc;
retry:
do {
rc = zki_->ZooCreate(zk_handle_, path, value, strlen(value),
&ZOO_OPEN_ACL_UNSAFE, 0, NULL, -1);
&ZOO_OPEN_ACL_UNSAFE, flag, NULL, -1);
} while (IsZooErrorRecoverable(rc));
if (IsZooErrorUnrecoverable(rc)) {
// Reconnect
Expand All @@ -168,6 +172,26 @@ int ZookeeperClientImpl::CreateNodeSync(const char *path, const char *value,
return rc;
}

bool ZookeeperClientImpl::CreateNode(const char *path, const char *value,
int flag) {
int err = 0;
int rc;
if (!IsConnected()) {
bool success(Connect());
if (!success) {
ZOO_LOG_ERR("Zookeeper Client Connect FAILED");
return false;
}
}
rc = CreateNodeSync(path, value, &err, flag);
if (rc != ZOK && rc != ZNODEEXISTS) {
ZOO_LOG_ERR("Creation of ZNODE(" << path << "): " << value
<< ": FAILED: (" << rc << ") error: " << err);
return false;
}
return true;
}

int ZookeeperClientImpl::GetNodeDataSync(const char *path, char *buf,
int *buf_len, int *err) {
int rc;
Expand All @@ -186,6 +210,20 @@ int ZookeeperClientImpl::GetNodeDataSync(const char *path, char *buf,
return rc;
}

bool ZookeeperClientImpl::CheckNodeExist(const char *path) {
if (!IsConnected()) {
bool success(Connect());
if (!success) {
ZOO_LOG_ERR("Zookeeper Client Connect FAILED");
return false;
}
}

struct Stat stat;
int rc = zki_->ZooExists(zk_handle_, path, 0, &stat);
return (rc == ZOK);
}

int ZookeeperClientImpl::DeleteNodeSync(const char *path, int *err) {
int rc;
retry:
Expand All @@ -203,6 +241,27 @@ int ZookeeperClientImpl::DeleteNodeSync(const char *path, int *err) {
return rc;
}

bool ZookeeperClientImpl::DeleteNode(const char *path) {
int err = 0;
int rc;
if (!IsConnected()) {
bool success(Connect());
if (!success) {
ZOO_LOG_ERR("Zookeeper Client Connect FAILED");
return false;
}
}

rc = DeleteNodeSync(path, &err);
if (rc != ZOK) {
ZOO_LOG_ERR("Deletion of ZNODE(" << path << "): "
<< ": FAILED: (" << rc << ") error: " << err);
return false;
}

return (rc == ZOK);
}

std::string ZookeeperClientImpl::Name() const {
return hostname_;
}
Expand All @@ -219,6 +278,30 @@ ZookeeperClient::ZookeeperClient(impl::ZookeeperClientImpl *impl) :
impl_(impl) {
}

bool ZookeeperClient::CreateNode(const char *path, const char *value,
int type) {
int flag = 0;
if (type == Z_NODE_TYPE_EPHEMERAL) {
flag |= ZOO_EPHEMERAL;
}
if (type == Z_NODE_TYPE_SEQUENCE) {
flag |= ZOO_SEQUENCE;
}
return impl_->CreateNode(path, value, flag);
}

bool ZookeeperClient::CheckNodeExist(const char *path) {
return impl_->CheckNodeExist(path);
}

bool ZookeeperClient::DeleteNode(const char *path) {
return impl_->DeleteNode(path);
}

void ZookeeperClient::Shutdown() {
return impl_->Shutdown();
}

ZookeeperClient::~ZookeeperClient() {
}

Expand Down Expand Up @@ -251,7 +334,7 @@ class ZookeeperLock::ZookeeperLockImpl {
// Try creating the znode
int err;
int rc(clientImpl_->CreateNodeSync(path_.c_str(), id_.c_str(),
&err));
&err, 0));
switch (rc) {
case ZOK: {
// We acquired the lock
Expand Down
12 changes: 12 additions & 0 deletions zookeeper/zookeeper_client.h
Expand Up @@ -15,13 +15,25 @@ namespace impl {
class ZookeeperClientImpl;
} // namespace impl

typedef enum Z_NODE_TYPE {
Z_NODE_TYPE_PERSISTENT = 1,
Z_NODE_TYPE_EPHEMERAL,
Z_NODE_TYPE_SEQUENCE,
}Z_NODE_TYPE_E;

//
// Blocking, synchronous, non-thread safe Zookeeper client
//
class ZookeeperClient {
public:
ZookeeperClient(const char *hostname, const char *servers);
virtual ~ZookeeperClient();
bool CreateNode(const char *path,
const char *data,
int type = Z_NODE_TYPE_PERSISTENT);
bool CheckNodeExist(const char* path);
bool DeleteNode(const char* path);
void Shutdown();

private:
ZookeeperClient(impl::ZookeeperClientImpl *impl);
Expand Down
5 changes: 4 additions & 1 deletion zookeeper/zookeeper_client_impl.h
Expand Up @@ -26,9 +26,12 @@ class ZookeeperClientImpl {
void Shutdown();
bool Reconnect();
bool IsConnected() const;
int CreateNodeSync(const char *path, const char *value, int *err);
bool CreateNode(const char *path, const char *value, int flag);
bool DeleteNode(const char *path);
int CreateNodeSync(const char *path, const char *value, int *err, int flag);
int GetNodeDataSync(const char *path, char *buf, int *buf_len, int *err);
int DeleteNodeSync(const char *path, int *err);
bool CheckNodeExist(const char *path);
std::string Name() const;

private:
Expand Down
2 changes: 2 additions & 0 deletions zookeeper/zookeeper_interface.h
Expand Up @@ -25,6 +25,8 @@ class ZookeeperInterface {
virtual int ZooDelete(zhandle_t *zh, const char *path, int version) = 0;
virtual int ZooGet(zhandle_t *zh, const char *path, int watch,
char *buffer, int* buffer_len, struct Stat *stat) = 0;
virtual int ZooExists(zhandle_t *zh, const char *path, int watch,
struct Stat *stat) = 0;
};

} // namespace interface
Expand Down

0 comments on commit d1e0ff0

Please sign in to comment.