Skip to content

Commit

Permalink
restore removed jsonrpc:call/3
Browse files Browse the repository at this point in the history
Restore the jsonrpc:call/3 function inadvertently removed in the
JSON-RPC 2.0 update. Add a new test for it. Remove test/src/httpc.erl
because it conflicted with inets:httpc during the execution of the new
test, and also because it's not used anywhere.
  • Loading branch information
vinoski committed Jun 1, 2011
1 parent 11b272b commit 183ec82
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 272 deletions.
64 changes: 64 additions & 0 deletions src/jsonrpc.erl
Expand Up @@ -29,8 +29,72 @@
-module(jsonrpc).
-author("Gaspar Chilingarov <nm@web.am>, Gurgen Tumanyan <barbarian@armkb.com>").
-vsn("3").
-export([call/3]).
-export([s/2]). % extract element from proplist

%%%
%%% call function calls json-rpc method on remote host
%%%
%%% URL - remote server url (may use https)
%%% Options - option list to be passed to http:request
%%% (ssl options ot timeout, for example)
%%% Payload -> {call, MethodName, Args} tuple
%%% MethodName -> atom
%%% Args -> list
%%%
call(URL, Options, Payload) ->
dbg:tracer(), dbg:p(all, call),
dbg:tpl(yaws_api, [{'$1',[],[{message,'$1'},{message,{caller}},{return_trace}]}]),
try
{ok, CallPayloadDeep} = encode_call_payload(Payload),
CallPayload = lists:flatten(CallPayloadDeep),
{ok, Response} = httpc:request(
post,
{URL,[{"Content-Length",length(CallPayload)}],
"application/x-www-form-urlencoded",CallPayload},
Options, []),

RespBody = if
(size(Response) == 2) or (size(Response) == 3) ->
element(size(Response), Response)
end,
decode_call_payload(RespBody)
catch
error:Err->
error_logger:error_report([{'json_rpc:call', error},
{error, Err},
{stack, erlang:get_stacktrace()}]),
{error,Err}
end.

%%%
%%% json-rpc.org defines such structure for making call
%%%
encode_call_payload({call, Method, Args}) when is_list(Args) ->
%% id makes sense when there are many requests in same
%% communication channel and replies can come in random
%% order here it can be changed to something less expensive
ID = element(3, erlang:now()),
Struct = json2:encode({struct, [{"jsonrpc", "2.0"},
{method, Method},
{params, {array, Args}},
{id, ID}]}),
{ok, Struct}.

%%%
%%% decode response structure
%%%
decode_call_payload(JSonStr) ->
{ok, JSON} = json2:decode_string(JSonStr),
Result = s(JSON, result),
Error = s(JSON, error),
case Error of
undefined ->
{ok,{response,[Result]}}; % make it compliant with xmlrpc response
Error ->
{error, Error}
end.

%%% lookup element in proplist
s({struct, List}, ElemName) ->
s(List, ElemName);
Expand Down
2 changes: 1 addition & 1 deletion test/src/Makefile
@@ -1,5 +1,5 @@
include ../support/include.mk

all: test.beam tftest.beam httpc.beam
all: test.beam tftest.beam

clean: tclean
270 changes: 0 additions & 270 deletions test/src/httpc.erl

This file was deleted.

8 changes: 7 additions & 1 deletion test/t2/app_test.erl
Expand Up @@ -273,6 +273,8 @@ streamcontent_test() ->
gen_tcp:close(Sock),
ok.

-define(JSON_URI, "http://localhost:8005/jsontest").

json_test() ->
io:format("json_test\n",[]),
io:format(" param array1\n", []),
Expand All @@ -291,6 +293,10 @@ json_test() ->
{struct, [{"jsonrpc", "2.0"},
{"result", -19},
{"id", 2}]}),
inets:start(),
io:format(" encode/decode\n", []),
?line {ok,{response,[19]}} = jsonrpc:call(?JSON_URI, [],
{call, "subtract", [42, 23]}),
io:format(" param obj1\n", []),
?line ok = do_json({struct, [{"jsonrpc", "2.0"},
{"method", "subtract"},
Expand Down Expand Up @@ -489,7 +495,7 @@ json_send(Req) ->
json_send(Req, encode) ->
json_send(json2:encode(Req), no_encode);
json_send(Req, no_encode) ->
Uri = "http://localhost:8005/jsontest",
Uri = ?JSON_URI,
ReqHdrs = [{content_type, "application/json"}],
ibrowse:send_req(Uri, ReqHdrs, post, Req).

Expand Down

0 comments on commit 183ec82

Please sign in to comment.