diff options
author | Jeff Darcy <jdarcy@redhat.com> | 2014-01-02 20:56:09 +0000 |
---|---|---|
committer | Jeff Darcy <jdarcy@redhat.com> | 2014-01-08 14:49:37 +0000 |
commit | c0dff5e2e163c1b8f3ab8a1e1336f13134067eba (patch) | |
tree | e1e960af8cbd5baa5af17c64e6c67084ec9c27f0 /xlators/cluster/nsr-server/src/etcd-api.c | |
parent | e0cce4cf7c22d5cd8ab6c2aff4ecf28c18c6a469 (diff) |
Update to etcd API v2.
Change-Id: I6609b39276674aa6d94113ba270c2bc67f2be1e8
Signed-off-by: Jeff Darcy <jdarcy@redhat.com>
Diffstat (limited to 'xlators/cluster/nsr-server/src/etcd-api.c')
-rw-r--r-- | xlators/cluster/nsr-server/src/etcd-api.c | 91 |
1 files changed, 76 insertions, 15 deletions
diff --git a/xlators/cluster/nsr-server/src/etcd-api.c b/xlators/cluster/nsr-server/src/etcd-api.c index a46a40745..be450c421 100644 --- a/xlators/cluster/nsr-server/src/etcd-api.c +++ b/xlators/cluster/nsr-server/src/etcd-api.c @@ -24,24 +24,22 @@ * POSSIBILITY OF SUCH DAMAGE. */ +/* For asprintf */ +#if !defined(_GNU_SOURCE) +#define _GNU_SOURCE +#endif + #include <stdio.h> #include <stdlib.h> #include <string.h> #include <curl/curl.h> #include <yajl/yajl_tree.h> - - #include "etcd-api.h" + #define DEFAULT_ETCD_PORT 4001 #define SL_DELIM "\n\r\t ,;" -/* - * This shuts up gcc, which complains about "null argument where non-null - * required" when we pass the result to strdup. - */ -#define MY_YAJL_GET_STRING(v) (YAJL_IS_STRING(v) ? (v)->u.string : "fubar") - typedef struct { etcd_server *servers; } _etcd_session; @@ -55,7 +53,20 @@ typedef struct { typedef size_t curl_callback_t (void *, size_t, size_t, void *); -int g_inited = 0; +int g_inited = 0; +const char *value_path[] = { "node", "value", NULL }; + +/* + * We only call this in case where it should be safe, but gcc doesn't know + * that so we use this to shut it up. + */ +char * +MY_YAJL_GET_STRING (yajl_val x) +{ + char *y = YAJL_GET_STRING(x); + + return y ? y : "bogus"; +} #if defined(DEBUG) void @@ -101,17 +112,58 @@ etcd_close (etcd_session this) free(this); } +/* + * Looking directly at node->u.array seems terribly un-modular, but the YAJL + * tree interface doesn't seem to have any exposed API for iterating over the + * elements of an array. I tried using yajl_tree_get with an index in the + * path, either as a type-casted integer or as a string, but that didn't work. + */ +char * +parse_array_response (yajl_val node) +{ + size_t i; + yajl_val item; + yajl_val value; + char *retval = NULL; + char *saved; + + for (i = 0; i < node->u.array.len; ++i) { + item = node->u.array.values[i]; + if (!item) { + break; + } + value = yajl_tree_get(item,value_path,yajl_t_string); + if (!value) { + break; + } + if (retval) { + saved = retval; + retval = NULL; + (void)asprintf (&retval, "%s\n%s", + saved, MY_YAJL_GET_STRING(value)); + free(saved); + } + else { + retval = strdup(MY_YAJL_GET_STRING(value)); + } + if (!retval) { + break; + } + } + + return retval; +} size_t parse_get_response (void *ptr, size_t size, size_t nmemb, void *stream) { yajl_val node; yajl_val value; - static const char *path[] = { "value", NULL }; node = yajl_tree_parse(ptr,NULL,0); - if (node) { - value = yajl_tree_get(node,path,yajl_t_string); + if (node) switch (node->type) { + case yajl_t_object: + value = yajl_tree_get(node,value_path,yajl_t_string); if (value) { /* * YAJL probably copied it once, now we're going to @@ -123,8 +175,15 @@ parse_get_response (void *ptr, size_t size, size_t nmemb, void *stream) */ *((char **)stream) = strdup(MY_YAJL_GET_STRING(value)); } + break; + case yajl_t_array: + *((char **)stream) = parse_array_response(node); + break; + default: + ; } + yajl_tree_free(node); return size*nmemb; } @@ -139,7 +198,7 @@ etcd_get_one (_etcd_session *this, char *key, etcd_server *srv, char *prefix, etcd_result res = ETCD_WTF; void *err_label = &&done; - if (asprintf(&url,"http://%s:%u/v1/%s%s", + if (asprintf(&url,"http://%s:%u/v2/%s%s", srv->host,srv->port,prefix,key) < 0) { goto *err_label; } @@ -293,7 +352,7 @@ parse_set_response (void *ptr, size_t size, size_t nmemb, void *stream) * contain errorCode and cause. Among all these, index seems to be the * one we're most likely to need later, so look for that. */ - static const char *path[] = { "index", NULL }; + static const char *path[] = { "node", "modifiedIndex", NULL }; node = yajl_tree_parse(ptr,NULL,0); if (node) { @@ -320,7 +379,7 @@ etcd_put_one (_etcd_session *this, char *key, char *value, CURLcode curl_res; void *err_label = &&done; - if (asprintf(&url,"http://%s:%u/v1/keys/%s", + if (asprintf(&url,"http://%s:%u/v2/keys/%s", srv->host,srv->port,key) < 0) { goto *err_label; } @@ -359,8 +418,10 @@ etcd_put_one (_etcd_session *this, char *key, char *value, err_label = &&cleanup_curl; /* TBD: add error checking for these */ + curl_easy_setopt(curl,CURLOPT_CUSTOMREQUEST,"PUT"); curl_easy_setopt(curl,CURLOPT_URL,url); curl_easy_setopt(curl,CURLOPT_FOLLOWLOCATION,1L); + curl_easy_setopt(curl,CURLOPT_POSTREDIR,CURL_REDIR_POST_ALL); curl_easy_setopt(curl,CURLOPT_WRITEFUNCTION,parse_set_response); curl_easy_setopt(curl,CURLOPT_WRITEDATA,&res); if (value) { |