summaryrefslogtreecommitdiff
path: root/src/mem3_httpd.erl
diff options
context:
space:
mode:
authorAdam Kocoloski <adam@cloudant.com>2010-06-30 16:23:38 -0400
committerAdam Kocoloski <adam@cloudant.com>2010-08-12 01:22:33 -0400
commit48c8fde34591f782be7af77575eaa02dab8659b3 (patch)
treebb54c0d61a660b9ba019f9b187e901ede7132bfa /src/mem3_httpd.erl
parent8a09581aa2252f53047fa0e9e95591eaae4556c9 (diff)
standardize mem3 naming. app is horribly broken for now
Diffstat (limited to 'src/mem3_httpd.erl')
-rw-r--r--src/mem3_httpd.erl77
1 files changed, 77 insertions, 0 deletions
diff --git a/src/mem3_httpd.erl b/src/mem3_httpd.erl
new file mode 100644
index 00000000..2b29b488
--- /dev/null
+++ b/src/mem3_httpd.erl
@@ -0,0 +1,77 @@
+-module(mem3_httpd).
+
+-export([handle_membership_req/1]).
+
+%% includes
+-include("mem3.hrl").
+
+
+handle_membership_req(#httpd{method='GET',
+ path_parts=[<<"_membership">>]} = Req) ->
+ {ok,ClusterNodes} = try mem3:nodes()
+ catch _:_ -> {ok,[]} end,
+ couch_httpd:send_json(Req, {[
+ {all_nodes, lists:sort([node()|nodes()])},
+ {cluster_nodes, lists:sort(ClusterNodes)}
+ ]});
+
+handle_membership_req(#httpd{method='POST',
+ path_parts=[<<"_membership">>]} = Req) ->
+ {JsonProps} = couch_httpd:json_body_obj(Req),
+ Method = couch_util:get_value(<<"method">>, JsonProps),
+ Params = couch_util:get_value(<<"params">>, JsonProps),
+ Id = couch_util:get_value(<<"id">>, JsonProps),
+ {Result, Error} = membership_dispatch(Method, Params),
+ couch_httpd:send_json(Req, {[
+ {result, Result},
+ {error, Error},
+ {id, Id}
+ ]}).
+
+%%
+%% internal
+%%
+membership_dispatch(<<"replace">>, Params) ->
+ OldNode = get_oldnode(Params),
+ NewNodeOpts = get_value_json(<<"newnode_options">>, Params, []),
+ PingNode = get_pingnode(Params),
+ send_join(replace, {OldNode, NewNodeOpts}, PingNode);
+membership_dispatch(TypeBin, Params) ->
+ Type = list_to_atom(?b2l(TypeBin)),
+ NodeList = get_value_json(<<"nodes">>, Params, []),
+ Nodes = lists:map(fun({List}) -> node_info(List) end, NodeList),
+ PingNode = get_pingnode(Params),
+ send_join(Type, Nodes, PingNode).
+
+get_pingnode(Params) ->
+ PingNodeBin = get_value_json(<<"pingnode">>, Params, <<"nil">>),
+ list_to_atom(?b2l(PingNodeBin)).
+
+get_oldnode(Params) ->
+ NodeBin = get_value_json(<<"oldnode">>, Params, undefined),
+ NodeList = ?b2l(NodeBin),
+ list_to_atom(NodeList).
+
+%% @doc send join command to mem module
+send_join(Type, Payload, PingNode) ->
+ case mem3:join(Type, Payload, PingNode) of
+ ok -> {ok, null};
+ {error, Error} -> {Type, Error};
+ Other ->
+ ?LOG_ERROR("membership dispatch error ~p", [Other]),
+ {Type, unknown_error}
+ end.
+
+node_info(List) ->
+ Order = couch_util:get_value(<<"order">>, List),
+ Node1 = couch_util:get_value(<<"node">>, List),
+ Node2 = list_to_atom(?b2l(Node1)),
+ Options = couch_util:get_value(<<"options">>, List),
+ {Order, Node2, Options}.
+
+get_value_json(_,[], Default) -> Default;
+get_value_json(Key, [JsonProp|Rest], Default) ->
+ case JsonProp of
+ {[{Key, Value}]} -> Value;
+ _ -> get_value_json(Key, Rest, Default)
+ end.