mirror of
https://github.com/valitydev/limiter.git
synced 2024-11-06 00:55:22 +00:00
VEN-9: Adds support for versioned limit config object (#20)
* Adds explicit damsel dependency * Bump dominant docker compose image (sha-e0afa44) * Adds dominant-sourced config unmarshalling * Adds operation `Limiter:GetVersioned/4` * Refactor test suite and add testcase group with dominant-sourced config object use
This commit is contained in:
parent
d7febd557c
commit
3eff7ddf1e
@ -2,6 +2,8 @@
|
||||
|
||||
-include_lib("limiter_proto/include/limproto_config_thrift.hrl").
|
||||
-include_lib("limiter_proto/include/limproto_timerange_thrift.hrl").
|
||||
-include_lib("damsel/include/dmsl_domain_thrift.hrl").
|
||||
-include_lib("damsel/include/dmsl_limiter_config_thrift.hrl").
|
||||
|
||||
-export([marshal/2]).
|
||||
-export([unmarshal/2]).
|
||||
@ -138,7 +140,35 @@ marshal_scope_type(payer_contact_email) ->
|
||||
unmarshal(timestamped_change, TimestampedChange) ->
|
||||
Timestamp = unmarshal_timestamp(TimestampedChange#config_TimestampedChange.occured_at),
|
||||
Change = unmarshal_change(TimestampedChange#config_TimestampedChange.change),
|
||||
{ev, Timestamp, Change}.
|
||||
{ev, Timestamp, Change};
|
||||
unmarshal('LimitConfigObject', #domain_LimitConfigObject{
|
||||
ref = #domain_LimitConfigRef{id = ID},
|
||||
data = #limiter_config_LimitConfig{
|
||||
processor_type = ProcessorType,
|
||||
created_at = CreatedAt,
|
||||
started_at = StartedAt,
|
||||
shard_size = ShardSize,
|
||||
time_range_type = TimeRangeType,
|
||||
context_type = ContextType,
|
||||
type = Type,
|
||||
scopes = Scopes,
|
||||
description = Description,
|
||||
op_behaviour = OpBehaviour
|
||||
}
|
||||
}) ->
|
||||
genlib_map:compact(#{
|
||||
id => ID,
|
||||
processor_type => ProcessorType,
|
||||
created_at => lim_time:from_rfc3339(CreatedAt),
|
||||
started_at => StartedAt,
|
||||
shard_size => ShardSize,
|
||||
time_range_type => unmarshal_time_range_type(TimeRangeType),
|
||||
context_type => unmarshal_context_type(ContextType),
|
||||
type => maybe_apply(Type, fun unmarshal_type/1),
|
||||
scope => maybe_apply(Scopes, fun unmarshal_scope/1),
|
||||
description => Description,
|
||||
op_behaviour => maybe_apply(OpBehaviour, fun unmarshal_op_behaviour/1)
|
||||
}).
|
||||
|
||||
unmarshal_timestamp(Timestamp) when is_binary(Timestamp) ->
|
||||
try
|
||||
@ -225,16 +255,22 @@ derive_type(undefined, {cash, Currency}) ->
|
||||
{turnover, {amount, Currency}}.
|
||||
|
||||
-spec unmarshal_op_behaviour(encoded_value()) -> decoded_value().
|
||||
unmarshal_op_behaviour(OpBehaviour) ->
|
||||
#config_OperationLimitBehaviour{
|
||||
invoice_payment_refund = Refund
|
||||
} = OpBehaviour,
|
||||
unmarshal_op_behaviour(#limiter_config_OperationLimitBehaviour{invoice_payment_refund = Refund}) ->
|
||||
do_unmarshal_op_behaviour_refund(Refund);
|
||||
unmarshal_op_behaviour(#config_OperationLimitBehaviour{invoice_payment_refund = Refund}) ->
|
||||
do_unmarshal_op_behaviour_refund(Refund).
|
||||
|
||||
do_unmarshal_op_behaviour_refund(Refund) ->
|
||||
genlib_map:compact(#{
|
||||
invoice_payment_refund => maybe_apply(Refund, fun unmarshal_behaviour/1)
|
||||
}).
|
||||
|
||||
unmarshal_behaviour({subtraction, #limiter_config_Subtraction{}}) ->
|
||||
subtraction;
|
||||
unmarshal_behaviour({subtraction, #config_Subtraction{}}) ->
|
||||
subtraction;
|
||||
unmarshal_behaviour({addition, #limiter_config_Addition{}}) ->
|
||||
addition;
|
||||
unmarshal_behaviour({addition, #config_Addition{}}) ->
|
||||
addition.
|
||||
|
||||
@ -244,6 +280,8 @@ unmarshal_body_type_deprecated({cash, #config_LimitBodyTypeCash{currency = Curre
|
||||
|
||||
unmarshal_time_range_type({calendar, CalendarType}) ->
|
||||
{calendar, unmarshal_calendar_time_range_type(CalendarType)};
|
||||
unmarshal_time_range_type({interval, #limiter_config_TimeRangeTypeInterval{amount = Amount}}) ->
|
||||
{interval, Amount};
|
||||
unmarshal_time_range_type({interval, #timerange_TimeRangeTypeInterval{amount = Amount}}) ->
|
||||
{interval, Amount}.
|
||||
|
||||
@ -256,22 +294,32 @@ unmarshal_calendar_time_range_type({month, _}) ->
|
||||
unmarshal_calendar_time_range_type({year, _}) ->
|
||||
year.
|
||||
|
||||
unmarshal_context_type({payment_processing, #limiter_config_LimitContextTypePaymentProcessing{}}) ->
|
||||
payment_processing;
|
||||
unmarshal_context_type({payment_processing, #config_LimitContextTypePaymentProcessing{}}) ->
|
||||
payment_processing;
|
||||
unmarshal_context_type({withdrawal_processing, #limiter_config_LimitContextTypeWithdrawalProcessing{}}) ->
|
||||
withdrawal_processing;
|
||||
unmarshal_context_type({withdrawal_processing, #config_LimitContextTypeWithdrawalProcessing{}}) ->
|
||||
withdrawal_processing.
|
||||
|
||||
unmarshal_type({turnover, #limiter_config_LimitTypeTurnover{metric = Metric}}) ->
|
||||
{turnover, maybe_apply(Metric, fun unmarshal_turnover_metric/1, number)};
|
||||
unmarshal_type({turnover, #config_LimitTypeTurnover{metric = Metric}}) ->
|
||||
{turnover, maybe_apply(Metric, fun unmarshal_turnover_metric/1, number)}.
|
||||
|
||||
unmarshal_turnover_metric({number, _}) ->
|
||||
number;
|
||||
unmarshal_turnover_metric({amount, #limiter_config_LimitTurnoverAmount{currency = Currency}}) ->
|
||||
{amount, Currency};
|
||||
unmarshal_turnover_metric({amount, #config_LimitTurnoverAmount{currency = Currency}}) ->
|
||||
{amount, Currency}.
|
||||
|
||||
unmarshal_scope({single, Type}) ->
|
||||
ordsets:from_list([unmarshal_scope_type(Type)]);
|
||||
unmarshal_scope({multi, Types}) ->
|
||||
ordsets:from_list(lists:map(fun unmarshal_scope_type/1, ordsets:to_list(Types)));
|
||||
unmarshal_scope(Types) when is_list(Types) ->
|
||||
ordsets:from_list(lists:map(fun unmarshal_scope_type/1, ordsets:to_list(Types))).
|
||||
|
||||
unmarshal_scope_type({party, _}) ->
|
||||
@ -360,4 +408,38 @@ unmarshal_created_w_deprecated_body_type_test_() ->
|
||||
)
|
||||
].
|
||||
|
||||
-spec unmarshal_config_object_test() -> _.
|
||||
unmarshal_config_object_test() ->
|
||||
CreatedAt = lim_time:now(),
|
||||
Config = #{
|
||||
id => <<"id">>,
|
||||
processor_type => <<"type">>,
|
||||
created_at => CreatedAt,
|
||||
started_at => <<"2000-01-01T00:00:00Z">>,
|
||||
shard_size => 7,
|
||||
time_range_type => {calendar, day},
|
||||
context_type => payment_processing,
|
||||
type => {turnover, number},
|
||||
scope => ordsets:from_list([party, shop]),
|
||||
description => <<"description">>
|
||||
},
|
||||
Object = #domain_LimitConfigObject{
|
||||
ref = #domain_LimitConfigRef{id = <<"id">>},
|
||||
data = #limiter_config_LimitConfig{
|
||||
processor_type = <<"type">>,
|
||||
created_at = lim_time:to_rfc3339(CreatedAt),
|
||||
started_at = <<"2000-01-01T00:00:00Z">>,
|
||||
shard_size = 7,
|
||||
time_range_type = {calendar, {day, #limiter_config_TimeRangeTypeCalendarDay{}}},
|
||||
context_type = {payment_processing, #limiter_config_LimitContextTypePaymentProcessing{}},
|
||||
type =
|
||||
{turnover, #limiter_config_LimitTypeTurnover{metric = {number, #limiter_config_LimitTurnoverNumber{}}}},
|
||||
scopes = ordsets:from_list([
|
||||
{'party', #limiter_config_LimitScopeEmptyDetails{}}, {'shop', #limiter_config_LimitScopeEmptyDetails{}}
|
||||
]),
|
||||
description = <<"description">>
|
||||
}
|
||||
},
|
||||
?assertEqual(Config, unmarshal('LimitConfigObject', Object)).
|
||||
|
||||
-endif.
|
||||
|
@ -1,6 +1,8 @@
|
||||
-module(lim_config_machine).
|
||||
|
||||
-include_lib("limiter_proto/include/limproto_limiter_thrift.hrl").
|
||||
-include_lib("damsel/include/dmsl_domain_thrift.hrl").
|
||||
-include_lib("damsel/include/dmsl_domain_conf_thrift.hrl").
|
||||
|
||||
%% Accessors
|
||||
|
||||
@ -21,7 +23,7 @@
|
||||
-export([start/3]).
|
||||
-export([get/2]).
|
||||
|
||||
-export([get_limit/2]).
|
||||
-export([get_limit/3]).
|
||||
-export([hold/2]).
|
||||
-export([commit/2]).
|
||||
-export([rollback/2]).
|
||||
@ -80,6 +82,7 @@
|
||||
-type operation_type() :: invoice_payment_refund.
|
||||
|
||||
-type lim_id() :: limproto_limiter_thrift:'LimitID'().
|
||||
-type lim_version() :: dmsl_domain_thrift:'DataRevision'() | undefined.
|
||||
-type lim_change() :: limproto_limiter_thrift:'LimitChange'().
|
||||
-type limit() :: limproto_limiter_thrift:'Limit'().
|
||||
-type timestamp() :: dmsl_base_thrift:'Timestamp'().
|
||||
@ -232,41 +235,56 @@ get(ID, LimitContext) ->
|
||||
collapse(Machine)
|
||||
end).
|
||||
|
||||
-spec get_limit(lim_id(), lim_context()) -> {ok, limit()} | {error, config_error() | {processor(), get_limit_error()}}.
|
||||
get_limit(ID, LimitContext) ->
|
||||
-spec get_limit(lim_id(), lim_version(), lim_context()) ->
|
||||
{ok, limit()} | {error, config_error() | {processor(), get_limit_error()}}.
|
||||
get_limit(ID, Version, LimitContext) ->
|
||||
do(fun() ->
|
||||
{Handler, Config} = unwrap(get_handler(ID, LimitContext)),
|
||||
{Handler, Config} = unwrap(get_handler(ID, Version, LimitContext)),
|
||||
unwrap(Handler, Handler:get_limit(ID, Config, LimitContext))
|
||||
end).
|
||||
|
||||
-spec hold(lim_change(), lim_context()) -> ok | {error, config_error() | {processor(), hold_error()}}.
|
||||
hold(LimitChange = #limiter_LimitChange{id = ID}, LimitContext) ->
|
||||
hold(LimitChange = #limiter_LimitChange{id = ID, version = Version}, LimitContext) ->
|
||||
do(fun() ->
|
||||
{Handler, Config} = unwrap(get_handler(ID, LimitContext)),
|
||||
{Handler, Config} = unwrap(get_handler(ID, Version, LimitContext)),
|
||||
unwrap(Handler, Handler:hold(LimitChange, Config, LimitContext))
|
||||
end).
|
||||
|
||||
-spec commit(lim_change(), lim_context()) -> ok | {error, config_error() | {processor(), commit_error()}}.
|
||||
commit(LimitChange = #limiter_LimitChange{id = ID}, LimitContext) ->
|
||||
commit(LimitChange = #limiter_LimitChange{id = ID, version = Version}, LimitContext) ->
|
||||
do(fun() ->
|
||||
{Handler, Config} = unwrap(get_handler(ID, LimitContext)),
|
||||
{Handler, Config} = unwrap(get_handler(ID, Version, LimitContext)),
|
||||
unwrap(Handler, Handler:commit(LimitChange, Config, LimitContext))
|
||||
end).
|
||||
|
||||
-spec rollback(lim_change(), lim_context()) -> ok | {error, config_error() | {processor(), rollback_error()}}.
|
||||
rollback(LimitChange = #limiter_LimitChange{id = ID}, LimitContext) ->
|
||||
rollback(LimitChange = #limiter_LimitChange{id = ID, version = Version}, LimitContext) ->
|
||||
do(fun() ->
|
||||
{Handler, Config} = unwrap(get_handler(ID, LimitContext)),
|
||||
{Handler, Config} = unwrap(get_handler(ID, Version, LimitContext)),
|
||||
unwrap(Handler, Handler:rollback(LimitChange, Config, LimitContext))
|
||||
end).
|
||||
|
||||
get_handler(ID, LimitContext) ->
|
||||
get_handler(ID, Version, LimitContext) ->
|
||||
do(fun() ->
|
||||
Config = #{processor_type := ProcessorType} = unwrap(config, get(ID, LimitContext)),
|
||||
Config = #{processor_type := ProcessorType} = unwrap(config, get_config(ID, Version, LimitContext)),
|
||||
{ok, Handler} = lim_router:get_handler(ProcessorType),
|
||||
{Handler, Config}
|
||||
end).
|
||||
|
||||
-spec get_config(lim_id(), lim_version(), lim_context()) -> {ok, config()} | {error, notfound}.
|
||||
get_config(ID, undefined, LimitContext) ->
|
||||
get(ID, LimitContext);
|
||||
get_config(ID, Version, #{woody_context := WoodyContext}) ->
|
||||
LimitConfigRef = {limit_config, #domain_LimitConfigRef{id = ID}},
|
||||
try
|
||||
Object = dmt_client:checkout_versioned_object(Version, LimitConfigRef, #{woody_context => WoodyContext}),
|
||||
#domain_conf_VersionedObject{object = {limit_config, ConfigObject}} = Object,
|
||||
{ok, lim_config_codec:unmarshal('LimitConfigObject', ConfigObject)}
|
||||
catch
|
||||
throw:#domain_conf_ObjectNotFound{} ->
|
||||
{error, notfound}
|
||||
end.
|
||||
|
||||
-spec calculate_time_range(timestamp(), config()) -> time_range().
|
||||
calculate_time_range(Timestamp, Config) ->
|
||||
StartedAt = started_at(Config),
|
||||
|
@ -27,11 +27,14 @@ handle_function(Fn, Args, WoodyCtx, Opts) ->
|
||||
).
|
||||
|
||||
-spec handle_function_(woody:func(), woody:args(), lim_context(), woody:options()) -> {ok, woody:result()}.
|
||||
handle_function_('Get', {LimitID, Clock, Context}, LimitContext, _Opts) ->
|
||||
handle_function_('Get', {LimitID, Clock, Context}, LimitContext, Opts) ->
|
||||
handle_function_('GetVersioned', {LimitID, undefined, Clock, Context}, LimitContext, Opts);
|
||||
handle_function_('GetVersioned', {LimitID, Version, Clock, Context}, LimitContext, _Opts) ->
|
||||
scoper:add_meta(#{limit_id => LimitID}),
|
||||
case
|
||||
lim_config_machine:get_limit(
|
||||
LimitID,
|
||||
Version,
|
||||
lim_context:set_context(Context, lim_context:set_clock(Clock, LimitContext))
|
||||
)
|
||||
of
|
||||
|
@ -10,7 +10,8 @@
|
||||
machinery,
|
||||
woody,
|
||||
scoper, % should be before any scoper event handler usage
|
||||
erl_health
|
||||
erl_health,
|
||||
dmt_client
|
||||
]},
|
||||
{mod, {limiter, []}},
|
||||
{env, []}
|
||||
|
@ -3,7 +3,7 @@
|
||||
-include_lib("limiter_proto/include/limproto_limiter_thrift.hrl").
|
||||
|
||||
-export([new/0]).
|
||||
-export([get/3]).
|
||||
-export([get/4]).
|
||||
-export([hold/3]).
|
||||
-export([commit/3]).
|
||||
-export([rollback/3]).
|
||||
@ -15,6 +15,7 @@
|
||||
-type client() :: woody_context:ctx().
|
||||
|
||||
-type limit_id() :: limproto_limiter_thrift:'LimitID'().
|
||||
-type limit_version() :: limproto_limiter_thrift:'Version'() | undefined.
|
||||
-type limit_change() :: limproto_limiter_thrift:'LimitChange'().
|
||||
-type limit_context() :: limproto_limiter_thrift:'LimitContext'().
|
||||
-type clock() :: limproto_limiter_thrift:'Clock'().
|
||||
@ -27,9 +28,11 @@
|
||||
new() ->
|
||||
woody_context:new().
|
||||
|
||||
-spec get(limit_id(), limit_context(), client()) -> woody:result() | no_return().
|
||||
get(LimitID, Context, Client) ->
|
||||
call('Get', {LimitID, clock(), Context}, Client).
|
||||
-spec get(limit_id(), limit_version(), limit_context(), client()) -> woody:result() | no_return().
|
||||
get(LimitID, undefined, Context, Client) ->
|
||||
call('Get', {LimitID, clock(), Context}, Client);
|
||||
get(LimitID, Version, Context, Client) ->
|
||||
call('GetVersioned', {LimitID, Version, clock(), Context}, Client).
|
||||
|
||||
-spec hold(limit_change(), limit_context(), client()) -> woody:result() | no_return().
|
||||
hold(LimitChange, Context, Client) ->
|
||||
|
@ -51,16 +51,38 @@ init_per_suite(Config) ->
|
||||
% dbg:tracer(), dbg:p(all, c),
|
||||
% dbg:tpl({machinery, '_', '_'}, x),
|
||||
Apps =
|
||||
genlib_app:start_application_with(limiter, [
|
||||
{service_clients, #{
|
||||
accounter => #{
|
||||
url => <<"http://shumway:8022/accounter">>
|
||||
},
|
||||
automaton => #{
|
||||
url => <<"http://machinegun:8022/v1/automaton">>
|
||||
}
|
||||
genlib_app:start_application_with(dmt_client, [
|
||||
% milliseconds
|
||||
{cache_update_interval, 5000},
|
||||
{max_cache_size, #{
|
||||
elements => 20,
|
||||
% 50Mb
|
||||
memory => 52428800
|
||||
}},
|
||||
{woody_event_handlers, [
|
||||
{scoper_woody_event_handler, #{
|
||||
event_handler_opts => #{
|
||||
formatter_opts => #{
|
||||
max_length => 1000
|
||||
}
|
||||
}
|
||||
}}
|
||||
]},
|
||||
{service_urls, #{
|
||||
'Repository' => <<"http://dominant:8022/v1/domain/repository">>,
|
||||
'RepositoryClient' => <<"http://dominant:8022/v1/domain/repository_client">>
|
||||
}}
|
||||
]),
|
||||
]) ++
|
||||
genlib_app:start_application_with(limiter, [
|
||||
{service_clients, #{
|
||||
accounter => #{
|
||||
url => <<"http://shumway:8022/accounter">>
|
||||
},
|
||||
automaton => #{
|
||||
url => <<"http://machinegun:8022/v1/automaton">>
|
||||
}
|
||||
}}
|
||||
]),
|
||||
[{apps, Apps}] ++ Config.
|
||||
|
||||
-spec end_per_suite(config()) -> _.
|
||||
|
@ -3,6 +3,7 @@
|
||||
-include_lib("stdlib/include/assert.hrl").
|
||||
-include_lib("common_test/include/ct.hrl").
|
||||
-include_lib("damsel/include/dmsl_base_thrift.hrl").
|
||||
-include_lib("damsel/include/dmsl_limiter_config_thrift.hrl").
|
||||
-include("lim_ct_helper.hrl").
|
||||
|
||||
-export([all/0]).
|
||||
@ -10,6 +11,8 @@
|
||||
-export([groups/0]).
|
||||
-export([init_per_suite/1]).
|
||||
-export([end_per_suite/1]).
|
||||
-export([init_per_group/2]).
|
||||
-export([end_per_group/2]).
|
||||
-export([init_per_testcase/2]).
|
||||
-export([end_per_testcase/2]).
|
||||
|
||||
@ -59,6 +62,7 @@
|
||||
all() ->
|
||||
[
|
||||
{group, default},
|
||||
{group, default_with_dominant},
|
||||
{group, withdrawals},
|
||||
{group, cashless},
|
||||
{group, idempotency}
|
||||
@ -91,6 +95,29 @@ groups() ->
|
||||
commit_with_email_scope_ok,
|
||||
commit_with_multi_scope_ok
|
||||
]},
|
||||
%% Repeats `default` group exept for `get_config_ok` and `commit_multirange_limit_ok`
|
||||
{default_with_dominant, [], [
|
||||
commit_with_long_change_id,
|
||||
commit_with_default_exchange,
|
||||
partial_commit_with_exchange,
|
||||
commit_with_exchange,
|
||||
commit_with_disabled_exchange,
|
||||
get_limit_ok,
|
||||
get_limit_notfound,
|
||||
hold_ok,
|
||||
commit_ok,
|
||||
rollback_ok,
|
||||
partial_zero_commit_rollbacks,
|
||||
refund_ok,
|
||||
commit_inexistent_hold_fails,
|
||||
partial_commit_inexistent_hold_fails,
|
||||
commit_with_payment_tool_scope_ok,
|
||||
commit_with_party_scope_ok,
|
||||
commit_with_provider_scope_ok,
|
||||
commit_with_terminal_scope_ok,
|
||||
commit_with_email_scope_ok,
|
||||
commit_with_multi_scope_ok
|
||||
]},
|
||||
{withdrawals, [parallel], [
|
||||
get_limit_ok,
|
||||
hold_ok,
|
||||
@ -123,30 +150,65 @@ init_per_suite(Config) ->
|
||||
% dbg:tracer(), dbg:p(all, c),
|
||||
% dbg:tpl({lim_handler, '_', '_'}, x),
|
||||
Apps =
|
||||
genlib_app:start_application_with(limiter, [
|
||||
{service_clients, #{
|
||||
accounter => #{
|
||||
url => <<"http://shumway:8022/accounter">>
|
||||
},
|
||||
automaton => #{
|
||||
url => <<"http://machinegun:8022/v1/automaton">>
|
||||
},
|
||||
xrates => #{
|
||||
url => <<"http://xrates:8022/xrates">>
|
||||
}
|
||||
genlib_app:start_application_with(dmt_client, [
|
||||
% milliseconds
|
||||
{cache_update_interval, 5000},
|
||||
{max_cache_size, #{
|
||||
elements => 20,
|
||||
% 50Mb
|
||||
memory => 52428800
|
||||
}},
|
||||
{exchange_factors, #{
|
||||
<<"DEFAULT">> => {1, 1},
|
||||
<<"USD">> => {105, 100},
|
||||
<<"EUR">> => {12, 10}
|
||||
{woody_event_handlers, [
|
||||
{scoper_woody_event_handler, #{
|
||||
event_handler_opts => #{
|
||||
formatter_opts => #{
|
||||
max_length => 1000
|
||||
}
|
||||
}
|
||||
}}
|
||||
]},
|
||||
{service_urls, #{
|
||||
'Repository' => <<"http://dominant:8022/v1/domain/repository">>,
|
||||
'RepositoryClient' => <<"http://dominant:8022/v1/domain/repository_client">>
|
||||
}}
|
||||
]),
|
||||
]) ++
|
||||
genlib_app:start_application_with(limiter, [
|
||||
{service_clients, #{
|
||||
accounter => #{
|
||||
url => <<"http://shumway:8022/accounter">>
|
||||
},
|
||||
automaton => #{
|
||||
url => <<"http://machinegun:8022/v1/automaton">>
|
||||
},
|
||||
xrates => #{
|
||||
url => <<"http://xrates:8022/xrates">>
|
||||
}
|
||||
}},
|
||||
{exchange_factors, #{
|
||||
<<"DEFAULT">> => {1, 1},
|
||||
<<"USD">> => {105, 100},
|
||||
<<"EUR">> => {12, 10}
|
||||
}}
|
||||
]),
|
||||
[{apps, Apps}] ++ Config.
|
||||
|
||||
-spec end_per_suite(config()) -> _.
|
||||
end_per_suite(Config) ->
|
||||
genlib_app:test_application_stop(?config(apps, Config)).
|
||||
|
||||
-spec init_per_group(test_case_name(), config()) -> config().
|
||||
init_per_group(default_with_dominant, C) ->
|
||||
set_limit_config_source(repository, C);
|
||||
init_per_group(_Name, C) ->
|
||||
set_limit_config_source(legacy, C).
|
||||
|
||||
set_limit_config_source(ConfigSource, C) ->
|
||||
[{limit_config_source, ConfigSource} | C].
|
||||
|
||||
-spec end_per_group(test_case_name(), config()) -> ok.
|
||||
end_per_group(_Name, _C) ->
|
||||
ok.
|
||||
|
||||
-spec init_per_testcase(test_case_name(), config()) -> config().
|
||||
init_per_testcase(Name, C) ->
|
||||
[
|
||||
@ -164,12 +226,16 @@ end_per_testcase(_Name, C) ->
|
||||
%%
|
||||
|
||||
-define(CHANGE_ID, 42).
|
||||
-define(LIMIT_CHANGE(ID), ?LIMIT_CHANGE(ID, ?CHANGE_ID)).
|
||||
-define(LIMIT_CHANGE(ID, ChangeID), #limiter_LimitChange{id = ID, change_id = gen_change_id(ID, ChangeID)}).
|
||||
-define(LIMIT_CHANGE(ID, ChangeID), ?LIMIT_CHANGE(ID, ChangeID, undefined)).
|
||||
-define(LIMIT_CHANGE(ID, ChangeID, Version), #limiter_LimitChange{
|
||||
id = ID,
|
||||
change_id = gen_change_id(ID, ChangeID),
|
||||
version = Version
|
||||
}).
|
||||
|
||||
-spec commit_with_long_change_id(config()) -> _.
|
||||
commit_with_long_change_id(C) ->
|
||||
ID = configure_limit(?time_range_month(), ?global(), C),
|
||||
{ID, Version} = configure_limit(?time_range_month(), ?global(), C),
|
||||
Context = ?payproc_ctx_invoice(?cash(10, <<"RUB">>)),
|
||||
LongBinary =
|
||||
<<
|
||||
@ -177,115 +243,122 @@ commit_with_long_change_id(C) ->
|
||||
" BinaryLongBinaryLongBinaryLongBinaryLongBinaryLongBinary"
|
||||
>>,
|
||||
ChangeID = <<LongBinary/binary, LongBinary/binary, LongBinary/binary, LongBinary/binary, LongBinary/binary>>,
|
||||
{ok, {vector, _}} = hold_and_commit(?LIMIT_CHANGE(ID, ChangeID), Context, ?config(client, C)),
|
||||
{ok, #limiter_Limit{amount = 10}} = lim_client:get(ID, Context, ?config(client, C)).
|
||||
{ok, {vector, _}} = hold_and_commit(?LIMIT_CHANGE(ID, ChangeID, Version), Context, ?config(client, C)),
|
||||
{ok, #limiter_Limit{amount = 10}} = lim_client:get(ID, Version, Context, ?config(client, C)).
|
||||
|
||||
-spec commit_with_default_exchange(config()) -> _.
|
||||
commit_with_default_exchange(C) ->
|
||||
ok = application:set_env(limiter, currency_conversion, enabled),
|
||||
Rational = #base_Rational{p = 1000000, q = 100},
|
||||
_ = mock_exchange(Rational, C),
|
||||
ID = configure_limit(?time_range_month(), ?global(), C),
|
||||
{ID, Version} = configure_limit(?time_range_month(), ?global(), C),
|
||||
Cost = ?cash(10000, <<"SOME_CURRENCY">>),
|
||||
Context = ?payproc_ctx_invoice(Cost),
|
||||
{ok, {vector, _}} = hold_and_commit(?LIMIT_CHANGE(ID), Context, ?config(client, C)),
|
||||
{ok, #limiter_Limit{amount = 10000}} = lim_client:get(ID, Context, ?config(client, C)).
|
||||
{ok, {vector, _}} = hold_and_commit(?LIMIT_CHANGE(ID, ?CHANGE_ID, Version), Context, ?config(client, C)),
|
||||
{ok, #limiter_Limit{amount = 10000}} = lim_client:get(ID, Version, Context, ?config(client, C)).
|
||||
|
||||
-spec partial_commit_with_exchange(config()) -> _.
|
||||
partial_commit_with_exchange(C) ->
|
||||
ok = application:set_env(limiter, currency_conversion, enabled),
|
||||
Rational = #base_Rational{p = 800000, q = 100},
|
||||
_ = mock_exchange(Rational, C),
|
||||
ID = configure_limit(?time_range_month(), ?global(), C),
|
||||
{ID, Version} = configure_limit(?time_range_month(), ?global(), C),
|
||||
Cost = ?cash(1000, <<"USD">>),
|
||||
CaptureCost = ?cash(800, <<"USD">>),
|
||||
Context = ?payproc_ctx_payment(Cost, CaptureCost),
|
||||
{ok, {vector, _}} = hold_and_commit(?LIMIT_CHANGE(ID), Context, ?config(client, C)),
|
||||
{ok, #limiter_Limit{amount = 8400}} = lim_client:get(ID, Context, ?config(client, C)).
|
||||
{ok, {vector, _}} = hold_and_commit(?LIMIT_CHANGE(ID, ?CHANGE_ID, Version), Context, ?config(client, C)),
|
||||
{ok, #limiter_Limit{amount = 8400}} = lim_client:get(ID, Version, Context, ?config(client, C)).
|
||||
|
||||
-spec commit_with_exchange(config()) -> _.
|
||||
commit_with_exchange(C) ->
|
||||
ok = application:set_env(limiter, currency_conversion, enabled),
|
||||
Rational = #base_Rational{p = 1000000, q = 100},
|
||||
_ = mock_exchange(Rational, C),
|
||||
ID = configure_limit(?time_range_month(), ?global(), C),
|
||||
{ID, Version} = configure_limit(?time_range_month(), ?global(), C),
|
||||
Cost = ?cash(10000, <<"USD">>),
|
||||
Context = ?payproc_ctx_invoice(Cost),
|
||||
{ok, {vector, _}} = hold_and_commit(?LIMIT_CHANGE(ID), Context, ?config(client, C)),
|
||||
{ok, #limiter_Limit{amount = 10500}} = lim_client:get(ID, Context, ?config(client, C)).
|
||||
{ok, {vector, _}} = hold_and_commit(?LIMIT_CHANGE(ID, ?CHANGE_ID, Version), Context, ?config(client, C)),
|
||||
{ok, #limiter_Limit{amount = 10500}} = lim_client:get(ID, Version, Context, ?config(client, C)).
|
||||
|
||||
-spec commit_with_disabled_exchange(config()) -> _.
|
||||
commit_with_disabled_exchange(C) ->
|
||||
ok = application:set_env(limiter, currency_conversion, disabled),
|
||||
Rational = #base_Rational{p = 1000000, q = 100},
|
||||
_ = mock_exchange(Rational, C),
|
||||
ID = configure_limit(?time_range_month(), ?global(), C),
|
||||
{ID, Version} = configure_limit(?time_range_month(), ?global(), C),
|
||||
Cost = ?cash(10000, <<"USD">>),
|
||||
Context = ?payproc_ctx_invoice(Cost),
|
||||
{exception, #base_InvalidRequest{}} =
|
||||
lim_client:hold(?LIMIT_CHANGE(ID), Context, ?config(client, C)).
|
||||
lim_client:hold(?LIMIT_CHANGE(ID, ?CHANGE_ID, Version), Context, ?config(client, C)).
|
||||
|
||||
-spec get_limit_ok(config()) -> _.
|
||||
get_limit_ok(C) ->
|
||||
ID = configure_limit(?time_range_month(), ?global(), C),
|
||||
{ID, Version} = configure_limit(?time_range_month(), ?global(), C),
|
||||
Context =
|
||||
case get_group_name(C) of
|
||||
default -> ?payproc_ctx_invoice(?cash(0));
|
||||
withdrawals -> ?wthdproc_ctx_withdrawal(?cash(0))
|
||||
withdrawals -> ?wthdproc_ctx_withdrawal(?cash(0));
|
||||
_Default -> ?payproc_ctx_invoice(?cash(0))
|
||||
end,
|
||||
?assertMatch(
|
||||
{ok, #limiter_Limit{amount = 0}},
|
||||
lim_client:get(ID, Context, ?config(client, C))
|
||||
lim_client:get(ID, Version, Context, ?config(client, C))
|
||||
).
|
||||
|
||||
-spec get_limit_notfound(config()) -> _.
|
||||
get_limit_notfound(C) ->
|
||||
Version =
|
||||
case proplists:get_value(limit_config_source, C, legacy) of
|
||||
legacy -> undefined;
|
||||
repository -> 0
|
||||
end,
|
||||
Context = ?payproc_ctx_invoice(?cash(0)),
|
||||
?assertEqual(
|
||||
{exception, #limiter_LimitNotFound{}},
|
||||
lim_client:get(<<"NOSUCHLIMITID">>, Context, ?config(client, C))
|
||||
lim_client:get(<<"NOSUCHLIMITID">>, Version, Context, ?config(client, C))
|
||||
).
|
||||
|
||||
-spec hold_ok(config()) -> _.
|
||||
hold_ok(C) ->
|
||||
ID = configure_limit(?time_range_month(), ?global(), C),
|
||||
{ID, Version} = configure_limit(?time_range_month(), ?global(), C),
|
||||
Context =
|
||||
case get_group_name(C) of
|
||||
default -> ?payproc_ctx_invoice(?cash(10));
|
||||
withdrawals -> ?wthdproc_ctx_withdrawal(?cash(10))
|
||||
withdrawals -> ?wthdproc_ctx_withdrawal(?cash(10));
|
||||
_Default -> ?payproc_ctx_invoice(?cash(10))
|
||||
end,
|
||||
{ok, {vector, #limiter_VectorClock{}}} = lim_client:hold(?LIMIT_CHANGE(ID), Context, ?config(client, C)),
|
||||
{ok, #limiter_Limit{}} = lim_client:get(ID, Context, ?config(client, C)).
|
||||
{ok, {vector, #limiter_VectorClock{}}} = lim_client:hold(
|
||||
?LIMIT_CHANGE(ID, ?CHANGE_ID, Version), Context, ?config(client, C)
|
||||
),
|
||||
{ok, #limiter_Limit{}} = lim_client:get(ID, Version, Context, ?config(client, C)).
|
||||
|
||||
-spec commit_ok(config()) -> _.
|
||||
commit_ok(C) ->
|
||||
ID = configure_limit(?time_range_month(), ?global(), C),
|
||||
{ID, Version} = configure_limit(?time_range_month(), ?global(), C),
|
||||
Context =
|
||||
case get_group_name(C) of
|
||||
default -> ?payproc_ctx_invoice(?cash(10, <<"RUB">>));
|
||||
withdrawals -> ?wthdproc_ctx_withdrawal(?cash(10, <<"RUB">>))
|
||||
withdrawals -> ?wthdproc_ctx_withdrawal(?cash(10, <<"RUB">>));
|
||||
_Default -> ?payproc_ctx_invoice(?cash(10, <<"RUB">>))
|
||||
end,
|
||||
{ok, {vector, _}} = hold_and_commit(?LIMIT_CHANGE(ID), Context, ?config(client, C)),
|
||||
{ok, #limiter_Limit{}} = lim_client:get(ID, Context, ?config(client, C)).
|
||||
{ok, {vector, _}} = hold_and_commit(?LIMIT_CHANGE(ID, ?CHANGE_ID, Version), Context, ?config(client, C)),
|
||||
{ok, #limiter_Limit{}} = lim_client:get(ID, Version, Context, ?config(client, C)).
|
||||
|
||||
-spec rollback_ok(config()) -> _.
|
||||
rollback_ok(C) ->
|
||||
ID = configure_limit(?time_range_week(), ?global(), C),
|
||||
{ID, Version} = configure_limit(?time_range_week(), ?global(), C),
|
||||
Context =
|
||||
case get_group_name(C) of
|
||||
default -> ?payproc_ctx_invoice(?cash(10, <<"RUB">>));
|
||||
withdrawals -> ?wthdproc_ctx_withdrawal(?cash(10, <<"RUB">>))
|
||||
withdrawals -> ?wthdproc_ctx_withdrawal(?cash(10, <<"RUB">>));
|
||||
_Default -> ?payproc_ctx_invoice(?cash(10, <<"RUB">>))
|
||||
end,
|
||||
Change = ?LIMIT_CHANGE(ID),
|
||||
Change = ?LIMIT_CHANGE(ID, ?CHANGE_ID, Version),
|
||||
{ok, {vector, _}} = lim_client:hold(Change, Context, ?config(client, C)),
|
||||
{ok, {vector, _}} = lim_client:rollback(Change, Context, ?config(client, C)).
|
||||
|
||||
-spec partial_zero_commit_rollbacks(config()) -> _.
|
||||
partial_zero_commit_rollbacks(C) ->
|
||||
ID = configure_limit(?time_range_week(), ?global(), C),
|
||||
{ID, Version} = configure_limit(?time_range_week(), ?global(), C),
|
||||
Context0 = ?payproc_ctx_payment(?cash(10), ?cash(10)),
|
||||
Context1 = ?payproc_ctx_payment(?cash(10), ?cash(0)),
|
||||
Change = ?LIMIT_CHANGE(ID),
|
||||
Change = ?LIMIT_CHANGE(ID, ?CHANGE_ID, Version),
|
||||
{ok, {vector, _}} = lim_client:hold(Change, Context0, ?config(client, C)),
|
||||
{ok, {vector, _}} = lim_client:commit(Change, Context1, ?config(client, C)),
|
||||
% NOTE
|
||||
@ -299,38 +372,38 @@ refund_ok(C) ->
|
||||
Client = ?config(client, C),
|
||||
OwnerID = <<"WWWcool Ltd">>,
|
||||
ShopID = <<"shop">>,
|
||||
ID = configure_limit(?time_range_day(), ?scope([?scope_party(), ?scope_shop()]), C),
|
||||
{ID, Version} = configure_limit(?time_range_day(), ?scope([?scope_party(), ?scope_shop()]), C),
|
||||
Context0 = ?payproc_ctx_payment(OwnerID, ShopID, ?cash(15), ?cash(15)),
|
||||
RefundContext1 = ?payproc_ctx_refund(OwnerID, ShopID, ?cash(10), ?cash(10), ?cash(10)),
|
||||
{ok, {vector, _}} = hold_and_commit(?LIMIT_CHANGE(ID, <<"Payment">>), Context0, Client),
|
||||
{ok, {vector, _}} = hold_and_commit(?LIMIT_CHANGE(ID, <<"Refund">>), RefundContext1, Client),
|
||||
{ok, #limiter_Limit{} = Limit2} = lim_client:get(ID, RefundContext1, Client),
|
||||
{ok, {vector, _}} = hold_and_commit(?LIMIT_CHANGE(ID, <<"Payment">>, Version), Context0, Client),
|
||||
{ok, {vector, _}} = hold_and_commit(?LIMIT_CHANGE(ID, <<"Refund">>, Version), RefundContext1, Client),
|
||||
{ok, #limiter_Limit{} = Limit2} = lim_client:get(ID, Version, RefundContext1, Client),
|
||||
?assertEqual(Limit2#limiter_Limit.amount, 5).
|
||||
|
||||
-spec get_config_ok(config()) -> _.
|
||||
get_config_ok(C) ->
|
||||
ID = configure_limit(?time_range_week(), ?global(), C),
|
||||
{ID, _Version} = configure_limit(?time_range_week(), ?global(), C),
|
||||
{ok, #config_LimitConfig{}} = lim_client:get_config(ID, ?config(client, C)).
|
||||
|
||||
-spec commit_inexistent_hold_fails(config()) -> _.
|
||||
commit_inexistent_hold_fails(C) ->
|
||||
ID = configure_limit(?time_range_week(), ?global(), C),
|
||||
{ID, Version} = configure_limit(?time_range_week(), ?global(), C),
|
||||
Context = ?payproc_ctx_payment(?cash(42), undefined),
|
||||
% NOTE
|
||||
% We do not expect `LimitChangeNotFound` here because we no longer reconcile with accounter
|
||||
% before requesting him to hold / commit.
|
||||
{exception, #base_InvalidRequest{}} =
|
||||
lim_client:commit(?LIMIT_CHANGE(ID), Context, ?config(client, C)).
|
||||
lim_client:commit(?LIMIT_CHANGE(ID, ?CHANGE_ID, Version), Context, ?config(client, C)).
|
||||
|
||||
-spec partial_commit_inexistent_hold_fails(config()) -> _.
|
||||
partial_commit_inexistent_hold_fails(C) ->
|
||||
ID = configure_limit(?time_range_week(), ?global(), C),
|
||||
{ID, Version} = configure_limit(?time_range_week(), ?global(), C),
|
||||
Context = ?payproc_ctx_payment(?cash(42), ?cash(21)),
|
||||
% NOTE
|
||||
% We do not expect `LimitChangeNotFound` here because we no longer reconcile with accounter
|
||||
% before requesting him to hold / commit.
|
||||
{exception, #base_InvalidRequest{}} =
|
||||
lim_client:commit(?LIMIT_CHANGE(ID), Context, ?config(client, C)).
|
||||
lim_client:commit(?LIMIT_CHANGE(ID, ?CHANGE_ID, Version), Context, ?config(client, C)).
|
||||
|
||||
-spec commit_multirange_limit_ok(config()) -> _.
|
||||
commit_multirange_limit_ok(C) ->
|
||||
@ -356,14 +429,14 @@ commit_multirange_limit_ok(C) ->
|
||||
{ok, _} = hold_and_commit(?LIMIT_CHANGE(ID, 2), ?payproc_ctx_payment(PaymentFeb), Client),
|
||||
PaymentApr = ?invoice_payment(?cash(44), ?cash(44), ?bank_card(), <<"2020-04-01T00:00:00Z">>),
|
||||
{ok, _} = hold_and_commit(?LIMIT_CHANGE(ID, 3), ?payproc_ctx_payment(PaymentApr), Client),
|
||||
{ok, #limiter_Limit{amount = 42}} = lim_client:get(ID, ?payproc_ctx_payment(PaymentJan), Client),
|
||||
{ok, #limiter_Limit{amount = 43}} = lim_client:get(ID, ?payproc_ctx_payment(PaymentFeb), Client),
|
||||
{ok, #limiter_Limit{amount = 44}} = lim_client:get(ID, ?payproc_ctx_payment(PaymentApr), Client).
|
||||
{ok, #limiter_Limit{amount = 42}} = lim_client:get(ID, undefined, ?payproc_ctx_payment(PaymentJan), Client),
|
||||
{ok, #limiter_Limit{amount = 43}} = lim_client:get(ID, undefined, ?payproc_ctx_payment(PaymentFeb), Client),
|
||||
{ok, #limiter_Limit{amount = 44}} = lim_client:get(ID, undefined, ?payproc_ctx_payment(PaymentApr), Client).
|
||||
|
||||
-spec commit_with_payment_tool_scope_ok(config()) -> _.
|
||||
commit_with_payment_tool_scope_ok(C) ->
|
||||
Client = ?config(client, C),
|
||||
ID = configure_limit(?time_range_week(), ?scope([?scope_payment_tool()]), ?turnover_metric_number(), C),
|
||||
{ID, Version} = configure_limit(?time_range_week(), ?scope([?scope_payment_tool()]), ?turnover_metric_number(), C),
|
||||
Context1 = ?payproc_ctx_payment(
|
||||
?invoice_payment(?cash(10), ?cash(10), ?bank_card(<<"Token">>, 2, 2022))
|
||||
),
|
||||
@ -379,13 +452,13 @@ commit_with_payment_tool_scope_ok(C) ->
|
||||
Context5 = ?payproc_ctx_payment(
|
||||
?invoice_payment(?cash(10), ?cash(10), ?digital_wallet(<<"ID42">>, <<"Pepal">>))
|
||||
),
|
||||
{ok, LimitState0} = lim_client:get(ID, Context1, Client),
|
||||
_ = hold_and_commit(?LIMIT_CHANGE(ID, 1), Context1, Client),
|
||||
_ = hold_and_commit(?LIMIT_CHANGE(ID, 2), Context2, Client),
|
||||
_ = hold_and_commit(?LIMIT_CHANGE(ID, 3), Context3, Client),
|
||||
_ = hold_and_commit(?LIMIT_CHANGE(ID, 4), Context4, Client),
|
||||
_ = hold_and_commit(?LIMIT_CHANGE(ID, 5), Context5, Client),
|
||||
{ok, LimitState1} = lim_client:get(ID, Context1, Client),
|
||||
{ok, LimitState0} = lim_client:get(ID, Version, Context1, Client),
|
||||
_ = hold_and_commit(?LIMIT_CHANGE(ID, 1, Version), Context1, Client),
|
||||
_ = hold_and_commit(?LIMIT_CHANGE(ID, 2, Version), Context2, Client),
|
||||
_ = hold_and_commit(?LIMIT_CHANGE(ID, 3, Version), Context3, Client),
|
||||
_ = hold_and_commit(?LIMIT_CHANGE(ID, 4, Version), Context4, Client),
|
||||
_ = hold_and_commit(?LIMIT_CHANGE(ID, 5, Version), Context5, Client),
|
||||
{ok, LimitState1} = lim_client:get(ID, Version, Context1, Client),
|
||||
?assertEqual(
|
||||
LimitState1#limiter_Limit.amount,
|
||||
LimitState0#limiter_Limit.amount + 1
|
||||
@ -396,66 +469,66 @@ commit_with_payment_tool_scope_ok(C) ->
|
||||
-spec commit_processes_idempotently(config()) -> _.
|
||||
commit_processes_idempotently(C) ->
|
||||
Client = ?config(client, C),
|
||||
ID = configure_limit(?time_range_week(), ?global(), C),
|
||||
{ID, Version} = configure_limit(?time_range_week(), ?global(), C),
|
||||
Context = ?payproc_ctx_payment(?cash(42), undefined),
|
||||
Change = ?LIMIT_CHANGE(ID),
|
||||
Change = ?LIMIT_CHANGE(ID, ?CHANGE_ID, Version),
|
||||
{ok, _} = lim_client:hold(Change, Context, Client),
|
||||
{ok, _} = lim_client:hold(Change, Context, Client),
|
||||
{ok, _} = lim_client:commit(Change, Context, Client),
|
||||
{ok, Limit = #limiter_Limit{amount = 42}} = lim_client:get(ID, Context, Client),
|
||||
{ok, Limit = #limiter_Limit{amount = 42}} = lim_client:get(ID, Version, Context, Client),
|
||||
{ok, _} = lim_client:commit(Change, Context, Client),
|
||||
{ok, Limit} = lim_client:get(ID, Context, Client).
|
||||
{ok, Limit} = lim_client:get(ID, Version, Context, Client).
|
||||
|
||||
-spec full_commit_processes_idempotently(config()) -> _.
|
||||
full_commit_processes_idempotently(C) ->
|
||||
Client = ?config(client, C),
|
||||
ID = configure_limit(?time_range_week(), ?global(), C),
|
||||
{ID, Version} = configure_limit(?time_range_week(), ?global(), C),
|
||||
Cost = ?cash(42),
|
||||
Context = ?payproc_ctx_payment(Cost, Cost),
|
||||
Change = ?LIMIT_CHANGE(ID),
|
||||
Change = ?LIMIT_CHANGE(ID, ?CHANGE_ID, Version),
|
||||
{ok, _} = lim_client:hold(Change, Context, Client),
|
||||
{ok, _} = lim_client:hold(Change, Context, Client),
|
||||
{ok, _} = lim_client:commit(Change, Context, Client),
|
||||
{ok, Limit = #limiter_Limit{amount = 42}} = lim_client:get(ID, Context, Client),
|
||||
{ok, Limit = #limiter_Limit{amount = 42}} = lim_client:get(ID, Version, Context, Client),
|
||||
{ok, _} = lim_client:commit(Change, Context, Client),
|
||||
{ok, Limit} = lim_client:get(ID, Context, Client).
|
||||
{ok, Limit} = lim_client:get(ID, Version, Context, Client).
|
||||
|
||||
-spec partial_commit_processes_idempotently(config()) -> _.
|
||||
partial_commit_processes_idempotently(C) ->
|
||||
Client = ?config(client, C),
|
||||
ID = configure_limit(?time_range_week(), ?global(), C),
|
||||
{ID, Version} = configure_limit(?time_range_week(), ?global(), C),
|
||||
Context = ?payproc_ctx_payment(?cash(42), ?cash(40)),
|
||||
Change = ?LIMIT_CHANGE(ID),
|
||||
Change = ?LIMIT_CHANGE(ID, ?CHANGE_ID, Version),
|
||||
{ok, _} = lim_client:hold(Change, Context, Client),
|
||||
{ok, _} = lim_client:hold(Change, Context, Client),
|
||||
{ok, _} = lim_client:commit(Change, Context, Client),
|
||||
{ok, Limit = #limiter_Limit{amount = 40}} = lim_client:get(ID, Context, Client),
|
||||
{ok, Limit = #limiter_Limit{amount = 40}} = lim_client:get(ID, Version, Context, Client),
|
||||
{ok, _} = lim_client:commit(Change, Context, Client),
|
||||
{ok, Limit = #limiter_Limit{amount = 40}} = lim_client:get(ID, Context, Client).
|
||||
{ok, Limit = #limiter_Limit{amount = 40}} = lim_client:get(ID, Version, Context, Client).
|
||||
|
||||
-spec rollback_processes_idempotently(config()) -> _.
|
||||
rollback_processes_idempotently(C) ->
|
||||
Client = ?config(client, C),
|
||||
ID = configure_limit(?time_range_week(), ?global(), C),
|
||||
{ID, Version} = configure_limit(?time_range_week(), ?global(), C),
|
||||
Context = ?payproc_ctx_payment(?cash(42), ?cash(0)),
|
||||
Change = ?LIMIT_CHANGE(ID),
|
||||
Change = ?LIMIT_CHANGE(ID, ?CHANGE_ID, Version),
|
||||
{ok, _} = lim_client:hold(Change, Context, Client),
|
||||
{ok, _} = lim_client:hold(Change, Context, Client),
|
||||
{ok, _} = lim_client:commit(Change, Context, Client),
|
||||
{ok, Limit = #limiter_Limit{amount = 0}} = lim_client:get(ID, Context, Client),
|
||||
{ok, Limit = #limiter_Limit{amount = 0}} = lim_client:get(ID, Version, Context, Client),
|
||||
{ok, _} = lim_client:commit(Change, Context, Client),
|
||||
{ok, Limit = #limiter_Limit{amount = 0}} = lim_client:get(ID, Context, Client).
|
||||
{ok, Limit = #limiter_Limit{amount = 0}} = lim_client:get(ID, Version, Context, Client).
|
||||
|
||||
%%
|
||||
|
||||
-spec commit_number_ok(config()) -> _.
|
||||
commit_number_ok(C) ->
|
||||
Client = ?config(client, C),
|
||||
ID = configure_limit(?time_range_week(), ?global(), ?turnover_metric_number(), C),
|
||||
{ID, Version} = configure_limit(?time_range_week(), ?global(), ?turnover_metric_number(), C),
|
||||
Context = ?payproc_ctx_payment(?cash(10), ?cash(10)),
|
||||
{ok, LimitState0} = lim_client:get(ID, Context, Client),
|
||||
_ = hold_and_commit(?LIMIT_CHANGE(ID), Context, Client),
|
||||
{ok, LimitState1} = lim_client:get(ID, Context, Client),
|
||||
{ok, LimitState0} = lim_client:get(ID, Version, Context, Client),
|
||||
_ = hold_and_commit(?LIMIT_CHANGE(ID, ?CHANGE_ID, Version), Context, Client),
|
||||
{ok, LimitState1} = lim_client:get(ID, Version, Context, Client),
|
||||
?assertEqual(
|
||||
LimitState1#limiter_Limit.amount,
|
||||
LimitState0#limiter_Limit.amount + 1
|
||||
@ -464,12 +537,12 @@ commit_number_ok(C) ->
|
||||
-spec rollback_number_ok(config()) -> _.
|
||||
rollback_number_ok(C) ->
|
||||
Client = ?config(client, C),
|
||||
ID = configure_limit(?time_range_week(), ?global(), ?turnover_metric_number(), C),
|
||||
{ID, Version} = configure_limit(?time_range_week(), ?global(), ?turnover_metric_number(), C),
|
||||
Context = ?payproc_ctx_payment(?cash(10), ?cash(10)),
|
||||
ContextRollback = ?payproc_ctx_payment(?cash(10), ?cash(0)),
|
||||
{ok, LimitState0} = lim_client:get(ID, Context, Client),
|
||||
_ = hold_and_commit(?LIMIT_CHANGE(ID), Context, ContextRollback, Client),
|
||||
{ok, LimitState1} = lim_client:get(ID, Context, Client),
|
||||
{ok, LimitState0} = lim_client:get(ID, Version, Context, Client),
|
||||
_ = hold_and_commit(?LIMIT_CHANGE(ID, ?CHANGE_ID, Version), Context, ContextRollback, Client),
|
||||
{ok, LimitState1} = lim_client:get(ID, Version, Context, Client),
|
||||
?assertEqual(
|
||||
LimitState1#limiter_Limit.amount,
|
||||
LimitState0#limiter_Limit.amount
|
||||
@ -478,16 +551,16 @@ rollback_number_ok(C) ->
|
||||
-spec commit_refund_keep_number_unchanged(config()) -> _.
|
||||
commit_refund_keep_number_unchanged(C) ->
|
||||
Client = ?config(client, C),
|
||||
ID = configure_limit(?time_range_week(), ?global(), ?turnover_metric_number(), C),
|
||||
{ID, Version} = configure_limit(?time_range_week(), ?global(), ?turnover_metric_number(), C),
|
||||
Cost = ?cash(10),
|
||||
CaptureCost = ?cash(8),
|
||||
RefundCost = ?cash(5),
|
||||
PaymentContext = ?payproc_ctx_payment(<<"OWNER">>, <<"SHOP">>, Cost, CaptureCost),
|
||||
RefundContext = ?payproc_ctx_refund(<<"OWNER">>, <<"SHOP">>, Cost, CaptureCost, RefundCost),
|
||||
{ok, LimitState0} = lim_client:get(ID, PaymentContext, Client),
|
||||
_ = hold_and_commit(?LIMIT_CHANGE(ID, 1), PaymentContext, Client),
|
||||
_ = hold_and_commit(?LIMIT_CHANGE(ID, 2), RefundContext, Client),
|
||||
{ok, LimitState1} = lim_client:get(ID, PaymentContext, Client),
|
||||
{ok, LimitState0} = lim_client:get(ID, Version, PaymentContext, Client),
|
||||
_ = hold_and_commit(?LIMIT_CHANGE(ID, 1, Version), PaymentContext, Client),
|
||||
_ = hold_and_commit(?LIMIT_CHANGE(ID, 2, Version), RefundContext, Client),
|
||||
{ok, LimitState1} = lim_client:get(ID, Version, PaymentContext, Client),
|
||||
?assertEqual(
|
||||
% Expected to be the same because refund decreases counter given limit config
|
||||
LimitState1#limiter_Limit.amount,
|
||||
@ -497,12 +570,12 @@ commit_refund_keep_number_unchanged(C) ->
|
||||
-spec partial_commit_number_counts_as_single_op(config()) -> _.
|
||||
partial_commit_number_counts_as_single_op(C) ->
|
||||
Client = ?config(client, C),
|
||||
ID = configure_limit(?time_range_week(), ?global(), ?turnover_metric_number(), C),
|
||||
{ID, Version} = configure_limit(?time_range_week(), ?global(), ?turnover_metric_number(), C),
|
||||
Context = ?payproc_ctx_payment(?cash(10), ?cash(10)),
|
||||
ContextPartial = ?payproc_ctx_payment(?cash(10), ?cash(5)),
|
||||
{ok, LimitState0} = lim_client:get(ID, Context, Client),
|
||||
_ = hold_and_commit(?LIMIT_CHANGE(ID), Context, ContextPartial, Client),
|
||||
{ok, LimitState1} = lim_client:get(ID, Context, Client),
|
||||
{ok, LimitState0} = lim_client:get(ID, Version, Context, Client),
|
||||
_ = hold_and_commit(?LIMIT_CHANGE(ID, ?CHANGE_ID, Version), Context, ContextPartial, Client),
|
||||
{ok, LimitState1} = lim_client:get(ID, Version, Context, Client),
|
||||
?assertEqual(
|
||||
LimitState1#limiter_Limit.amount,
|
||||
LimitState0#limiter_Limit.amount + 1
|
||||
@ -523,40 +596,40 @@ commit_with_terminal_scope_ok(C) ->
|
||||
_ = commit_with_some_scope(?scope([?scope_terminal()]), C).
|
||||
|
||||
commit_with_some_scope(Scope, C) ->
|
||||
ID = configure_limit(?time_range_month(), Scope, C),
|
||||
{ID, Version} = configure_limit(?time_range_month(), Scope, C),
|
||||
Context =
|
||||
case get_group_name(C) of
|
||||
default -> ?payproc_ctx_payment(?cash(10, <<"RUB">>), ?cash(10, <<"RUB">>));
|
||||
withdrawals -> ?wthdproc_ctx_withdrawal(?cash(10, <<"RUB">>))
|
||||
withdrawals -> ?wthdproc_ctx_withdrawal(?cash(10, <<"RUB">>));
|
||||
_Default -> ?payproc_ctx_payment(?cash(10, <<"RUB">>), ?cash(10, <<"RUB">>))
|
||||
end,
|
||||
{ok, {vector, _}} = hold_and_commit(?LIMIT_CHANGE(ID), Context, ?config(client, C)),
|
||||
{ok, #limiter_Limit{}} = lim_client:get(ID, Context, ?config(client, C)).
|
||||
{ok, {vector, _}} = hold_and_commit(?LIMIT_CHANGE(ID, ?CHANGE_ID, Version), Context, ?config(client, C)),
|
||||
{ok, #limiter_Limit{}} = lim_client:get(ID, Version, Context, ?config(client, C)).
|
||||
|
||||
-spec commit_with_email_scope_ok(config()) -> _.
|
||||
commit_with_email_scope_ok(C) ->
|
||||
ID = configure_limit(?time_range_month(), ?scope([?scope_payer_contact_email()]), C),
|
||||
{ID, Version} = configure_limit(?time_range_month(), ?scope([?scope_payer_contact_email()]), C),
|
||||
Context = ?payproc_ctx_payment(?cash(10, <<"RUB">>), ?cash(10, <<"RUB">>)),
|
||||
{ok, {vector, _}} = hold_and_commit(?LIMIT_CHANGE(ID), Context, ?config(client, C)),
|
||||
{ok, #limiter_Limit{}} = lim_client:get(ID, Context, ?config(client, C)).
|
||||
{ok, {vector, _}} = hold_and_commit(?LIMIT_CHANGE(ID, ?CHANGE_ID, Version), Context, ?config(client, C)),
|
||||
{ok, #limiter_Limit{}} = lim_client:get(ID, Version, Context, ?config(client, C)).
|
||||
|
||||
-spec commit_with_identity_scope_ok(config()) -> _.
|
||||
commit_with_identity_scope_ok(C) ->
|
||||
ID = configure_limit(?time_range_month(), ?scope([?scope_identity()]), C),
|
||||
{ID, Version} = configure_limit(?time_range_month(), ?scope([?scope_identity()]), C),
|
||||
Context = ?wthdproc_ctx_withdrawal(?cash(10, <<"RUB">>)),
|
||||
{ok, {vector, _}} = hold_and_commit(?LIMIT_CHANGE(ID), Context, ?config(client, C)),
|
||||
{ok, #limiter_Limit{}} = lim_client:get(ID, Context, ?config(client, C)).
|
||||
{ok, {vector, _}} = hold_and_commit(?LIMIT_CHANGE(ID, ?CHANGE_ID, Version), Context, ?config(client, C)),
|
||||
{ok, #limiter_Limit{}} = lim_client:get(ID, Version, Context, ?config(client, C)).
|
||||
|
||||
-spec commit_with_wallet_scope_ok(config()) -> _.
|
||||
commit_with_wallet_scope_ok(C) ->
|
||||
ID = configure_limit(?time_range_month(), ?scope([?scope_wallet()]), C),
|
||||
{ID, Version} = configure_limit(?time_range_month(), ?scope([?scope_wallet()]), C),
|
||||
Context = ?wthdproc_ctx_withdrawal(?cash(10, <<"RUB">>)),
|
||||
{ok, {vector, _}} = hold_and_commit(?LIMIT_CHANGE(ID), Context, ?config(client, C)),
|
||||
{ok, #limiter_Limit{}} = lim_client:get(ID, Context, ?config(client, C)).
|
||||
{ok, {vector, _}} = hold_and_commit(?LIMIT_CHANGE(ID, ?CHANGE_ID, Version), Context, ?config(client, C)),
|
||||
{ok, #limiter_Limit{}} = lim_client:get(ID, Version, Context, ?config(client, C)).
|
||||
|
||||
-spec commit_with_multi_scope_ok(config()) -> _.
|
||||
commit_with_multi_scope_ok(C) ->
|
||||
Client = ?config(client, C),
|
||||
ID = configure_limit(?time_range_week(), ?scope([?scope_provider(), ?scope_payment_tool()]), C),
|
||||
{ID, Version} = configure_limit(?time_range_week(), ?scope([?scope_provider(), ?scope_payment_tool()]), C),
|
||||
Context1 = ?payproc_ctx_payment(
|
||||
?invoice_payment(?cash(10), ?cash(10), ?bank_card(<<"Token">>, 2, 2022))
|
||||
),
|
||||
@ -572,13 +645,13 @@ commit_with_multi_scope_ok(C) ->
|
||||
Context5 = ?payproc_ctx_payment(
|
||||
?invoice_payment(?cash(10), ?cash(10), ?digital_wallet(<<"ID42">>, <<"Pepal">>))
|
||||
),
|
||||
{ok, LimitState0} = lim_client:get(ID, Context1, Client),
|
||||
_ = hold_and_commit(?LIMIT_CHANGE(ID, 1), Context1, Client),
|
||||
_ = hold_and_commit(?LIMIT_CHANGE(ID, 2), Context2, Client),
|
||||
_ = hold_and_commit(?LIMIT_CHANGE(ID, 3), Context3, Client),
|
||||
_ = hold_and_commit(?LIMIT_CHANGE(ID, 4), Context4, Client),
|
||||
_ = hold_and_commit(?LIMIT_CHANGE(ID, 5), Context5, Client),
|
||||
{ok, LimitState1} = lim_client:get(ID, Context1, Client),
|
||||
{ok, LimitState0} = lim_client:get(ID, Version, Context1, Client),
|
||||
_ = hold_and_commit(?LIMIT_CHANGE(ID, 1, Version), Context1, Client),
|
||||
_ = hold_and_commit(?LIMIT_CHANGE(ID, 2, Version), Context2, Client),
|
||||
_ = hold_and_commit(?LIMIT_CHANGE(ID, 3, Version), Context3, Client),
|
||||
_ = hold_and_commit(?LIMIT_CHANGE(ID, 4, Version), Context4, Client),
|
||||
_ = hold_and_commit(?LIMIT_CHANGE(ID, 5, Version), Context5, Client),
|
||||
{ok, LimitState1} = lim_client:get(ID, Version, Context1, Client),
|
||||
?assertEqual(
|
||||
LimitState1#limiter_Limit.amount,
|
||||
LimitState0#limiter_Limit.amount + 10
|
||||
@ -609,7 +682,7 @@ configure_limit(TimeRange, Scope, Metric, C) ->
|
||||
withdrawals -> ?ctx_type_wthdproc();
|
||||
_Default -> ?ctx_type_payproc()
|
||||
end,
|
||||
Params = #config_LimitConfigParams{
|
||||
CreateParams = #config_LimitConfigParams{
|
||||
id = ID,
|
||||
started_at = <<"2000-01-01T00:00:00Z">>,
|
||||
time_range_type = TimeRange,
|
||||
@ -619,8 +692,16 @@ configure_limit(TimeRange, Scope, Metric, C) ->
|
||||
context_type = ContextType,
|
||||
op_behaviour = ?op_behaviour(?op_subtraction())
|
||||
},
|
||||
{ok, _LimitConfig} = lim_client:create_config(Params, ?config(client, C)),
|
||||
ID.
|
||||
ConfigSource = proplists:get_value(limit_config_source, C, legacy),
|
||||
put_config_into_repository(ConfigSource, CreateParams, ?config(client, C)).
|
||||
|
||||
put_config_into_repository(legacy, CreateParams = #config_LimitConfigParams{id = ID}, Client) ->
|
||||
{ok, _LimitConfig} = lim_client:create_config(CreateParams, Client),
|
||||
{ID, undefined};
|
||||
put_config_into_repository(repository, CreateParams = #config_LimitConfigParams{id = ID}, _Client) ->
|
||||
LimitConfigObject = mk_limit_config_object(CreateParams),
|
||||
Version = dmt_client:insert({limit_config, LimitConfigObject}),
|
||||
{ID, Version}.
|
||||
|
||||
gen_unique_id(Prefix) ->
|
||||
genlib:format("~s/~B", [Prefix, lim_time:now()]).
|
||||
@ -628,3 +709,67 @@ gen_unique_id(Prefix) ->
|
||||
get_group_name(C) ->
|
||||
GroupProps = ?config(tc_group_properties, C),
|
||||
proplists:get_value(name, GroupProps).
|
||||
|
||||
mk_limit_config_object(#config_LimitConfigParams{
|
||||
id = ID,
|
||||
started_at = StartedAt,
|
||||
time_range_type = TimeRange,
|
||||
shard_size = ShardSize,
|
||||
type = Type,
|
||||
scope = Scope,
|
||||
context_type = ContextType,
|
||||
op_behaviour = OpBehaviour
|
||||
}) ->
|
||||
#domain_LimitConfigObject{
|
||||
ref = #domain_LimitConfigRef{id = ID},
|
||||
data = #limiter_config_LimitConfig{
|
||||
processor_type = <<"TurnoverProcessor">>,
|
||||
created_at = StartedAt,
|
||||
started_at = StartedAt,
|
||||
shard_size = ShardSize,
|
||||
time_range_type = translate_time_range_type(TimeRange),
|
||||
context_type = translate_tuple_record(ContextType, "config", "limiter_config"),
|
||||
type = maybe_apply(Type, fun translate_type/1),
|
||||
scopes = maybe_apply(Scope, fun translate_scope/1),
|
||||
description = <<"Description">>,
|
||||
op_behaviour = maybe_apply(OpBehaviour, fun mk_op_behaviour/1)
|
||||
}
|
||||
}.
|
||||
|
||||
mk_op_behaviour(#config_OperationLimitBehaviour{invoice_payment_refund = PaymentRefund}) ->
|
||||
#limiter_config_OperationLimitBehaviour{
|
||||
invoice_payment_refund = maybe_apply(PaymentRefund, fun(Item) ->
|
||||
translate_tuple_record(Item, "config", "limiter_config")
|
||||
end)
|
||||
}.
|
||||
|
||||
%% Interval type is never used in this test suite. To appease dialyzer this clause is commented out.
|
||||
% translate_time_range_type({interval, #timerange_TimeRangeTypeInterval{amount = Amount}}) ->
|
||||
% {interval, #limiter_config_TimeRangeTypeInterval{amount = Amount}};
|
||||
translate_time_range_type({calendar, CalendarType}) ->
|
||||
{calendar, translate_tuple_record(CalendarType, "timerange", "limiter_config")}.
|
||||
|
||||
translate_type({turnover, #config_LimitTypeTurnover{metric = Metric}}) ->
|
||||
{turnover, #limiter_config_LimitTypeTurnover{metric = translate_tuple_record(Metric, "config", "limiter_config")}}.
|
||||
|
||||
translate_scope({single, ScopeType}) ->
|
||||
ordsets:from_list([translate_scope_type(ScopeType)]);
|
||||
translate_scope({multi, ScopeTypes}) ->
|
||||
ordsets:from_list(lists:map(fun translate_scope_type/1, ordsets:to_list(ScopeTypes))).
|
||||
|
||||
translate_scope_type({Scope, #config_LimitScopeEmptyDetails{}}) ->
|
||||
{Scope, #limiter_config_LimitScopeEmptyDetails{}}.
|
||||
|
||||
maybe_apply(undefined, _) ->
|
||||
undefined;
|
||||
maybe_apply(Value, Fun) ->
|
||||
Fun(Value).
|
||||
|
||||
translate_tuple_record({Type, Record}, OldRecordPrefix, NewRecordPrefix) ->
|
||||
{Type, change_record_name_prefix(Record, OldRecordPrefix, NewRecordPrefix)}.
|
||||
|
||||
change_record_name_prefix(Record, OldPrefix, NewPrefix) ->
|
||||
RecordName = atom_to_list(element(1, Record)),
|
||||
[OldPrefix, TypeName] = string:split(RecordName, "_", trailing),
|
||||
NewRecordName = list_to_existing_atom(NewPrefix ++ "_" ++ TypeName),
|
||||
setelement(1, Record, NewRecordName).
|
||||
|
14
compose.yml
14
compose.yml
@ -15,11 +15,25 @@ services:
|
||||
working_dir: $PWD
|
||||
command: /sbin/init
|
||||
depends_on:
|
||||
dominant:
|
||||
condition: service_healthy
|
||||
machinegun:
|
||||
condition: service_healthy
|
||||
shumway:
|
||||
condition: service_healthy
|
||||
|
||||
dominant:
|
||||
image: ghcr.io/valitydev/dominant:sha-e0afa44
|
||||
command: /opt/dominant/bin/dominant foreground
|
||||
depends_on:
|
||||
machinegun:
|
||||
condition: service_healthy
|
||||
healthcheck:
|
||||
test: "/opt/dominant/bin/dominant ping"
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 10
|
||||
|
||||
machinegun:
|
||||
image: ghcr.io/valitydev/machinegun:sha-7e785cd
|
||||
volumes:
|
||||
|
@ -73,6 +73,29 @@
|
||||
}}
|
||||
]},
|
||||
|
||||
{dmt_client, [
|
||||
% milliseconds
|
||||
{cache_update_interval, 5000},
|
||||
{max_cache_size, #{
|
||||
elements => 20,
|
||||
% 50Mb
|
||||
memory => 52428800
|
||||
}},
|
||||
{woody_event_handlers, [
|
||||
{scoper_woody_event_handler, #{
|
||||
event_handler_opts => #{
|
||||
formatter_opts => #{
|
||||
max_length => 1000
|
||||
}
|
||||
}
|
||||
}}
|
||||
]},
|
||||
{service_urls, #{
|
||||
'Repository' => <<"http://dominant:8022/v1/domain/repository">>,
|
||||
'RepositoryClient' => <<"http://dominant:8022/v1/domain/repository_client">>
|
||||
}}
|
||||
]},
|
||||
|
||||
{kernel, [
|
||||
{logger_sasl_compatible, false},
|
||||
{logger_level, debug},
|
||||
|
@ -26,13 +26,15 @@
|
||||
|
||||
%% Common project dependencies.
|
||||
{deps, [
|
||||
{damsel, {git, "https://github.com/valitydev/damsel.git", {branch, "master"}}},
|
||||
{limiter_proto, {git, "https://github.com/valitydev/limiter-proto.git", {branch, "master"}}},
|
||||
{xrates_proto, {git, "https://github.com/valitydev/xrates-proto.git", {branch, "master"}}},
|
||||
{machinery, {git, "https://github.com/valitydev/machinery-erlang.git", {branch, "master"}}},
|
||||
{erl_health, {git, "https://github.com/valitydev/erlang-health.git", {branch, "master"}}},
|
||||
{genlib, {git, "https://github.com/valitydev/genlib.git", {branch, "master"}}},
|
||||
{scoper, {git, "https://github.com/valitydev/scoper.git", {branch, "master"}}},
|
||||
{woody, {git, "https://github.com/valitydev/woody_erlang.git", {branch, "master"}}}
|
||||
{woody, {git, "https://github.com/valitydev/woody_erlang.git", {branch, "master"}}},
|
||||
{dmt_client, {git, "https://github.com/valitydev/dmt_client.git", {branch, "master"}}}
|
||||
]}.
|
||||
|
||||
%% XRef checks
|
||||
|
12
rebar.lock
12
rebar.lock
@ -9,7 +9,15 @@
|
||||
{<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.11.0">>},2},
|
||||
{<<"damsel">>,
|
||||
{git,"https://github.com/valitydev/damsel.git",
|
||||
{ref,"33c5665571042440ccec109735481d8c13704ec2"}},
|
||||
{ref,"9859ca2843ad1617a0bf8549c125a7e94d1d54b7"}},
|
||||
0},
|
||||
{<<"dmt_client">>,
|
||||
{git,"https://github.com/valitydev/dmt_client.git",
|
||||
{ref,"19a8ded17c05140f663c7b8b30450d9a1da4f53e"}},
|
||||
0},
|
||||
{<<"dmt_core">>,
|
||||
{git,"https://github.com/valitydev/dmt-core.git",
|
||||
{ref,"75841332fe0b40a77da0c12ea8d5dbb994da8e82"}},
|
||||
1},
|
||||
{<<"erl_health">>,
|
||||
{git,"https://github.com/valitydev/erlang-health.git",
|
||||
@ -25,7 +33,7 @@
|
||||
{<<"jsx">>,{pkg,<<"jsx">>,<<"3.1.0">>},1},
|
||||
{<<"limiter_proto">>,
|
||||
{git,"https://github.com/valitydev/limiter-proto.git",
|
||||
{ref,"31de59b17ad20e426b158ace6097e35330926bea"}},
|
||||
{ref,"9b76200a957c0e91bcdf6f16dfbab90d38a3f173"}},
|
||||
0},
|
||||
{<<"machinery">>,
|
||||
{git,"https://github.com/valitydev/machinery-erlang.git",
|
||||
|
@ -15,6 +15,10 @@ namespaces:
|
||||
processor:
|
||||
url: http://limiter:8022/v1/stateproc/lim/range_v1
|
||||
pool_size: 500
|
||||
domain-config:
|
||||
processor:
|
||||
url: http://dominant:8022/v1/stateproc
|
||||
pool_size: 300
|
||||
|
||||
storage:
|
||||
type: memory
|
||||
|
Loading…
Reference in New Issue
Block a user