Current section

Files

Jump to
influxdb src influxdb_http.erl
Raw

src/influxdb_http.erl

-module(influxdb_http).
-export([
post/6
]).
-export_type([
result/0,
series/0
]).
-spec post(binary(), string(), string(), string(), iodata(), timeout()) ->
ok
| {ok, [result()]}
| {error, {not_found, string()}}
| {error, {server_error, string()}}.
-type result() :: [series()].
-type series() :: #{name := binary(), columns := [binary()], rows := [tuple()], tags => #{binary() => binary()}}.
post(Url, Username, Password, ContentType, Body, Timeout) ->
Authorization = "Basic " ++ base64:encode_to_string(Username ++ ":" ++ Password),
Headers = [{"Authorization", Authorization}],
case httpc:request(post,
{binary_to_list(Url), Headers, ContentType, iolist_to_binary(Body)},
[{timeout, Timeout}],
[{body_format, binary}],
influxdb) of
{ok, {{_, RespCode, _}, RespHeaders, RespBody}} ->
response(RespCode, RespHeaders, RespBody);
{error, Reason} ->
erlang:exit(Reason)
end.
%% Internals
response(200, _, Body) ->
case results(jsone:decode(Body)) of
[] -> ok;
Results -> {ok, Results}
end;
response(204, _, _) ->
ok;
response(400, _, Body) ->
#{<<"error">> := Message} = jsone:decode(Body),
erlang:error({bad_request, unicode:characters_to_list(Message)});
response(404, _, Body) ->
#{<<"error">> := Message} = jsone:decode(Body),
{error, {not_found, unicode:characters_to_list(Message)}};
response(500, _, Body) ->
#{<<"error">> := Message} = jsone:decode(Body),
{error, {server_error, unicode:characters_to_list(Message)}}.
results(#{<<"results">> := Results}) ->
[series(Series) || #{<<"series">> := Series} <- Results].
series(Series) ->
[maps:fold(fun
(<<"name">>, Name, Acc) -> Acc#{name => Name};
(<<"tags">>, Tags, Acc) -> Acc#{tags => Tags};
(<<"columns">>, Columns, Acc) -> Acc#{columns => Columns};
(<<"values">>, Values, Acc) -> Acc#{rows => [list_to_tuple(Value) || Value <- Values]}
end, #{}, S) || S <- Series].