Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 16 additions & 9 deletions apps/hellgate/src/hg_limiter.erl
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@
id = ShopID
}).

%% Very specific errors to crutch around
-define(POSTING_PLAN_NOT_FOUND(ID), #base_InvalidRequest{errors = [<<"Posting plan not found: ", ID/binary>>]}).
-define(OPERATION_NOT_FOUND, #base_InvalidRequest{errors = [<<"OperationNotFound">>]}).

-spec get_turnover_limits(turnover_selector() | undefined) -> [turnover_limit()].
get_turnover_limits(undefined) ->
[];
Expand Down Expand Up @@ -279,13 +283,19 @@ rollback_payment_limits(TurnoverLimits, Invoice, Payment, Route, Iter, Flags) ->
{LegacyTurnoverLimits, BatchTurnoverLimits} = split_turnover_limits_by_available_limiter_api(TurnoverLimits),
ok = legacy_rollback_payment_limits(Context, LegacyTurnoverLimits, Invoice, Payment, Route, Iter, Flags),
OperationIdSegments = make_route_operation_segments(Invoice, Payment, Route, Iter),
ok = batch_rollback_limits(Context, BatchTurnoverLimits, OperationIdSegments).
ok = batch_rollback_limits(Context, BatchTurnoverLimits, OperationIdSegments, Flags).

batch_rollback_limits(_Context, [], _OperationIdSegments) ->
batch_rollback_limits(_Context, [], _OperationIdSegments, _Flags) ->
ok;
batch_rollback_limits(Context, TurnoverLimits, OperationIdSegments) ->
batch_rollback_limits(Context, TurnoverLimits, OperationIdSegments, Flags) ->
{LimitRequest, _} = prepare_limit_request(TurnoverLimits, OperationIdSegments),
hg_limiter_client:rollback_batch(LimitRequest, Context).
IgnoreError = lists:member(ignore_not_found, Flags) orelse lists:member(ignore_business_error, Flags),
try
ok = hg_limiter_client:rollback_batch(LimitRequest, Context)
catch
error:(?OPERATION_NOT_FOUND) when IgnoreError =:= true ->
ok
end.

legacy_rollback_payment_limits(Context, TurnoverLimits, Invoice, Payment, Route, Iter, Flags) ->
ChangeIDs = [
Expand All @@ -302,7 +312,7 @@ rollback_shop_limits(TurnoverLimits, Party, Shop, Invoice, Payment, Flags) ->
{LegacyTurnoverLimits, BatchTurnoverLimits} = split_turnover_limits_by_available_limiter_api(TurnoverLimits),
ok = legacy_rollback_shop_limits(Context, LegacyTurnoverLimits, Party, Shop, Invoice, Payment, Flags),
OperationIdSegments = make_shop_operation_segments(Party, Shop, Invoice, Payment),
ok = batch_rollback_limits(Context, BatchTurnoverLimits, OperationIdSegments).
ok = batch_rollback_limits(Context, BatchTurnoverLimits, OperationIdSegments, Flags).

legacy_rollback_shop_limits(Context, TurnoverLimits, Party, Shop, Invoice, Payment, Flags) ->
ChangeIDs = [construct_shop_change_id(Party, Shop, Invoice, Payment)],
Expand All @@ -315,7 +325,7 @@ rollback_refund_limits(TurnoverLimits, Invoice, Payment, Refund, Route) ->
{LegacyTurnoverLimits, BatchTurnoverLimits} = split_turnover_limits_by_available_limiter_api(TurnoverLimits),
ok = legacy_rollback_refund_limits(Context, LegacyTurnoverLimits, Invoice, Payment, Refund),
OperationIdSegments = make_refund_operation_segments(Invoice, Payment, Refund),
ok = batch_rollback_limits(Context, BatchTurnoverLimits, OperationIdSegments).
ok = batch_rollback_limits(Context, BatchTurnoverLimits, OperationIdSegments, []).

legacy_rollback_refund_limits(Context, TurnoverLimits, Invoice, Payment, Refund) ->
ChangeIDs = [construct_refund_change_id(Invoice, Payment, Refund)],
Expand All @@ -342,9 +352,6 @@ process_changes(LimitChangesQueues, WithFun, Clock, Context, Flags) ->
LimitChangesQueues
).

%% Very specific error to crutch around
-define(POSTING_PLAN_NOT_FOUND(ID), #base_InvalidRequest{errors = [<<"Posting plan not found: ", ID/binary>>]}).

process_changes_try_wrap([LimitChange], WithFun, Clock, Context, Flags) ->
IgnoreNotFound = lists:member(ignore_not_found, Flags),
#limiter_LimitChange{change_id = ChangeID} = LimitChange,
Expand Down
63 changes: 63 additions & 0 deletions apps/hellgate/test/hg_invoice_tests_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,7 @@
-export([repair_fulfill_session_on_captured_succeeded/1]).

-export([repair_fail_routing_succeeded/1]).
-export([repair_fail_routing_not_existent_operation/1]).
-export([repair_fail_cash_flow_building_succeeded/1]).

-export([consistent_account_balances/1]).
Expand Down Expand Up @@ -489,6 +490,7 @@ groups() ->
]},
{repair_preproc_w_limits, [], [
repair_fail_routing_succeeded,
repair_fail_routing_not_existent_operation,
repair_fail_cash_flow_building_succeeded
]},
{allocation, [parallel], [
Expand Down Expand Up @@ -728,6 +730,8 @@ init_per_testcase(Name = repair_fail_routing_succeeded, C) ->
fun override_check_limits/5
),
init_per_testcase_(Name, C);
init_per_testcase(Name = repair_fail_routing_not_existent_operation, C) ->
init_per_testcase_(Name, override_terms_limit_reference(?prv(5), C));
init_per_testcase(Name = repair_fail_cash_flow_building_succeeded, C) ->
meck:expect(
hg_cashflow_utils,
Expand Down Expand Up @@ -760,6 +764,27 @@ override_domain_fixture(Fixture, C) ->
override_domain_fixture(Fixture, Name, C) ->
init_per_testcase_(Name, override_domain_fixture(Fixture, C)).

override_terms_limit_reference(ProviderRef, C) ->
override_domain_fixture(
fun(Revision, _C) ->
[
change_provider_payments_provision_terms(ProviderRef, Revision, fun(PaymentsProvisionTerms) ->
PaymentsProvisionTerms#domain_PaymentsProvisionTerms{
turnover_limits =
{value, [
#domain_TurnoverLimit{
id = <<"NOT_EXISTENT_LIMIT_ID">>,
upper_boundary = ?LIMIT_UPPER_BOUNDARY,
domain_revision = Revision
}
]}
}
end)
]
end,
C
).

init_per_testcase_(Name, C) ->
ApiClient = hg_ct_helper:create_client(cfg(root_url, C)),
Client = hg_client_invoicing:start_link(ApiClient),
Expand All @@ -778,6 +803,8 @@ trace_testcase(Name, C) ->
end_per_testcase(repair_fail_routing_succeeded, C) ->
meck:unload(hg_limiter),
end_per_testcase(default, C);
end_per_testcase(repair_fail_routing_not_existent_operation, C) ->
end_per_testcase(default, C);
end_per_testcase(repair_fail_cash_flow_building_succeeded, C) ->
meck:unload(hg_cashflow_utils),
end_per_testcase(default, C);
Expand Down Expand Up @@ -5798,6 +5825,42 @@ repair_fail_routing_succeeded(C) ->
InvoiceID, fail_pre_processing, Client
).

-spec repair_fail_routing_not_existent_operation(config()) -> test_return().
repair_fail_routing_not_existent_operation(C) ->
RootUrl = cfg(root_url, C),
Client = hg_client_invoicing:start_link(hg_ct_helper:create_client(RootUrl)),
PartyClient = cfg(party_client, C),
#{party_id := PartyID} = cfg(limits, C),
ShopID = hg_ct_helper:create_shop(PartyID, ?cat(8), <<"RUB">>, ?tmpl(1), ?pinst(1), PartyClient),

%% Invoice
InvoiceParams = make_invoice_params(PartyID, ShopID, <<"rubberduck">>, make_due_date(10), make_cash(10000)),
InvoiceID = create_invoice(InvoiceParams, Client),
?invoice_created(?invoice_w_status(?invoice_unpaid())) = next_change(InvoiceID, Client),

%% Payment
PaymentParams = make_payment_params(?pmt_sys(<<"visa-ref">>)),
?payment_state(?payment(PaymentID)) = hg_client_invoicing:start_payment(InvoiceID, PaymentParams, Client),
[
?payment_ev(PaymentID, ?payment_started(?payment_w_status(?pending()))),
?payment_ev(PaymentID, ?shop_limit_initiated()),
?payment_ev(PaymentID, ?shop_limit_applied()),
?payment_ev(PaymentID, ?risk_score_changed(_))
] = next_changes(InvoiceID, 4, Client),
%% routing broken
timeout = next_change(InvoiceID, 2000, Client),

%% Repair with rollback limits
ok = repair_invoice_with_scenario(InvoiceID, fail_pre_processing, Client),

%% Check final status
?payment_ev(PaymentID, ?payment_status_changed(?failed({failure, _Failure}))) = next_change(InvoiceID, Client),

%% Check duplicate repair
{exception, {base_InvalidRequest, [<<"No need to repair">>]}} = repair_invoice_with_scenario(
InvoiceID, fail_pre_processing, Client
).

%% fail cash_flow_building before accounting hold
-spec repair_fail_cash_flow_building_succeeded(config()) -> test_return().
repair_fail_cash_flow_building_succeeded(C) ->
Expand Down
2 changes: 1 addition & 1 deletion compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ services:
retries: 10

limiter:
image: ghcr.io/valitydev/limiter:sha-2271094
image: ghcr.io/valitydev/limiter:sha-36eb612
command: /opt/limiter/bin/limiter foreground
depends_on:
machinegun:
Expand Down
Loading