<commit_before>%%%-------------------------------------------------------------------
%%% @author tihon
%%% @copyright (C) 2016, <COMPANY>
%%% @doc
%%%
%%% @end
%%% Created : 28. Oct 2016 18:15
%%%-------------------------------------------------------------------
-module(sc_backend_consul).
-author("tihon").

-behavior(sc_backend).

%% Callbacks
-export([get_service/2, get_services/1, register/4, get_value/2, set_value/3]).

%% Consul API
-export([dns_request/3, get_service_near/3]).

-define(SERVICES, "~s/v1/catalog/services/").
-define(SERVICE, "~s/v1/catalog/service/~s").
-define(REGISTER, "~s/v1/catalog/register").
-define(SERVICE_NEAR, "~s/v1/catalog/service/~s?near=~s").
-define(KEYVALUE, "~s/v1/kv/~s").

-define(MAP, [{object_format, map}]).

-spec get_service(string(), string()) -> {ok, map()} | {error, any()}.
get_service(Addr, Name) ->
  Url = lists:flatten(io_lib:format(?SERVICE, [Addr, Name])),
  case httpc:request(get, {Url, []}, [], [{body_format, binary}]) of
    {ok, {{_, 200, _}, _, Reply}} ->
      {ok, jsone:decode(Reply, ?MAP)};
    Err ->
      {error, Err}
  end.

-spec get_services(string()) -> {ok, map()} | {error, any()}.
get_services(Addr) ->
  Url = lists:flatten(io_lib:format(?SERVICES, [Addr])),
  case httpc:request(get, {Url, []}, [], [{body_format, binary}]) of
    {ok, {{_, 200, _}, _, Reply}} ->
      {ok, jsone:decode(Reply, ?MAP)};
    Err ->
      {error, Err}
  end.

-spec get_service_near(string(), string(), string()) -> {ok, map(), list()} | {error, any()}.
get_service_near(Addr, Name, Node) ->
  Url = lists:flatten(io_lib:format(?SERVICE_NEAR, [Addr, Name, Node])),
  case httpc:request(get, {Url, []}, [], [{body_format, binary}]) of
    {ok, {{_, 200, _}, _, Reply}} ->
      [Near | Other] = jsone:decode(Reply, ?MAP),
      {ok, Near, Other};
    Err ->
      {error, Err}
  end.

-spec dns_request(string(), string(), pos_integer()) -> list().
dns_request(Service, ConsulIp, Port) ->
  {ok, Ip} = inet:parse_address(ConsulIp),
  inet_res:lookup(Service ++ ".service.consul", any, srv, [{nameservers, [{Ip, Port}]}]).

-spec register(string(), string(), string(), integer()) -> ok | {error, any()}.
register(Host, Service, Address, Port) ->
  Url = lists:flatten(io_lib:format(?REGISTER, [Host])),
  Body = form_register_body(Service, Address, Port),
  case httpc:request(put, {Url, [], "application/json", Body}, [], [{body_format, binary}]) of
    {ok, {{_, 200, _}, _, _}} -> ok;
    Err -> {error, Err}
  end.

-spec get_value(string(), binary()) -> {ok, binary() | undefined} | {error, any()}.
get_value(Host, Key) ->
  Url = lists:flatten(io_lib:format(?KEYVALUE, [Host, Key])),
  case httpc:request(get, {Url, []}, [], [{body_format, binary}]) of
    {ok, {{_, 200, _}, _, Reply}} ->
      #{<<"Value">> := Value} = jsone:decode(Reply, ?MAP),
      {ok, base64:decode(Value)};
    {ok, {{_, 404, _}, _, _}} ->
      {ok, undefined};
      Err ->
      {error, Err}
  end.

-spec set_value(string(), binary(), binary()) -> ok | {error, any()}.
set_value(Host, Key, Value) ->
  Url = lists:flatten(io_lib:format(?KEYVALUE, [Host, Key])),
  case httpc:request(put, {Url, [], "application/text", Value}, [], [{body_format, binary}]) of<commit_msg>fix consul return result on get as list<commit_after>%%%-------------------------------------------------------------------
%%% @author tihon
%%% @copyright (C) 2016, <COMPANY>
%%% @doc
%%%
%%% @end
%%% Created : 28. Oct 2016 18:15
%%%-------------------------------------------------------------------
-module(sc_backend_consul).
-author("tihon").

-behavior(sc_backend).

%% Callbacks
-export([get_service/2, get_services/1, register/4, get_value/2, set_value/3]).

%% Consul API
-export([dns_request/3, get_service_near/3]).

-define(SERVICES, "~s/v1/catalog/services/").
-define(SERVICE, "~s/v1/catalog/service/~s").
-define(REGISTER, "~s/v1/catalog/register").
-define(SERVICE_NEAR, "~s/v1/catalog/service/~s?near=~s").
-define(KEYVALUE, "~s/v1/kv/~s").

-define(MAP, [{object_format, map}]).

-spec get_service(string(), string()) -> {ok, map()} | {error, any()}.
get_service(Addr, Name) ->
  Url = lists:flatten(io_lib:format(?SERVICE, [Addr, Name])),
  case httpc:request(get, {Url, []}, [], [{body_format, binary}]) of
    {ok, {{_, 200, _}, _, Reply}} ->
      {ok, jsone:decode(Reply, ?MAP)};
    Err ->
      {error, Err}
  end.

-spec get_services(string()) -> {ok, map()} | {error, any()}.
get_services(Addr) ->
  Url = lists:flatten(io_lib:format(?SERVICES, [Addr])),
  case httpc:request(get, {Url, []}, [], [{body_format, binary}]) of
    {ok, {{_, 200, _}, _, Reply}} ->
      {ok, jsone:decode(Reply, ?MAP)};
    Err ->
      {error, Err}
  end.

-spec get_service_near(string(), string(), string()) -> {ok, map(), list()} | {error, any()}.
get_service_near(Addr, Name, Node) ->
  Url = lists:flatten(io_lib:format(?SERVICE_NEAR, [Addr, Name, Node])),
  case httpc:request(get, {Url, []}, [], [{body_format, binary}]) of
    {ok, {{_, 200, _}, _, Reply}} ->
      [Near | Other] = jsone:decode(Reply, ?MAP),
      {ok, Near, Other};
    Err ->
      {error, Err}
  end.

-spec dns_request(string(), string(), pos_integer()) -> list().
dns_request(Service, ConsulIp, Port) ->
  {ok, Ip} = inet:parse_address(ConsulIp),
  inet_res:lookup(Service ++ ".service.consul", any, srv, [{nameservers, [{Ip, Port}]}]).

-spec register(string(), string(), string(), integer()) -> ok | {error, any()}.
register(Host, Service, Address, Port) ->
  Url = lists:flatten(io_lib:format(?REGISTER, [Host])),
  Body = form_register_body(Service, Address, Port),
  case httpc:request(put, {Url, [], "application/json", Body}, [], [{body_format, binary}]) of
    {ok, {{_, 200, _}, _, _}} -> ok;
    Err -> {error, Err}
  end.

-spec get_value(string(), binary()) -> {ok, binary() | undefined} | {error, any()}.
get_value(Host, Key) ->
  Url = lists:flatten(io_lib:format(?KEYVALUE, [Host, Key])),
  case httpc:request(get, {Url, []}, [], [{body_format, binary}]) of
    {ok, {{_, 200, _}, _, Reply}} ->
      [#{<<"Value">> := Value}] = jsone:decode(Reply, ?MAP),
      {ok, base64:decode(Value)};
    {ok, {{_, 404, _}, _, _}} ->
      {ok, undefined};
      Err ->
      {error, Err}
  end.

-spec set_value(string(), binary(), binary()) -> ok | {error, any()}.
set_value(Host, Key, Value) ->
  Url = lists:flatten(io_lib:format(?KEYVALUE, [Host, Key])),
  case httpc:request(put, {Url, [], "application/text", Value}, [], [{body_format, binary}]) of
{'fraction_non_alphanumeric': 0.27295208655332304, 'fraction_numerical': 0.014219474497681607, 'mean_word_length': 3.444368131868132, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 59, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2629001', 'n_tokens_mistral': 2456, 'n_tokens_neox': 2337, 'n_words': 492}