summaryrefslogtreecommitdiffstats
path: root/xlators/cluster/nsr-server/src/etcd-api.c
diff options
context:
space:
mode:
authorJeff Darcy <jdarcy@redhat.com>2014-01-02 20:56:09 +0000
committerJeff Darcy <jdarcy@redhat.com>2014-01-08 14:49:37 +0000
commitc0dff5e2e163c1b8f3ab8a1e1336f13134067eba (patch)
treee1e960af8cbd5baa5af17c64e6c67084ec9c27f0 /xlators/cluster/nsr-server/src/etcd-api.c
parente0cce4cf7c22d5cd8ab6c2aff4ecf28c18c6a469 (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.c91
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) {