diff --git a/apps/hellgate/src/hg_invoice_payment.erl b/apps/hellgate/src/hg_invoice_payment.erl index 72cdde74..4fff41d1 100644 --- a/apps/hellgate/src/hg_invoice_payment.erl +++ b/apps/hellgate/src/hg_invoice_payment.erl @@ -2607,7 +2607,7 @@ hold_limit_routes(Routes0, VS, Iter, St) -> {lists:reverse(Routes1), Rejected}. do_reject_route(LimiterError, Route, TurnoverLimits, {LimitHeldRoutes, RejectedRoutes}) -> - LimitsIDs = [T#domain_TurnoverLimit.id || T <- TurnoverLimits], + LimitsIDs = [T#domain_TurnoverLimit.ref#domain_LimitConfigRef.id || T <- TurnoverLimits], RejectedRoute = hg_route:to_rejected_route(Route, {'LimitHoldError', LimitsIDs, LimiterError}), {LimitHeldRoutes, [RejectedRoute | RejectedRoutes]}. diff --git a/apps/hellgate/src/hg_limiter.erl b/apps/hellgate/src/hg_limiter.erl index 62a374e6..8eeb24f6 100644 --- a/apps/hellgate/src/hg_limiter.erl +++ b/apps/hellgate/src/hg_limiter.erl @@ -2,7 +2,6 @@ -include_lib("damsel/include/dmsl_payproc_thrift.hrl"). -include_lib("damsel/include/dmsl_domain_thrift.hrl"). --include_lib("damsel/include/dmsl_base_thrift.hrl"). -include_lib("limiter_proto/include/limproto_base_thrift.hrl"). -include_lib("limiter_proto/include/limproto_limiter_thrift.hrl"). -include_lib("limiter_proto/include/limproto_context_payproc_thrift.hrl"). @@ -19,8 +18,6 @@ -type party_config_ref() :: dmsl_domain_thrift:'PartyConfigRef'(). -type shop_config_ref() :: dmsl_domain_thrift:'ShopConfigRef'(). --type change_queue() :: [hg_limiter_client:limit_change()]. - -export_type([turnover_limit_value/0]). -export([get_turnover_limits/2]). @@ -42,16 +39,7 @@ terminal = TerminalRef }). --define(party(PartyID), #domain_Party{ - id = PartyID -}). - --define(shop(ShopID), #domain_Shop{ - 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, {invalid_request, [<<"OperationNotFound">>]}). -spec get_turnover_limits(turnover_terms_container(), strict | lenient) -> [turnover_limit()]. @@ -67,27 +55,24 @@ get_turnover_limits(#domain_PaymentsProvisionTerms{turnover_limits = {value, Lim get_turnover_limits(#domain_PaymentsProvisionTerms{turnover_limits = Ambiguous}, _Mode) -> error({misconfiguration, {'Could not reduce selector to a value', Ambiguous}}). --define(LIMIT_NOT_FOUND(Revision, LimitID), - {object_not_found, {Revision, {limit_config, #domain_LimitConfigRef{id = LimitID}}}} -). +-define(ref(LimitID), #domain_LimitConfigRef{id = LimitID}). +-define(LIMIT_NOT_FOUND(Revision, LimitRef), {object_not_found, {Revision, {limit_config, LimitRef}}}). + filter_existing_turnover_limits(Limits, Mode) -> %% When mode is strict and limit-config does not exist it raises a %% misconfiguration error. %% Otherwise it filters out non existent one. lists:filter( - fun - (#domain_TurnoverLimit{domain_revision = undefined}) -> - true; - (#domain_TurnoverLimit{id = ID, domain_revision = Ver}) -> - try - _ = hg_domain:get(Ver, {limit_config, #domain_LimitConfigRef{id = ID}}), - true - catch - error:?LIMIT_NOT_FOUND(_Revision, _LimitID) when Mode =:= lenient -> - false; - error:?LIMIT_NOT_FOUND(Revision, LimitID) when Mode =:= strict -> - error({misconfiguration, {'Limit config not found', {Revision, LimitID}}}) - end + fun(#domain_TurnoverLimit{ref = ?ref(ID), domain_revision = Ver}) -> + try + _ = hg_domain:get(Ver, {limit_config, ?ref(ID)}), + true + catch + error:?LIMIT_NOT_FOUND(_Revision, ?ref(_LimitID)) when Mode =:= lenient -> + false; + error:?LIMIT_NOT_FOUND(Revision, ?ref(LimitID)) when Mode =:= strict -> + error({misconfiguration, {'Limit config not found', {Revision, LimitID}}}) + end end, Limits ). @@ -107,22 +92,7 @@ make_route_operation_segments(Invoice, Payment, ?route(ProviderRef, TerminalRef) ]. get_limit_values(Context, TurnoverLimits, OperationIdSegments) -> - {LegacyTurnoverLimits, BatchTurnoverLimits} = split_turnover_limits_by_available_limiter_api(TurnoverLimits), - get_legacy_limit_values(Context, LegacyTurnoverLimits) ++ - get_batch_limit_values(Context, BatchTurnoverLimits, OperationIdSegments). - -get_legacy_limit_values(Context, TurnoverLimits) -> - lists:foldl( - fun(TurnoverLimit, Acc) -> - #domain_TurnoverLimit{id = LimitID, domain_revision = Version} = TurnoverLimit, - Clock = get_latest_clock(), - Limit = hg_limiter_client:get(LimitID, Version, Clock, Context), - #limiter_Limit{amount = LimiterAmount} = Limit, - [#payproc_TurnoverLimitValue{limit = TurnoverLimit, value = LimiterAmount} | Acc] - end, - [], - TurnoverLimits - ). + get_batch_limit_values(Context, TurnoverLimits, OperationIdSegments). get_batch_limit_values(_Context, [], _OperationIdSegments) -> []; @@ -146,7 +116,7 @@ check_limits(TurnoverLimits, Invoice, Payment, Route, Iter) -> {ok, Limits} catch throw:limit_overflow -> - IDs = [T#domain_TurnoverLimit.id || T <- TurnoverLimits], + IDs = [T#domain_TurnoverLimit.ref#domain_LimitConfigRef.id || T <- TurnoverLimits], {error, {limit_overflow, IDs, Limits}} end. @@ -162,7 +132,7 @@ check_shop_limits(TurnoverLimits, PartyConfigRef, ShopConfigRef, Invoice, Paymen check_limits_(Limits, Context) catch throw:limit_overflow -> - IDs = [T#domain_TurnoverLimit.id || T <- TurnoverLimits], + IDs = [T#domain_TurnoverLimit.ref#domain_LimitConfigRef.id || T <- TurnoverLimits], {error, {limit_overflow, IDs}} end. @@ -179,7 +149,7 @@ check_limits_([], _) -> check_limits_([TurnoverLimitValue | TLVs], Context) -> #payproc_TurnoverLimitValue{ limit = #domain_TurnoverLimit{ - id = LimitID, + ref = ?ref(LimitID), upper_boundary = UpperBoundary }, value = LimiterAmount @@ -199,14 +169,7 @@ check_limits_([TurnoverLimitValue | TLVs], Context) -> -spec hold_payment_limits([turnover_limit()], invoice(), payment(), route(), pos_integer()) -> ok. hold_payment_limits(TurnoverLimits, Invoice, Payment, Route, Iter) -> Context = gen_limit_context(Invoice, Payment, Route), - {LegacyTurnoverLimits, BatchTurnoverLimits} = split_turnover_limits_by_available_limiter_api(TurnoverLimits), - ok = legacy_hold_payment_limits(Context, LegacyTurnoverLimits, Invoice, Payment, Route, Iter), - ok = batch_hold_limits(Context, BatchTurnoverLimits, make_route_operation_segments(Invoice, Payment, Route, Iter)). - -legacy_hold_payment_limits(Context, TurnoverLimits, Invoice, Payment, Route, Iter) -> - ChangeIDs = [construct_payment_change_id(Route, Iter, Invoice, Payment)], - LimitChanges = gen_limit_changes(TurnoverLimits, ChangeIDs), - hold(LimitChanges, get_latest_clock(), Context). + ok = batch_hold_limits(Context, TurnoverLimits, make_route_operation_segments(Invoice, Payment, Route, Iter)). batch_hold_limits(_Context, [], _OperationIdSegments) -> ok; @@ -218,23 +181,14 @@ batch_hold_limits(Context, TurnoverLimits, OperationIdSegments) -> -spec hold_shop_limits([turnover_limit()], party_config_ref(), shop_config_ref(), invoice(), payment()) -> ok. hold_shop_limits(TurnoverLimits, PartyConfigRef, ShopConfigRef, Invoice, Payment) -> Context = gen_limit_shop_context(Invoice, Payment), - {LegacyTurnoverLimits, BatchTurnoverLimits} = split_turnover_limits_by_available_limiter_api(TurnoverLimits), - ok = legacy_hold_shop_limits(Context, LegacyTurnoverLimits, PartyConfigRef, ShopConfigRef, Invoice, Payment), ok = batch_hold_limits( - Context, BatchTurnoverLimits, make_shop_operation_segments(PartyConfigRef, ShopConfigRef, Invoice, Payment) + Context, TurnoverLimits, make_shop_operation_segments(PartyConfigRef, ShopConfigRef, Invoice, Payment) ). -legacy_hold_shop_limits(Context, TurnoverLimits, PartyConfigRef, ShopConfigRef, Invoice, Payment) -> - ChangeIDs = [construct_shop_change_id(PartyConfigRef, ShopConfigRef, Invoice, Payment)], - LimitChanges = gen_limit_changes(TurnoverLimits, ChangeIDs), - hold(LimitChanges, get_latest_clock(), Context). - -spec hold_refund_limits([turnover_limit()], invoice(), payment(), refund(), route()) -> ok. hold_refund_limits(TurnoverLimits, Invoice, Payment, Refund, Route) -> Context = gen_limit_refund_context(Invoice, Payment, Refund, Route), - {LegacyTurnoverLimits, BatchTurnoverLimits} = split_turnover_limits_by_available_limiter_api(TurnoverLimits), - ok = legacy_hold_refund_limits(Context, LegacyTurnoverLimits, Invoice, Payment, Refund), - ok = batch_hold_limits(Context, BatchTurnoverLimits, make_refund_operation_segments(Invoice, Payment, Refund)). + ok = batch_hold_limits(Context, TurnoverLimits, make_refund_operation_segments(Invoice, Payment, Refund)). make_refund_operation_segments(Invoice, Payment, Refund) -> [ @@ -243,66 +197,43 @@ make_refund_operation_segments(Invoice, Payment, Refund) -> {refund_session, get_refund_id(Refund)} ]. -legacy_hold_refund_limits(Context, TurnoverLimits, Invoice, Payment, Refund) -> - ChangeIDs = [construct_refund_change_id(Invoice, Payment, Refund)], - LimitChanges = gen_limit_changes(TurnoverLimits, ChangeIDs), - hold(LimitChanges, get_latest_clock(), Context). - -spec commit_payment_limits([turnover_limit()], invoice(), payment(), route(), pos_integer(), cash() | undefined) -> ok. commit_payment_limits(TurnoverLimits, Invoice, Payment, Route, Iter, CapturedCash) -> Context = gen_limit_context(Invoice, Payment, Route, CapturedCash), - {LegacyTurnoverLimits, BatchTurnoverLimits} = split_turnover_limits_by_available_limiter_api(TurnoverLimits), - Clock = get_latest_clock(), - ok = legacy_commit_payment_limits(Clock, Context, LegacyTurnoverLimits, Invoice, Payment, Route, Iter), OperationIdSegments = make_route_operation_segments(Invoice, Payment, Route, Iter), - ok = batch_commit_limits(Context, BatchTurnoverLimits, OperationIdSegments), - ok = log_limit_changes(TurnoverLimits, Clock, Context). - -batch_commit_limits(_Context, [], _OperationIdSegments) -> - ok; -batch_commit_limits(Context, TurnoverLimits, OperationIdSegments) -> - {LimitRequest, _} = prepare_limit_request(TurnoverLimits, OperationIdSegments), - hg_limiter_client:commit_batch(LimitRequest, Context). - -legacy_commit_payment_limits(Clock, Context, TurnoverLimits, Invoice, Payment, Route, Iter) -> - ChangeIDs = [ - construct_payment_change_id(Route, Iter, Invoice, Payment), - construct_payment_change_id(Route, Iter, Invoice, Payment, legacy) - ], - LimitChanges = gen_limit_changes(TurnoverLimits, ChangeIDs), - commit(LimitChanges, Clock, Context). + ok = batch_commit_limits(Context, TurnoverLimits, OperationIdSegments). -spec commit_shop_limits([turnover_limit()], party_config_ref(), shop_config_ref(), invoice(), payment()) -> ok. commit_shop_limits(TurnoverLimits, PartyConfigRef, ShopConfigRef, Invoice, Payment) -> Context = gen_limit_shop_context(Invoice, Payment), - {LegacyTurnoverLimits, BatchTurnoverLimits} = split_turnover_limits_by_available_limiter_api(TurnoverLimits), - Clock = get_latest_clock(), - ok = legacy_commit_shop_limits( - Clock, Context, LegacyTurnoverLimits, PartyConfigRef, ShopConfigRef, Invoice, Payment - ), OperationIdSegments = make_shop_operation_segments(PartyConfigRef, ShopConfigRef, Invoice, Payment), - ok = batch_commit_limits(Context, BatchTurnoverLimits, OperationIdSegments), - ok = log_limit_changes(TurnoverLimits, Clock, Context). - -legacy_commit_shop_limits(Clock, Context, TurnoverLimits, PartyConfigRef, ShopConfigRef, Invoice, Payment) -> - ChangeIDs = [construct_shop_change_id(PartyConfigRef, ShopConfigRef, Invoice, Payment)], - LimitChanges = gen_limit_changes(TurnoverLimits, ChangeIDs), - ok = commit(LimitChanges, Clock, Context). + ok = batch_commit_limits(Context, TurnoverLimits, OperationIdSegments). -spec commit_refund_limits([turnover_limit()], invoice(), payment(), refund(), route()) -> ok. commit_refund_limits(TurnoverLimits, Invoice, Payment, Refund, Route) -> Context = gen_limit_refund_context(Invoice, Payment, Refund, Route), - {LegacyTurnoverLimits, BatchTurnoverLimits} = split_turnover_limits_by_available_limiter_api(TurnoverLimits), - Clock = get_latest_clock(), - ok = legacy_commit_refund_limits(Clock, Context, LegacyTurnoverLimits, Invoice, Payment, Refund), OperationIdSegments = make_refund_operation_segments(Invoice, Payment, Refund), - ok = batch_commit_limits(Context, BatchTurnoverLimits, OperationIdSegments), - ok = log_limit_changes(TurnoverLimits, Clock, Context). + ok = batch_commit_limits(Context, TurnoverLimits, OperationIdSegments). -legacy_commit_refund_limits(Clock, Context, TurnoverLimits, Invoice, Payment, Refund) -> - ChangeIDs = [construct_refund_change_id(Invoice, Payment, Refund)], - LimitChanges = gen_limit_changes(TurnoverLimits, ChangeIDs), - commit(LimitChanges, Clock, Context). +batch_commit_limits(_Context, [], _OperationIdSegments) -> + ok; +batch_commit_limits(Context, TurnoverLimits, OperationIdSegments) -> + {LimitRequest, TurnoverLimitsMap} = prepare_limit_request(TurnoverLimits, OperationIdSegments), + ok = hg_limiter_client:commit_batch(LimitRequest, Context), + Attrs = mk_limit_log_attributes(Context), + lists:foreach( + fun(#limiter_Limit{id = LimitID, amount = LimitAmount}) -> + #domain_TurnoverLimit{upper_boundary = UpperBoundary} = maps:get(LimitID, TurnoverLimitsMap), + ok = logger:log(notice, "Limit change commited", [], #{ + limit => Attrs#{ + config_id => LimitID, + boundary => UpperBoundary, + amount => LimitAmount + } + }) + end, + hg_limiter_client:get_batch(LimitRequest, Context) + ). %% @doc This function supports flags that can change reaction behaviour to %% limiter response: @@ -316,10 +247,8 @@ legacy_commit_refund_limits(Clock, Context, TurnoverLimits, Invoice, Payment, Re ok. rollback_payment_limits(TurnoverLimits, Invoice, Payment, Route, Iter, Flags) -> Context = gen_limit_context(Invoice, Payment, Route), - {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, Flags). + ok = batch_rollback_limits(Context, TurnoverLimits, OperationIdSegments, Flags). batch_rollback_limits(_Context, [], _OperationIdSegments, _Flags) -> ok; @@ -333,14 +262,6 @@ batch_rollback_limits(Context, TurnoverLimits, OperationIdSegments, Flags) -> ok end. -legacy_rollback_payment_limits(Context, TurnoverLimits, Invoice, Payment, Route, Iter, Flags) -> - ChangeIDs = [ - construct_payment_change_id(Route, Iter, Invoice, Payment), - construct_payment_change_id(Route, Iter, Invoice, Payment, legacy) - ], - LimitChanges = gen_limit_changes(TurnoverLimits, ChangeIDs), - rollback(LimitChanges, get_latest_clock(), Context, Flags). - -spec rollback_shop_limits( [turnover_limit()], party_config_ref(), @@ -351,78 +272,14 @@ legacy_rollback_payment_limits(Context, TurnoverLimits, Invoice, Payment, Route, ) -> ok. rollback_shop_limits(TurnoverLimits, PartyConfigRef, ShopConfigRef, Invoice, Payment, Flags) -> Context = gen_limit_shop_context(Invoice, Payment), - {LegacyTurnoverLimits, BatchTurnoverLimits} = split_turnover_limits_by_available_limiter_api(TurnoverLimits), - ok = legacy_rollback_shop_limits( - Context, LegacyTurnoverLimits, PartyConfigRef, ShopConfigRef, Invoice, Payment, Flags - ), OperationIdSegments = make_shop_operation_segments(PartyConfigRef, ShopConfigRef, Invoice, Payment), - ok = batch_rollback_limits(Context, BatchTurnoverLimits, OperationIdSegments, Flags). - -legacy_rollback_shop_limits(Context, TurnoverLimits, PartyConfigRef, ShopConfigRef, Invoice, Payment, Flags) -> - ChangeIDs = [construct_shop_change_id(PartyConfigRef, ShopConfigRef, Invoice, Payment)], - LimitChanges = gen_limit_changes(TurnoverLimits, ChangeIDs), - rollback(LimitChanges, get_latest_clock(), Context, Flags). + ok = batch_rollback_limits(Context, TurnoverLimits, OperationIdSegments, Flags). -spec rollback_refund_limits([turnover_limit()], invoice(), payment(), refund(), route()) -> ok. rollback_refund_limits(TurnoverLimits, Invoice, Payment, Refund, Route) -> Context = gen_limit_refund_context(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, []). - -legacy_rollback_refund_limits(Context, TurnoverLimits, Invoice, Payment, Refund) -> - ChangeIDs = [construct_refund_change_id(Invoice, Payment, Refund)], - LimitChanges = gen_limit_changes(TurnoverLimits, ChangeIDs), - rollback(LimitChanges, get_latest_clock(), Context, []). - --spec hold([change_queue()], hg_limiter_client:clock(), hg_limiter_client:context()) -> ok. -hold(LimitChanges, Clock, Context) -> - process_changes(LimitChanges, fun hg_limiter_client:hold/3, Clock, Context, []). - --spec commit([change_queue()], hg_limiter_client:clock(), hg_limiter_client:context()) -> ok. -commit(LimitChanges, Clock, Context) -> - process_changes(LimitChanges, fun hg_limiter_client:commit/3, Clock, Context, []). - --spec rollback([change_queue()], hg_limiter_client:clock(), hg_limiter_client:context(), [handling_flag()]) -> ok. -rollback(LimitChanges, Clock, Context, Flags) -> - process_changes(LimitChanges, fun hg_limiter_client:rollback/3, Clock, Context, Flags). - -process_changes(LimitChangesQueues, WithFun, Clock, Context, Flags) -> - lists:foreach( - fun(LimitChangesQueue) -> - process_changes_try_wrap(LimitChangesQueue, WithFun, Clock, Context, Flags) - end, - LimitChangesQueues - ). - -process_changes_try_wrap([LimitChange], WithFun, Clock, Context, Flags) -> - IgnoreNotFound = lists:member(ignore_not_found, Flags), - #limiter_LimitChange{change_id = ChangeID} = LimitChange, - try - WithFun(LimitChange, Clock, Context) - catch - error:(?POSTING_PLAN_NOT_FOUND(ChangeID)) when IgnoreNotFound =:= true -> - %% See `limproto_limiter_thrift:'Clock'/0` - {latest, #limiter_LatestClock{}} - end; -process_changes_try_wrap([LimitChange | OtherLimitChanges], WithFun, Clock, Context, Flags) -> - IgnoreBusinessError = lists:member(ignore_business_error, Flags), - #limiter_LimitChange{change_id = ChangeID} = LimitChange, - try - WithFun(LimitChange, Clock, Context) - catch - error:(?POSTING_PLAN_NOT_FOUND(ChangeID)) -> - process_changes_try_wrap(OtherLimitChanges, WithFun, Clock, Context, Flags); - Class:Reason:Stacktrace -> - handle_caught_exception(Class, Reason, Stacktrace, IgnoreBusinessError) - end. - -handle_caught_exception(error, #limiter_LimitNotFound{}, _Stacktrace, true) -> ok; -handle_caught_exception(error, #limiter_InvalidOperationCurrency{}, _Stacktrace, true) -> ok; -handle_caught_exception(error, #limiter_OperationContextNotSupported{}, _Stacktrace, true) -> ok; -handle_caught_exception(error, #limiter_PaymentToolNotSupported{}, _Stacktrace, true) -> ok; -handle_caught_exception(Class, Reason, Stacktrace, _IgnoreBusinessError) -> erlang:raise(Class, Reason, Stacktrace). + ok = batch_rollback_limits(Context, TurnoverLimits, OperationIdSegments, []). gen_limit_context(Invoice, Payment, Route) -> gen_limit_context(Invoice, Payment, Route, undefined). @@ -473,57 +330,6 @@ gen_limit_refund_context(Invoice, Payment, Refund, Route) -> } }. --spec gen_limit_changes([turnover_limit()], [binary()]) -> [change_queue()]. -gen_limit_changes(Limits, ChangeIDs) -> - %% It produces lists like - %% [ - %% [#limiter_LimitChange{...}, #limiter_LimitChange{...}], - %% [#limiter_LimitChange{...}], - %% ... - %% ] - [[gen_limit_change(Limit, ChangeID) || ChangeID <- ChangeIDs] || Limit <- Limits]. - -gen_limit_change(#domain_TurnoverLimit{id = ID, domain_revision = Version}, ChangeID) -> - #limiter_LimitChange{ - id = ID, - change_id = hg_utils:construct_complex_id([<<"limiter">>, ID, ChangeID]), - version = Version - }. - -construct_payment_change_id(Route, Iter, Invoice, Payment) -> - construct_payment_change_id(Route, Iter, Invoice, Payment, normal). - -construct_payment_change_id(?route(ProviderRef, TerminalRef), _Iter, Invoice, Payment, legacy) -> - hg_utils:construct_complex_id([ - genlib:to_binary(get_provider_id(ProviderRef)), - genlib:to_binary(get_terminal_id(TerminalRef)), - get_invoice_id(Invoice), - get_payment_id(Payment) - ]); -construct_payment_change_id(?route(ProviderRef, TerminalRef), Iter, Invoice, Payment, normal) -> - hg_utils:construct_complex_id([ - genlib:to_binary(get_provider_id(ProviderRef)), - genlib:to_binary(get_terminal_id(TerminalRef)), - get_invoice_id(Invoice), - get_payment_id(Payment), - integer_to_binary(Iter) - ]). - -construct_shop_change_id(PartyConfigRef, ShopConfigRef, Invoice, Payment) -> - hg_utils:construct_complex_id([ - PartyConfigRef, - ShopConfigRef, - get_invoice_id(Invoice), - get_payment_id(Payment) - ]). - -construct_refund_change_id(Invoice, Payment, Refund) -> - hg_utils:construct_complex_id([ - get_invoice_id(Invoice), - get_payment_id(Payment), - {refund_session, get_refund_id(Refund)} - ]). - get_provider_id(#domain_ProviderRef{id = ID}) -> ID. @@ -539,27 +345,12 @@ get_payment_id(#domain_InvoicePayment{id = ID}) -> get_refund_id(#domain_InvoicePaymentRefund{id = ID}) -> ID. -get_latest_clock() -> - {latest, #limiter_LatestClock{}}. - convert_to_limit_route(#domain_PaymentRoute{provider = Provider, terminal = Terminal}) -> #base_Route{ provider = Provider, terminal = Terminal }. -log_limit_changes(TurnoverLimits, Clock, Context) -> - Attrs = mk_limit_log_attributes(Context), - lists:foreach( - fun(#domain_TurnoverLimit{id = ID, upper_boundary = UpperBoundary, domain_revision = DomainRevision}) -> - #limiter_Limit{amount = LimitAmount} = hg_limiter_client:get(ID, DomainRevision, Clock, Context), - ok = logger:log(notice, "Limit change commited", [], #{ - limit => Attrs#{config_id => ID, boundary => UpperBoundary, amount => LimitAmount} - }) - end, - TurnoverLimits - ). - mk_limit_log_attributes(#limiter_LimitContext{ payment_processing = #context_payproc_Context{op = Op, invoice = CtxInvoice} }) -> @@ -601,14 +392,11 @@ maybe_route_context(#base_Route{provider = Provider, terminal = Terminal}) -> terminal_id => Terminal#domain_TerminalRef.id }. -split_turnover_limits_by_available_limiter_api(TurnoverLimits) -> - lists:partition(fun(#domain_TurnoverLimit{domain_revision = V}) -> V =:= undefined end, TurnoverLimits). - prepare_limit_request(TurnoverLimits, IdSegments) -> {TurnoverLimitsIdList, LimitChanges} = lists:unzip( lists:map( - fun(TurnoverLimit = #domain_TurnoverLimit{id = Id, domain_revision = DomainRevision}) -> - {{Id, TurnoverLimit}, #limiter_LimitChange{id = Id, version = DomainRevision}} + fun(TurnoverLimit = #domain_TurnoverLimit{ref = ?ref(LimitID), domain_revision = DomainRevision}) -> + {{LimitID, TurnoverLimit}, #limiter_LimitChange{id = LimitID, version = DomainRevision}} end, TurnoverLimits ) diff --git a/apps/hellgate/src/hg_limiter_client.erl b/apps/hellgate/src/hg_limiter_client.erl index c8bbd141..8f9dea69 100644 --- a/apps/hellgate/src/hg_limiter_client.erl +++ b/apps/hellgate/src/hg_limiter_client.erl @@ -3,11 +3,6 @@ -include_lib("damsel/include/dmsl_base_thrift.hrl"). -include_lib("limiter_proto/include/limproto_limiter_thrift.hrl"). --export([get/4]). --export([hold/3]). --export([commit/3]). --export([rollback/3]). - -export([get_values/2]). -export([get_batch/2]). -export([hold_batch/2]). @@ -16,63 +11,14 @@ -type limit() :: limproto_limiter_thrift:'Limit'(). -type limit_id() :: limproto_limiter_thrift:'LimitID'(). --type limit_version() :: limproto_limiter_thrift:'Version'(). -type limit_change() :: limproto_limiter_thrift:'LimitChange'(). -type context() :: limproto_limiter_thrift:'LimitContext'(). --type clock() :: limproto_limiter_thrift:'Clock'(). -type request() :: limproto_limiter_thrift:'LimitRequest'(). -export_type([limit/0]). -export_type([limit_id/0]). -export_type([limit_change/0]). -export_type([context/0]). --export_type([clock/0]). - --spec get(limit_id(), limit_version() | undefined, clock(), context()) -> limit() | no_return(). -get(LimitID, Version, Clock, Context) -> - Opts = hg_woody_wrapper:get_service_options(limiter), - Args = {LimitID, Version, Clock, Context}, - case hg_woody_wrapper:call(limiter, 'GetVersioned', Args, Opts) of - {ok, Limit} -> - Limit; - {exception, #limiter_LimitNotFound{}} -> - error({not_found, LimitID}); - {exception, #base_InvalidRequest{errors = Errors}} -> - error({invalid_request, Errors}) - end. - --spec hold(limit_change(), clock(), context()) -> clock() | no_return(). -hold(LimitChange, Clock, Context) -> - Opts = hg_woody_wrapper:get_service_options(limiter), - Args = {LimitChange, Clock, Context}, - case hg_woody_wrapper:call(limiter, 'Hold', Args, Opts) of - {ok, ClockUpdated} -> - ClockUpdated; - {exception, Exception} -> - error(Exception) - end. - --spec commit(limit_change(), clock(), context()) -> clock() | no_return(). -commit(LimitChange, Clock, Context) -> - Opts = hg_woody_wrapper:get_service_options(limiter), - Args = {LimitChange, Clock, Context}, - case hg_woody_wrapper:call(limiter, 'Commit', Args, Opts) of - {ok, ClockUpdated} -> - ClockUpdated; - {exception, Exception} -> - error(Exception) - end. - --spec rollback(limit_change(), clock(), context()) -> clock() | no_return(). -rollback(LimitChange, Clock, Context) -> - Opts = hg_woody_wrapper:get_service_options(limiter), - Args = {LimitChange, Clock, Context}, - case hg_woody_wrapper:call(limiter, 'Rollback', Args, Opts) of - {ok, ClockUpdated} -> - ClockUpdated; - {exception, Exception} -> - error(Exception) - end. -spec get_values(request(), context()) -> [limit()] | no_return(). get_values(Request, Context) -> diff --git a/apps/hellgate/test/hg_ct_domain.hrl b/apps/hellgate/test/hg_ct_domain.hrl index 383f7742..f62a8416 100644 --- a/apps/hellgate/test/hg_ct_domain.hrl +++ b/apps/hellgate/test/hg_ct_domain.hrl @@ -16,6 +16,7 @@ -define(pmt(C, T), #domain_PaymentMethodRef{id = {C, T}}). -define(pmt_sys(ID), #domain_PaymentSystemRef{id = ID}). -define(pmt_srv(ID), #domain_PaymentServiceRef{id = ID}). +-define(lim(ID), #domain_LimitConfigRef{id = ID}). -define(cat(ID), #domain_CategoryRef{id = ID}). -define(prx(ID), #domain_ProxyRef{id = ID}). -define(prv(ID), #domain_ProviderRef{id = ID}). diff --git a/apps/hellgate/test/hg_invoice_lite_tests_SUITE.erl b/apps/hellgate/test/hg_invoice_lite_tests_SUITE.erl index 0c121aaa..21e72b01 100644 --- a/apps/hellgate/test/hg_invoice_lite_tests_SUITE.erl +++ b/apps/hellgate/test/hg_invoice_lite_tests_SUITE.erl @@ -28,8 +28,6 @@ -export([payment_has_optional_fields/1]). -export([payment_last_trx_correct/1]). --export([payment_ok_hybrid_test/1]). - -type config() :: hg_ct_helper:config(). -type test_case_name() :: hg_ct_helper:test_case_name(). -type group_name() :: hg_ct_helper:group_name(). @@ -48,8 +46,7 @@ init([]) -> -spec all() -> [test_case_name() | {group, group_name()}]. all() -> [ - {group, payments}, - payment_ok_hybrid_test + {group, payments} % {group, wrap_load} ]. @@ -501,30 +498,6 @@ payment_last_trx_correct(C) -> PaymentID = await_payment_capture(InvoiceID, PaymentID, Client), ?payment_last_trx(TrxInfo0) = hg_client_invoicing:get_payment(InvoiceID, PaymentID, Client). --spec payment_ok_hybrid_test(config()) -> test_return(). -payment_ok_hybrid_test(C) -> - Client = cfg(client, C), - OriginalBackend = application:get_env(hellgate, backend, machinegun), - ok = application:set_env(hellgate, backend, machinegun), - InvoiceID = start_invoice(<<"rubberduck">>, make_due_date(10), 42000, C), - Context = #base_Content{ - type = <<"application/x-erlang-binary">>, - data = erlang:term_to_binary({you, 643, "not", [<<"welcome">>, here]}) - }, - PayerSessionInfo = #domain_PayerSessionInfo{ - redirect_url = <<"https://redirectly.io/merchant">> - }, - PaymentParams = (make_payment_params(?pmt_sys(<<"visa-ref">>)))#payproc_InvoicePaymentParams{ - payer_session_info = PayerSessionInfo, - context = Context - }, - ok = application:set_env(hellgate, backend, hybrid), - PaymentID = process_payment(InvoiceID, PaymentParams, Client), - PaymentID = await_payment_capture(InvoiceID, PaymentID, Client), - #payproc_Invoice{} = hg_client_invoicing:get(InvoiceID, Client), - ok = application:set_env(hellgate, backend, OriginalBackend), - ok. - %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Internals %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff --git a/apps/hellgate/test/hg_invoice_tests_SUITE.erl b/apps/hellgate/test/hg_invoice_tests_SUITE.erl index 029e638d..63f9866c 100644 --- a/apps/hellgate/test/hg_invoice_tests_SUITE.erl +++ b/apps/hellgate/test/hg_invoice_tests_SUITE.erl @@ -181,7 +181,6 @@ -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]). @@ -473,7 +472,6 @@ groups() -> ]}, {repair_preproc_w_limits, [], [ repair_fail_routing_succeeded, - repair_fail_routing_not_existent_operation, repair_fail_cash_flow_building_succeeded ]}, {route_cascading, [parallel], [ @@ -725,8 +723,6 @@ 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, @@ -759,27 +755,6 @@ 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), @@ -798,8 +773,6 @@ 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); @@ -1229,7 +1202,7 @@ payment_shop_limit_success(C) -> PartyConfigRef = cfg(party_config_ref_big_merch, C), TurnoverLimits = [ #domain_TurnoverLimit{ - id = ?SHOPLIMIT_ID, + ref = ?lim(?SHOPLIMIT_ID), upper_boundary = ?LIMIT_UPPER_BOUNDARY, domain_revision = hg_domain:head() } @@ -1251,7 +1224,7 @@ payment_shop_limit_overflow(C) -> PartyConfigRef = cfg(party_config_ref_big_merch, C), TurnoverLimits = ordsets:from_list([ #domain_TurnoverLimit{ - id = ?SHOPLIMIT_ID, + ref = ?lim(?SHOPLIMIT_ID), upper_boundary = ?LIMIT_UPPER_BOUNDARY, domain_revision = hg_domain:head() } @@ -1277,7 +1250,7 @@ payment_shop_limit_more_overflow(C) -> PartyConfigRef = cfg(party_config_ref_big_merch, C), TurnoverLimits = ordsets:from_list([ #domain_TurnoverLimit{ - id = ?SHOPLIMIT_ID, + ref = ?lim(?SHOPLIMIT_ID), upper_boundary = ?LIMIT_UPPER_BOUNDARY, domain_revision = hg_domain:head() } @@ -1319,7 +1292,7 @@ payment_routes_limit_values(C) -> #{ Route := [ #payproc_TurnoverLimitValue{ - limit = #domain_TurnoverLimit{id = ?LIMIT_ID, upper_boundary = ?LIMIT_UPPER_BOUNDARY}, + limit = #domain_TurnoverLimit{ref = ?lim(?LIMIT_ID), upper_boundary = ?LIMIT_UPPER_BOUNDARY}, value = 10000 } ] @@ -1745,7 +1718,7 @@ patch_with_unsupported_payment_tool(Revision, _C) -> turnover_limits = {value, [ #domain_TurnoverLimit{ - id = ?LIMIT_ID, + ref = ?lim(?LIMIT_ID), upper_boundary = ?LIMIT_UPPER_BOUNDARY, domain_revision = NewRevision } @@ -1781,14 +1754,14 @@ patch_providers_limits_to_fail_and_overflow(Revision, _C) -> ), change_terms_limit_config_version(Revision, ?prv(5), [ #domain_TurnoverLimit{ - id = ?LIMIT_ID, + ref = ?lim(?LIMIT_ID), upper_boundary = ?LIMIT_UPPER_BOUNDARY, domain_revision = NewRevision } ]), change_terms_limit_config_version(Revision, ?prv(6), [ #domain_TurnoverLimit{ - id = ?LIMIT_ID2, + ref = ?lim(?LIMIT_ID2), %% Every op will overflow! upper_boundary = 0, domain_revision = NewRevision @@ -1818,7 +1791,7 @@ unset_provider_chargebacks_terms(Revision, ProviderRef) -> change_terms_limit_config_version(Revision, LimitConfigRevision) -> change_terms_limit_config_version(Revision, ?prv(5), [ #domain_TurnoverLimit{ - id = ?LIMIT_ID, + ref = ?lim(?LIMIT_ID), upper_boundary = ?LIMIT_UPPER_BOUNDARY, domain_revision = LimitConfigRevision } @@ -5709,7 +5682,7 @@ repair_fail_routing_succeeded(C) -> #{ Route := [ #payproc_TurnoverLimitValue{ - limit = #domain_TurnoverLimit{id = ?LIMIT_ID, upper_boundary = ?LIMIT_UPPER_BOUNDARY}, + limit = #domain_TurnoverLimit{ref = ?lim(?LIMIT_ID), upper_boundary = ?LIMIT_UPPER_BOUNDARY}, value = 10000 } ] @@ -5725,7 +5698,7 @@ repair_fail_routing_succeeded(C) -> #{ Route := [ #payproc_TurnoverLimitValue{ - limit = #domain_TurnoverLimit{id = ?LIMIT_ID, upper_boundary = ?LIMIT_UPPER_BOUNDARY}, + limit = #domain_TurnoverLimit{ref = ?lim(?LIMIT_ID), upper_boundary = ?LIMIT_UPPER_BOUNDARY}, value = 0 } ] @@ -5736,43 +5709,6 @@ 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_config_ref := PartyConfigRef} = cfg(limits, C), - ShopConfigRef = hg_ct_helper:create_shop(PartyConfigRef, ?cat(8), <<"RUB">>, ?trms(1), ?pinst(1), PartyClient), - - %% Invoice - InvoiceParams = - make_invoice_params(PartyConfigRef, ShopConfigRef, <<"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: limit holds fail with misconfiguration error - 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) -> @@ -5805,7 +5741,7 @@ repair_fail_cash_flow_building_succeeded(C) -> #{ Route := [ #payproc_TurnoverLimitValue{ - limit = #domain_TurnoverLimit{id = ?LIMIT_ID, upper_boundary = ?LIMIT_UPPER_BOUNDARY}, + limit = #domain_TurnoverLimit{ref = ?lim(?LIMIT_ID), upper_boundary = ?LIMIT_UPPER_BOUNDARY}, value = 10000 } ] @@ -5821,7 +5757,7 @@ repair_fail_cash_flow_building_succeeded(C) -> #{ Route := [ #payproc_TurnoverLimitValue{ - limit = #domain_TurnoverLimit{id = ?LIMIT_ID, upper_boundary = ?LIMIT_UPPER_BOUNDARY}, + limit = #domain_TurnoverLimit{ref = ?lim(?LIMIT_ID), upper_boundary = ?LIMIT_UPPER_BOUNDARY}, value = 0 } ] @@ -6334,7 +6270,7 @@ payment_cascade_success_fixture(Revision, _C) -> turnover_limits = {value, [ #domain_TurnoverLimit{ - id = ?LIMIT_ID4, + ref = ?lim(?LIMIT_ID4), upper_boundary = ?BIG_LIMIT_UPPER_BOUNDARY, domain_revision = Revision } @@ -6499,7 +6435,7 @@ payment_cascade_success_w_refund_fixture(Revision, _C) -> turnover_limits = {value, [ #domain_TurnoverLimit{ - id = ?LIMIT_ID4, + ref = ?lim(?LIMIT_ID4), upper_boundary = ?BIG_LIMIT_UPPER_BOUNDARY, domain_revision = Revision } @@ -6587,7 +6523,7 @@ payment_big_cascade_success_fixture(Revision, _C) -> turnover_limits = {value, [ #domain_TurnoverLimit{ - id = ?LIMIT_ID4, + ref = ?lim(?LIMIT_ID4), upper_boundary = ?BIG_LIMIT_UPPER_BOUNDARY, domain_revision = Revision } @@ -6721,7 +6657,7 @@ payment_cascade_limit_overflow_fixture(Revision, _C) -> turnover_limits = {value, [ #domain_TurnoverLimit{ - id = ?LIMIT_ID4, + ref = ?lim(?LIMIT_ID4), upper_boundary = ?LIMIT_UPPER_BOUNDARY, domain_revision = Revision } @@ -6949,7 +6885,7 @@ payment_cascade_fail_provider_error_fixture(Revision, _C) -> turnover_limits = {value, [ #domain_TurnoverLimit{ - id = ?LIMIT_ID4, + ref = ?lim(?LIMIT_ID4), upper_boundary = ?BIG_LIMIT_UPPER_BOUNDARY, domain_revision = Revision } @@ -7186,7 +7122,7 @@ payment_cascade_fail_wo_route_candidates_fixture(Revision, _C) -> turnover_limits = {value, [ #domain_TurnoverLimit{ - id = ?LIMIT_ID4, + ref = ?lim(?LIMIT_ID4), upper_boundary = ?BIG_LIMIT_UPPER_BOUNDARY, domain_revision = Revision } @@ -7265,7 +7201,7 @@ payment_cascade_fail_wo_available_attempt_limit_fixture(Revision, _C) -> turnover_limits = {value, [ #domain_TurnoverLimit{ - id = ?LIMIT_ID4, + ref = ?lim(?LIMIT_ID4), upper_boundary = ?BIG_LIMIT_UPPER_BOUNDARY, domain_revision = Revision } @@ -9506,7 +9442,7 @@ construct_domain_fixture(BaseLimitsRevision) -> turnover_limits = {value, [ #domain_TurnoverLimit{ - id = ?LIMIT_ID, + ref = ?lim(?LIMIT_ID), upper_boundary = ?LIMIT_UPPER_BOUNDARY, domain_revision = BaseLimitsRevision } @@ -9559,7 +9495,7 @@ construct_domain_fixture(BaseLimitsRevision) -> turnover_limits = {value, [ #domain_TurnoverLimit{ - id = ?LIMIT_ID2, + ref = ?lim(?LIMIT_ID2), upper_boundary = ?LIMIT_UPPER_BOUNDARY, domain_revision = BaseLimitsRevision } @@ -9604,7 +9540,7 @@ construct_domain_fixture(BaseLimitsRevision) -> turnover_limits = {value, [ #domain_TurnoverLimit{ - id = ?LIMIT_ID3, + ref = ?lim(?LIMIT_ID3), upper_boundary = ?LIMIT_UPPER_BOUNDARY, domain_revision = BaseLimitsRevision } diff --git a/apps/hellgate/test/hg_limiter_helper.erl b/apps/hellgate/test/hg_limiter_helper.erl index d6953382..01041fba 100644 --- a/apps/hellgate/test/hg_limiter_helper.erl +++ b/apps/hellgate/test/hg_limiter_helper.erl @@ -108,7 +108,6 @@ mk_config_object(LimitID, Currency, ContextType, Scopes) -> ref = #domain_LimitConfigRef{id = LimitID}, data = #limiter_config_LimitConfig{ processor_type = <<"TurnoverProcessor">>, - created_at = <<"2000-01-01T00:00:00Z">>, started_at = <<"2000-01-01T00:00:00Z">>, shard_size = 12, time_range_type = {calendar, {month, #limiter_config_TimeRangeTypeCalendarMonth{}}}, diff --git a/apps/routing/src/hg_routing_explanation.erl b/apps/routing/src/hg_routing_explanation.erl index 24ee9554..9aea6e16 100644 --- a/apps/routing/src/hg_routing_explanation.erl +++ b/apps/routing/src/hg_routing_explanation.erl @@ -179,7 +179,7 @@ check_route_limits([TurnoverLimitValue | Rest]) -> case TurnoverLimitValue of #payproc_TurnoverLimitValue{ limit = #domain_TurnoverLimit{ - id = LimitID, + ref = #domain_LimitConfigRef{id = LimitID}, upper_boundary = UpperBoundary }, value = Value diff --git a/compose.tracing.yaml b/compose.tracing.yaml index e55c1ff7..24e0bbbf 100644 --- a/compose.tracing.yaml +++ b/compose.tracing.yaml @@ -16,9 +16,6 @@ services: party-management: environment: *otlp_enabled - machinegun: - environment: *otlp_enabled - testrunner: environment: <<: *otlp_enabled diff --git a/compose.yaml b/compose.yaml index 5fc843f7..86556bd4 100644 --- a/compose.yaml +++ b/compose.yaml @@ -27,36 +27,26 @@ services: command: /sbin/init dmt: - image: ghcr.io/valitydev/dominant-v2:sha-1705fe8 + image: ghcr.io/valitydev/dominant-v2:sha-90f5fa2 command: /opt/dmt/bin/dmt foreground - healthcheck: - test: "/opt/dmt/bin/dmt ping" - interval: 5s - timeout: 3s - retries: 12 + volumes: + - ./test/dmt/sys.config:/opt/dmt/releases/0.1/sys.config depends_on: db: condition: service_healthy - volumes: - - ./test/dmt/sys.config:/opt/dmt/releases/0.1/sys.config - - machinegun: - image: ghcr.io/valitydev/mg2:sha-436f723 - command: /opt/machinegun/bin/machinegun foreground - volumes: - - ./test/machinegun/config.yaml:/opt/machinegun/etc/config.yaml - - ./test/machinegun/cookie:/opt/machinegun/etc/cookie healthcheck: - test: "/opt/machinegun/bin/machinegun ping" + test: "/opt/dmt/bin/dmt ping" interval: 5s - timeout: 1s - retries: 20 + timeout: 3s + retries: 12 bender: - image: ghcr.io/valitydev/bender:sha-a3b227f + image: ghcr.io/valitydev/bender:sha-bc14c2e command: /opt/bender/bin/bender foreground + volumes: + - ./test/bender/sys.config:/opt/bender/releases/1.0.0/sys.config depends_on: - machinegun: + db: condition: service_healthy healthcheck: test: "/opt/bender/bin/bender ping" @@ -65,13 +55,9 @@ services: retries: 10 limiter: - image: ghcr.io/valitydev/limiter:sha-7b27571 + image: ghcr.io/valitydev/limiter:sha-2a3f78d command: /opt/limiter/bin/limiter foreground depends_on: - machinegun: - condition: service_healthy - shumway: - condition: service_started liminator: condition: service_healthy healthcheck: @@ -81,7 +67,7 @@ services: retries: 20 shumway: - image: ghcr.io/valitydev/shumway:sha-658587c + image: ghcr.io/valitydev/shumway:sha-d198581 restart: unless-stopped depends_on: db: @@ -121,8 +107,10 @@ services: retries: 20 party-management: - image: ghcr.io/valitydev/party-management:sha-51e92f7 + image: ghcr.io/valitydev/party-management:sha-53d780a command: /opt/party-management/bin/party-management foreground + volumes: + - ./test/party-management/sys.config:/opt/party-management/releases/0.1/sys.config depends_on: db: condition: service_healthy @@ -135,14 +123,12 @@ services: interval: 10s timeout: 5s retries: 10 - volumes: - - ./test/party-management/sys.config:/opt/party-management/releases/0.1/sys.config db: image: postgres:15-bookworm command: -c 'max_connections=1000' environment: - POSTGRES_MULTIPLE_DATABASES: "hellgate,dmt,party_management,shumway,liminator" + POSTGRES_MULTIPLE_DATABASES: "hellgate,bender,dmt,party_management,shumway,liminator" POSTGRES_PASSWORD: "postgres" volumes: - ./test/postgres/docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d diff --git a/rebar.config b/rebar.config index 0fc7d82d..39d87ac5 100644 --- a/rebar.config +++ b/rebar.config @@ -31,16 +31,16 @@ {gproc, "0.9.0"}, {genlib, {git, "https://github.com/valitydev/genlib.git", {tag, "v1.1.0"}}}, {woody, {git, "https://github.com/valitydev/woody_erlang.git", {tag, "v1.1.0"}}}, - {damsel, {git, "https://github.com/valitydev/damsel.git", {tag, "v2.2.14"}}}, + {damsel, {git, "https://github.com/valitydev/damsel.git", {tag, "v2.2.17"}}}, {payproc_errors, {git, "https://github.com/valitydev/payproc-errors-erlang.git", {branch, "master"}}}, {mg_proto, {git, "https://github.com/valitydev/machinegun-proto.git", {branch, "master"}}}, {dmt_client, {git, "https://github.com/valitydev/dmt-client.git", {tag, "v2.0.3"}}}, {scoper, {git, "https://github.com/valitydev/scoper.git", {tag, "v1.1.0"}}}, {party_client, {git, "https://github.com/valitydev/party-client-erlang.git", {tag, "v2.0.1"}}}, {bender_client, {git, "https://github.com/valitydev/bender-client-erlang.git", {tag, "v1.1.0"}}}, - {erl_health, {git, "https://github.com/valitydev/erlang-health.git", {branch, "master"}}}, + {erl_health, {git, "https://github.com/valitydev/erlang-health.git", {tag, "v1.0.0"}}}, {fault_detector_proto, {git, "https://github.com/valitydev/fault-detector-proto.git", {branch, "master"}}}, - {limiter_proto, {git, "https://github.com/valitydev/limiter-proto.git", {branch, "master"}}}, + {limiter_proto, {git, "https://github.com/valitydev/limiter-proto.git", {tag, "v2.1.0"}}}, {herd, {git, "https://github.com/wgnet/herd.git", {tag, "1.3.4"}}}, {progressor, {git, "https://github.com/valitydev/progressor.git", {tag, "v1.0.12"}}}, {prometheus, "4.11.0"}, diff --git a/rebar.lock b/rebar.lock index 025b36d2..f288c3ba 100644 --- a/rebar.lock +++ b/rebar.lock @@ -27,7 +27,7 @@ {<<"ctx">>,{pkg,<<"ctx">>,<<"0.6.0">>},2}, {<<"damsel">>, {git,"https://github.com/valitydev/damsel.git", - {ref,"1d0c1eceed23cedb46583ca67519b11abd69867a"}}, + {ref,"f831d3aa5fdfd0338b41af44d1eeffe810ca9708"}}, 0}, {<<"dmt_client">>, {git,"https://github.com/valitydev/dmt-client.git", @@ -43,12 +43,12 @@ 2}, {<<"eqwalizer_support">>, {git_subdir,"https://github.com/whatsapp/eqwalizer.git", - {ref,"092cf1e1e9854c8d2ef8fa8b9935b1dc45fff070"}, + {ref,"c4d1098174cec06bd124855f3a28dfd6eda0a581"}, "eqwalizer_support"}, 0}, {<<"erl_health">>, {git,"https://github.com/valitydev/erlang-health.git", - {ref,"49716470d0e8dab5e37db55d52dea78001735a3d"}}, + {ref,"63d34ef9fb60afea953dad9828330f4198614800"}}, 0}, {<<"fault_detector_proto">>, {git,"https://github.com/valitydev/fault-detector-proto.git", @@ -72,12 +72,12 @@ {<<"kafka_protocol">>,{pkg,<<"kafka_protocol">>,<<"4.1.10">>},2}, {<<"limiter_proto">>, {git,"https://github.com/valitydev/limiter-proto.git", - {ref,"d4cdf0f6328125996ee705c3da87461f99dde7f4"}}, + {ref,"1af3724af24dd8b5ad9ce2ae80cd42318b471397"}}, 0}, {<<"metrics">>,{pkg,<<"metrics">>,<<"1.0.1">>},2}, {<<"mg_proto">>, {git,"https://github.com/valitydev/machinegun-proto.git", - {ref,"3decc8f8b13c9cd1701deab47781aacddd7dbc92"}}, + {ref,"cc2c27c30d30dc34c0c56fc7c7e96326d6bd6a14"}}, 0}, {<<"mimerl">>,{pkg,<<"mimerl">>,<<"1.4.0">>},2}, {<<"msgpack_proto">>, @@ -122,7 +122,7 @@ {ref,"3a60e5dc5bbd709495024f26e100b041c3547fd9"}}, 1}, {<<"tls_certificate_check">>, - {pkg,<<"tls_certificate_check">>,<<"1.28.0">>}, + {pkg,<<"tls_certificate_check">>,<<"1.29.0">>}, 1}, {<<"unicode_util_compat">>,{pkg,<<"unicode_util_compat">>,<<"0.7.1">>},2}, {<<"woody">>, @@ -162,7 +162,7 @@ {<<"ranch">>, <<"8C7A100A139FD57F17327B6413E4167AC559FBC04CA7448E9BE9057311597A1D">>}, {<<"recon">>, <<"CBA53FA8DB83AD968C9A652E09C3ED7DDCC4DA434F27C3EAA9CA47FFB2B1FF03">>}, {<<"ssl_verify_fun">>, <<"354C321CF377240C7B8716899E182CE4890C5938111A1296ADD3EC74CF1715DF">>}, - {<<"tls_certificate_check">>, <<"C39BF21F67C2D124AE905454FAD00F27E625917E8AB1009146E916E1DF6AB275">>}, + {<<"tls_certificate_check">>, <<"4473005EB0BBDAD215D7083A230E2E076F538D9EA472C8009FD22006A4CFC5F6">>}, {<<"unicode_util_compat">>, <<"A48703A25C170EEDADCA83B11E88985AF08D35F37C6F664D6DCFB106A97782FC">>}]}, {pkg_hash_ext,[ {<<"accept">>, <<"CA69388943F5DAD2E7232A5478F16086E3C872F48E32B88B378E1885A59F5649">>}, @@ -196,6 +196,6 @@ {<<"ranch">>, <<"49FBCFD3682FAB1F5D109351B61257676DA1A2FDBE295904176D5E521A2DDFE5">>}, {<<"recon">>, <<"2C7523C8DEE91DFF41F6B3D63CBA2BD49EB6D2FE5BF1EEC0DF7F87EB5E230E1C">>}, {<<"ssl_verify_fun">>, <<"FE4C190E8F37401D30167C8C405EDA19469F34577987C76DDE613E838BBC67F8">>}, - {<<"tls_certificate_check">>, <<"3AB058C3F9457FFFCA916729587415F0DDC822048A0E5B5E2694918556D92DF1">>}, + {<<"tls_certificate_check">>, <<"5B0D0E5CB0F928BC4F210DF667304ED91C5BFF2A391CE6BDEDFBFE70A8F096C5">>}, {<<"unicode_util_compat">>, <<"B3A917854CE3AE233619744AD1E0102E05673136776FB2FA76234F3E03B23642">>}]} ]. diff --git a/test/bender/sys.config b/test/bender/sys.config new file mode 100644 index 00000000..3c20df9d --- /dev/null +++ b/test/bender/sys.config @@ -0,0 +1,183 @@ +[ + {bender, [ + %% Available options for 'machinery_backend' + %% machinegun | progressor | hybrid + %% + %% For 'progressor' and 'hybrid' backends ensure config + %% '{progressor, [ ... ]}' is set. + {machinery_backend, progressor}, + {services, #{ + bender => #{path => <<"/v1/bender">>}, + generator => #{path => <<"/v1/generator">>} + }}, + + {generator, #{ + path => <<"/v1/stateproc/bender_generator">>, + schema => machinery_mg_schema_generic, + % mandatory + url => <<"http://machinegun:8022/v1/automaton">>, + transport_opts => #{ + max_connections => 1000 + } + }}, + + {sequence, #{ + path => <<"/v1/stateproc/bender_sequence">>, + schema => machinery_mg_schema_generic, + % mandatory + url => <<"http://machinegun:8022/v1/automaton">>, + transport_opts => #{ + max_connections => 1000 + } + }}, + + {route_opts, #{ + % handler_limits => #{} + }}, + + {ip, "::"}, + {port, 8022}, + + {protocol_opts, #{ + % time in ms with no requests before Cowboy closes the connection + request_timeout => 5000 + }}, + % time in ms before woody forces connections closing + {shutdown_timeout, 7000}, + + {transport_opts, #{ + % timeout() | infinity, default is 5000 + handshake_timeout => 5000, + % maximum number of incoming connections, default is 1024 + max_connections => 10000, + % size of acceptors pool, default is 10 + num_acceptors => 100 + }}, + + {woody_event_handlers, [ + {scoper_woody_event_handler, #{ + event_handler_opts => #{ + formatter_opts => #{ + max_length => 1000, + max_printable_string_length => 80 + } + } + }} + ]}, + + {health_check, #{ + disk => {erl_health, disk, ["/", 99]}, + memory => {erl_health, cg_memory, [99]}, + service => {erl_health, service, [<<"bender">>]} + }} + ]}, + + {kernel, [ + {logger_sasl_compatible, false}, + {logger_level, debug}, + {logger, [ + {handler, default, logger_std_h, #{ + level => error, + config => #{ + type => standard_error + }, + formatter => + {logger_formatter, #{ + depth => 30 + }} + }}, + {handler, console, logger_std_h, #{ + config => #{ + type => {file, "/var/log/bender/log.json"} + }, + formatter => {logger_logstash_formatter, #{}} + }} + ]} + ]}, + + {epg_connector, [ + {databases, #{ + default_db => #{ + host => "db", + port => 5432, + username => "bender", + password => "postgres", + database => "bender" + } + }}, + {pools, #{ + default_pool => #{ + database => default_db, + size => 30 + } + }} + ]}, + + {progressor, [ + {call_wait_timeout, 20}, + {defaults, #{ + storage => #{ + client => prg_pg_backend, + options => #{ + pool => default_pool + } + }, + retry_policy => #{ + initial_timeout => 5, + backoff_coefficient => 1.0, + %% seconds + max_timeout => 180, + max_attempts => 3, + non_retryable_errors => [] + }, + task_scan_timeout => 1, + worker_pool_size => 100, + process_step_timeout => 30 + }}, + {namespaces, #{ + 'bender_generator' => #{ + processor => #{ + client => machinery_prg_backend, + options => #{ + namespace => 'bender_generator', + handler => {bender_generator, #{}}, + schema => machinery_mg_schema_generic + } + } + }, + 'bender_sequence' => #{ + processor => #{ + client => machinery_prg_backend, + options => #{ + namespace => 'bender_sequence', + handler => {bender_sequence, #{}}, + schema => machinery_mg_schema_generic + } + } + } + }} + ]}, + + {os_mon, [ + % for better compatibility with busybox coreutils + {disksup_posix_only, true} + ]}, + + {scoper, [ + {storage, scoper_storage_logger} + ]}, + + {snowflake, [ + % 1 second + {max_backward_clock_moving, 1000} + % {machine_id, hostname_hash} % you MUST set this option in production + ]}, + + {prometheus, [ + {collectors, [default]} + ]}, + + {hackney, [ + {mod_metrics, woody_hackney_prometheus} + ]} +]. diff --git a/test/machinegun/config.yaml b/test/machinegun/config.yaml deleted file mode 100644 index 1bea8b92..00000000 --- a/test/machinegun/config.yaml +++ /dev/null @@ -1,50 +0,0 @@ -service_name: machinegun -erlang: - secret_cookie_file: "/opt/machinegun/etc/cookie" -namespaces: - invoice: - processor: - url: http://hellgate:8022/v1/stateproc/invoice - pool_size: 300 - invoice_template: - processor: - url: http://hellgate:8022/v1/stateproc/invoice_template - pool_size: 300 - customer: - processor: - url: http://hellgate:8022/v1/stateproc/customer - pool_size: 300 - recurrent_paytools: - processor: - url: http://hellgate:8022/v1/stateproc/recurrent_paytools - pool_size: 300 - party: - processor: - url: http://party-management:8022/v1/stateproc/party - pool_size: 300 - lim/config_v1: - processor: - url: http://limiter:8022/v1/stateproc/lim/config_v1 - pool_size: 500 - lim/range_v1: - processor: - url: http://limiter:8022/v1/stateproc/lim/range_v1 - pool_size: 500 - bender_generator: - processor: - url: http://bender:8022/v1/stateproc/bender_generator - pool_size: 300 - bender_sequence: - processor: - url: http://bender:8022/v1/stateproc/bender_sequence - pool_size: 300 -storage: - type: memory - -woody_server: - max_concurrent_connections: 8000 - http_keep_alive_timeout: 15S - -logging: - out_type: stdout - level: info diff --git a/test/machinegun/cookie b/test/machinegun/cookie deleted file mode 100644 index 30d74d25..00000000 --- a/test/machinegun/cookie +++ /dev/null @@ -1 +0,0 @@ -test \ No newline at end of file