Skip to content

Commit

Permalink
MB-3575 - conflate new_config() call signature changed
Browse files Browse the repository at this point in the history
Provide a useful response to the new_config() callback, where moxi can
tell conflate that it received a bogus config.  conflate can then try
to contact an alternative REST config server.

Change-Id: I19a76db41dd161e62938d4ef6b5738d1a7aab7f5
Reviewed-on: http://review.membase.org/6342
Tested-by: Steve Yen <steve.yen@gmail.com>
Reviewed-by: Bin Cui <bin.cui@gmail.com>
  • Loading branch information
steveyen authored and bcui6611 committed May 19, 2011
1 parent 36fe280 commit db63df8
Show file tree
Hide file tree
Showing 4 changed files with 293 additions and 7 deletions.
1 change: 1 addition & 0 deletions Makefile.am
Expand Up @@ -122,6 +122,7 @@ test: memcached-debug sizes testapp
./t/issue-MB-2980.sh
./t/issue-MB-3076.sh
./t/issue-MB-3113.sh
./t/issue-MB-3575.sh

test_gcov: test
@if test `basename $(PROFILER)` = "gcov"; then \
Expand Down
3 changes: 2 additions & 1 deletion agent.h
Expand Up @@ -20,7 +20,8 @@ proxy_main *cproxy_init_agent_start(char *jid, char *jpw,
int nthreads);

#ifdef HAVE_CONFLATE_H
void on_conflate_new_config(void *userdata, kvpair_t *config);
conflate_result on_conflate_new_config(void *userdata, kvpair_t *config);

enum conflate_mgmt_cb_result on_conflate_get_stats(void *opaque,
conflate_handle_t *handle,
const char *cmd,
Expand Down
48 changes: 42 additions & 6 deletions agent_config.c
Expand Up @@ -384,7 +384,7 @@ static void cproxy_init_null_bucket(proxy_main *m) {
}
}

void on_conflate_new_config(void *userdata, kvpair_t *config) {
conflate_result on_conflate_new_config(void *userdata, kvpair_t *config) {
assert(config != NULL);

proxy_main *m = userdata;
Expand All @@ -397,17 +397,53 @@ void on_conflate_new_config(void *userdata, kvpair_t *config) {
moxi_log_write("configuration received\n");
}

char **urlv = get_key_values(config, "url"); // NULL delimited array of char *.
char *url = urlv != NULL ? urlv[0] : NULL;

char **contentsv = get_key_values(config, "contents");
char *contents = contentsv != NULL ? contentsv[0] : NULL;

if (url != NULL &&
contents != NULL &&
strlen(contents) > 0) {
// Must be a REST/JSON config. Wastefully test parse it here,
// before we asynchronously invoke the real worker who can't
// respond nicely with an error code.
//
bool ok = false;

cJSON *c = cJSON_Parse(contents);
if (c != NULL) {
ok = true;
cJSON_Delete(c);
}

if (!ok) {
moxi_log_write("ERROR: parse JSON failed, from REST server: %s, %s\n",
url, contents);

return CONFLATE_ERROR_BAD_SOURCE;
}
}

kvpair_t *copy = dup_kvpair(config);
if (copy != NULL) {
if (!work_send(mthread->work_queue, cproxy_on_config, m, copy) &&
settings.verbose > 1) {
moxi_log_write("work_send failed\n");
if (work_send(mthread->work_queue, cproxy_on_config, m, copy)) {
return CONFLATE_SUCCESS;
}
} else {

if (settings.verbose > 1) {
moxi_log_write("agent_config ocnc failed dup_kvpair\n");
moxi_log_write("work_send failed\n");
}

return CONFLATE_ERROR;
}

if (settings.verbose > 1) {
moxi_log_write("agent_config ocnc failed dup_kvpair\n");
}

return CONFLATE_ERROR;
}

#ifdef MOXI_USE_LIBVBUCKET
Expand Down
248 changes: 248 additions & 0 deletions t/issue-MB-3575.sh
@@ -0,0 +1,248 @@
#!/bin/sh

rm -f /tmp/issue-MB-3575.out*

( cat << EOF
HTTP/1.0 200 OK
This is just a bad response that is not JSON.
EOF
) | nc -l 22100 &

( cat << EOF
{ "buckets": [
{"name":"default",
"foo":"bar",
"saslPassword": "",
"bucketType":"membase",
"nodes":[
{"replication":0.0,"clusterMembership":"active","status":"healthy",
"hostname":"127.0.0.1:22100",
"ports":{"proxy":11266,"direct":11277}}
],
"nodeLocator":"vbucket",
"vBucketServerMap":{
"hashAlgorithm":"CRC","numReplicas":0,
"serverList":["127.0.0.1:11277"],
"vBucketMap":[[0]]
}
}
] }
EOF
) > /tmp/issue-MB-3575-good.cfg

ruby ./t/rest_mock.rb /tmp/issue-MB-3575-good.cfg &

sleep 1

echo starting moxi

./moxi \
-z http://127.0.0.1:22100/bad,http://127.0.0.1:4567/pools/default/bucketsStreaming/default \
-Z port_listen=11266,downstream_conn_max=1,downstream_max=0,downstream_timeout=300,wait_queue_timeout=300,downstream_conn_queue_timeout=300,connect_timeout=300,auth_timeout=300 2>> /tmp/issue-MB-3575.out &

sleep 1

echo OK

killall moxi
killall nc

ps | grep ruby | grep rest_mock.rb | cut -d ' ' -f 1 - | xargs kill -KILL

echo --------------- >> /tmp/issue-MB-3575.out

( cat << EOF
HTTP/1.0 200 OK
This is just a bad response that is not JSON.
EOF
) | nc -l 22100 &

( cat << EOF
{ "buckets": [
{"name":"default",
"foo":"bar",
"saslPassword": "",
"bucketType":"membase",
"nodes":[
{"replication":0.0,"clusterMembership":"active","status":"healthy",
"hostname":"127.0.0.1:22100",
"ports":{"proxy":11266,"direct":11277}}
],
"nodeLocator":"vbucket",
"vBucketServerMap":{
"hashAlgorithm":"CRC","numReplicas":0,
"serverList":["127.0.0.1:11277"],
"vBucketMap":[[0]]
}
}
] }
EOF
) > /tmp/issue-MB-3575-good.cfg

ruby ./t/rest_mock.rb /tmp/issue-MB-3575-good.cfg &

sleep 1

echo starting moxi

./moxi \
-z http://127.0.0.1:4567/pools/default/bucketsStreaming/default,http://127.0.0.1:22100/bad \
-Z port_listen=11266,downstream_conn_max=1,downstream_max=0,downstream_timeout=300,wait_queue_timeout=300,downstream_conn_queue_timeout=300,connect_timeout=300,auth_timeout=300 2>> /tmp/issue-MB-3575.out &

sleep 1

echo OK

killall moxi
killall nc

ps | grep ruby | grep rest_mock.rb | cut -d ' ' -f 1 - | xargs kill -KILL

echo --------------- >> /tmp/issue-MB-3575.out

( cat << EOF
HTTP/1.0 200 OK
This is just a bad response that is not JSON.
EOF
) | nc -l 22100 &

( cat << EOF
HTTP/1.0 200 OK
This is just a bad response that is not JSON.
EOF
) | nc -l 22101 &

( cat << EOF
{ "buckets": [
{"name":"default",
"foo":"bar",
"saslPassword": "",
"bucketType":"membase",
"nodes":[
{"replication":0.0,"clusterMembership":"active","status":"healthy",
"hostname":"127.0.0.1:22100",
"ports":{"proxy":11266,"direct":11277}}
],
"nodeLocator":"vbucket",
"vBucketServerMap":{
"hashAlgorithm":"CRC","numReplicas":0,
"serverList":["127.0.0.1:11277"],
"vBucketMap":[[0]]
}
}
] }
EOF
) > /tmp/issue-MB-3575-good.cfg

ruby ./t/rest_mock.rb /tmp/issue-MB-3575-good.cfg &

sleep 1

echo starting moxi

./moxi \
-z http://127.0.0.1:22100/bad,http://127.0.0.1:22101/bad,http://127.0.0.1:4567/pools/default/bucketsStreaming/default \
-Z port_listen=11266,downstream_conn_max=1,downstream_max=0,downstream_timeout=300,wait_queue_timeout=300,downstream_conn_queue_timeout=300,connect_timeout=300,auth_timeout=300 2>> /tmp/issue-MB-3575.out &

sleep 1

echo OK

killall moxi
killall nc

ps | grep ruby | grep rest_mock.rb | cut -d ' ' -f 1 - | xargs kill -KILL

echo --------------- >> /tmp/issue-MB-3575.out

( cat << EOF
HTTP/1.0 200 OK
This is just a bad response that is not JSON.
EOF
) | nc -l 22100 &

( cat << EOF
HTTP/1.0 200 OK
This is just a bad response that is not JSON.
EOF
) | nc -l 22101 &

( cat << EOF
{ "buckets": [
{"name":"default",
"foo":"bar",
"saslPassword": "",
"bucketType":"membase",
"nodes":[
{"replication":0.0,"clusterMembership":"active","status":"healthy",
"hostname":"127.0.0.1:22100",
"ports":{"proxy":11266,"direct":11277}}
],
"nodeLocator":"vbucket",
"vBucketServerMap":{
"hashAlgorithm":"CRC","numReplicas":0,
"serverList":["127.0.0.1:11277"],
"vBucketMap":[[0]]
}
}
] }
EOF
) > /tmp/issue-MB-3575-good.cfg

ruby ./t/rest_mock.rb /tmp/issue-MB-3575-good.cfg &

sleep 1

echo starting moxi

./moxi \
-z http://127.0.0.1:22100/bad,http://127.0.0.1:4567/pools/default/bucketsStreaming/default,http://127.0.0.1:22101/bad \
-Z port_listen=11266,downstream_conn_max=1,downstream_max=0,downstream_timeout=300,wait_queue_timeout=300,downstream_conn_queue_timeout=300,connect_timeout=300,auth_timeout=300 2>> /tmp/issue-MB-3575.out &

sleep 1

echo OK

killall moxi
killall nc

ps | grep ruby | grep rest_mock.rb | cut -d ' ' -f 1 - | xargs kill -KILL

echo ----------------------

cut -d ' ' -f 4- /tmp/issue-MB-3575.out > /tmp/issue-MB-3575.out2

count=$( (diff /tmp/issue-MB-3575.out2 - <<EOF
ERROR: parse JSON failed, from REST server: http://127.0.0.1:22100/bad, This is just a bad response that is not JSON.
ERROR: invalid, empty config from REST server http://127.0.0.1:4567/pools/default/bucketsStreaming/default
---------------
ERROR: invalid, empty config from REST server http://127.0.0.1:4567/pools/default/bucketsStreaming/default
---------------
ERROR: parse JSON failed, from REST server: http://127.0.0.1:22100/bad, This is just a bad response that is not JSON.
ERROR: parse JSON failed, from REST server: http://127.0.0.1:22101/bad, This is just a bad response that is not JSON.
ERROR: invalid, empty config from REST server http://127.0.0.1:4567/pools/default/bucketsStreaming/default
---------------
ERROR: parse JSON failed, from REST server: http://127.0.0.1:22100/bad, This is just a bad response that is not JSON.
ERROR: invalid, empty config from REST server http://127.0.0.1:4567/pools/default/bucketsStreaming/default
EOF
) | wc -l)

if [[ $count -ne 0 ]] ; then
echo "FAIL count expect 0, got $count"
exit 1
fi

echo
echo "OK - issue-MB-3575 fixed"


0 comments on commit db63df8

Please sign in to comment.