ED-184: migrate to party_client (#546)

This commit is contained in:
dinama 2021-06-28 18:43:17 +03:00 committed by GitHub
parent af3819613e
commit a1151e3ca3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
34 changed files with 556 additions and 326 deletions

View File

@ -17,10 +17,10 @@ SERVICE_IMAGE_PUSH_TAG ?= $(SERVICE_IMAGE_TAG)
# Base image for the service
BASE_IMAGE_NAME := service-erlang
BASE_IMAGE_TAG := d2b5ac42305aadae44d6f8b1d859fd1065749997
BASE_IMAGE_TAG := c114fc51a7b166d22144fcbf856f217dc7b5946f
BUILD_IMAGE_NAME := build-erlang
BUILD_IMAGE_TAG := cc2d319150ec0b9cd23ad9347692a8066616b0f4
BUILD_IMAGE_TAG := 2ea61e9556ad67d5918f060ed50353662ed84e59
CALL_ANYWHERE := \
submodules \

View File

@ -30,7 +30,8 @@
prometheus,
prometheus_cowboy,
bouncer_client,
token_keeper_client
token_keeper_client,
party_client
]},
{env, []}
]}.

View File

@ -17,7 +17,8 @@ allowed_origins(_, State) ->
-spec allowed_headers(cowboy_req:req(), any()) -> {[binary()], any()}.
allowed_headers(_, State) ->
{[
{
[
<<"x-requested-with">>,
<<"content-type">>,
<<"accept">>,
@ -25,7 +26,8 @@ allowed_headers(_, State) ->
<<"x-request-id">>,
<<"x-request-deadline">>
],
State}.
State
}.
-spec allowed_methods(cowboy_req:req(), any()) -> {[binary()], any()}.
allowed_methods(_, State) ->

View File

@ -21,7 +21,9 @@
-type processing_context() :: #{
operation_id := operation_id(),
swagger_context := swag_server:request_context(),
woody_context := woody_context:ctx()
woody_context := woody_context:ctx(),
party_client := party_client:client(),
party_client_context := party_client:context()
}.
-type throw(_T) :: no_return().
@ -31,14 +33,18 @@
process := fun(() -> {ok, response()} | throw(response()))
}.
-type handler_opts() ::
swag_server:handler_opts(#{
party_client := party_client:client()
}).
-export_type([operation_id/0]).
-export_type([request_data/0]).
-export_type([request_context/0]).
-export_type([processing_context/0]).
-export_type([request_state/0]).
-export_type([response/0]).
-type handler_opts() :: swag_server:handler_opts(_).
-export_type([handler_opts/0]).
%% Handler behaviour
@ -129,7 +135,7 @@ handle_request(OperationID, Req, SwagContext, HandlerOpts) ->
SwagContext :: request_context(),
HandlerOpts :: handler_opts()
) -> {ok | error, response()}.
handle_function_(OperationID, Req, SwagContext0, _HandlerOpts) ->
handle_function_(OperationID, Req, SwagContext0, HandlerOpts) ->
try
RpcID = create_rpc_id(Req),
ok = set_rpc_meta(RpcID),
@ -138,10 +144,10 @@ handle_function_(OperationID, Req, SwagContext0, _HandlerOpts) ->
WoodyContext0 = attach_deadline(Req, create_woody_context(RpcID)),
SwagContext = do_authorize_api_key(SwagContext0, WoodyContext0),
WoodyContext = put_user_identity(WoodyContext0, get_auth_context(SwagContext)),
Context = create_processing_context(OperationID, SwagContext, WoodyContext),
Context = create_processing_context(OperationID, SwagContext, WoodyContext, HandlerOpts),
ok = set_context_meta(Context),
{ok, #{authorize := Authorize, process := Process}} =
prepare(OperationID, Req, Context, get_handlers()),
{ok, RequestState} = prepare(OperationID, Req, Context, get_handlers()),
#{authorize := Authorize, process := Process} = RequestState,
{ok, Resolution} = Authorize(),
case Resolution of
allowed ->
@ -219,11 +225,13 @@ make_token_context(#{cowboy_req := CowboyReq}) ->
undefined
end.
create_processing_context(OperationID, SwaggerContext, WoodyContext) ->
create_processing_context(OperationID, SwaggerContext, WoodyContext, HandlerOpts) ->
#{
operation_id => OperationID,
woody_context => WoodyContext,
swagger_context => SwaggerContext
swagger_context => SwaggerContext,
party_client_context => party_client:create_context(#{woody_context => WoodyContext}),
party_client => maps:get(party_client, HandlerOpts)
}.
-spec create_rpc_id(request_data()) -> woody:rpc_id().

View File

@ -21,12 +21,10 @@ prepare(OperationID, Req, Context) when OperationID =:= 'GetAccountByID' ->
end,
Process = fun() ->
AccountID = genlib:to_int(maps:get('accountID', Req)),
CallArgs = {PartyID, AccountID},
Call = {party_management, 'GetAccountState', CallArgs},
case capi_handler_utils:service_call_with([user_info], Call, Context) of
case capi_party:get_account_state(PartyID, AccountID, Context) of
{ok, S} ->
{ok, {200, #{}, decode_account_state(S)}};
{exception, #payproc_AccountNotFound{}} ->
{error, #payproc_AccountNotFound{}} ->
{ok, general_error(404, <<"Account not found">>)}
end
end,

View File

@ -22,10 +22,7 @@ prepare(OperationID = 'GetClaims', Req, Context) ->
{ok, capi_auth:authorize_operation(Prototypes, Context, Req)}
end,
Process = fun() ->
Call = {party_management, 'GetClaims', {PartyID}},
Claims = capi_utils:unwrap(
capi_handler_utils:service_call_with([user_info], Call, Context)
),
Claims = capi_utils:unwrap(capi_party:get_claims(PartyID, Context)),
{ok, {200, #{}, decode_claims(filter_claims(maps:get('claimStatus', Req), Claims))}}
end,
{ok, #{authorize => Authorize, process => Process}};
@ -39,9 +36,7 @@ prepare(OperationID = 'GetClaimByID', Req, Context) ->
{ok, capi_auth:authorize_operation(Prototypes, Context, Req)}
end,
Process = fun() ->
CallArgs = {PartyID, genlib:to_int(ClaimID)},
Call = {party_management, 'GetClaim', CallArgs},
case capi_handler_utils:service_call_with([user_info], Call, Context) of
case capi_party:get_claim(PartyID, genlib:to_int(ClaimID), Context) of
{ok, Claim} ->
case is_wallet_claim(Claim) of
true ->
@ -50,7 +45,7 @@ prepare(OperationID = 'GetClaimByID', Req, Context) ->
false ->
{ok, {200, #{}, decode_claim(Claim)}}
end;
{exception, #payproc_ClaimNotFound{}} ->
{error, #payproc_ClaimNotFound{}} ->
{ok, general_error(404, <<"Claim not found">>)}
end
end,
@ -66,12 +61,10 @@ prepare(OperationID = 'CreateClaim', Req, Context) ->
{ok, capi_auth:authorize_operation(Prototypes, Context, Req)}
end,
Process = fun() ->
CallArgs = {PartyID, Changeset},
Call = {party_management, 'CreateClaim', CallArgs},
case capi_handler_utils:service_call_with([user_info], Call, Context) of
case capi_party:create_claim(PartyID, Changeset, Context) of
{ok, Claim} ->
{ok, {201, #{}, decode_claim(Claim)}};
{exception, Exception} ->
{error, Exception} ->
case Exception of
#payproc_InvalidPartyStatus{} ->
{ok, logic_error(invalidPartyStatus, <<"Invalid party status">>)};
@ -107,15 +100,12 @@ prepare(OperationID = 'CreateClaim', Req, Context) ->
% {ok, capi_auth:authorize_operation(Prototypes, Context, Req)}
% end,
% Process = fun() ->
% Call =
% {party_management, 'UpdateClaim', {
% Party = capi_utils:unwrap(
% capi_party:update_claim(
% PartyID,
% genlib:to_int(ClaimID),
% genlib:to_int(maps:get('claimRevision', Req)),
% encode_claim_changeset(maps:get('claimChangeset', Req))
% }},
% Party = capi_utils:unwrap(
% capi_handler_utils:service_call_with([user_info], Call, Context)
% encode_claim_changeset(maps:get('claimChangeset', Req)), Context)
% ),
% {ok, {200, #{}, capi_handler_decoder_party:decode_party(Party)}}
% end,
@ -130,17 +120,17 @@ prepare(OperationID = 'RevokeClaimByID', Req, Context) ->
{ok, capi_auth:authorize_operation(Prototypes, Context, Req)}
end,
Process = fun() ->
CallArgs = {
Result = capi_party:revoke_claim(
PartyID,
genlib:to_int(ClaimID),
genlib:to_int(maps:get('claimRevision', Req)),
encode_reason(maps:get('Reason', Req))
},
Call = {party_management, 'RevokeClaim', CallArgs},
case capi_handler_utils:service_call_with([user_info], Call, Context) of
{ok, _} ->
encode_reason(maps:get('Reason', Req)),
Context
),
case Result of
ok ->
{ok, {204, #{}, undefined}};
{exception, Exception} ->
{error, Exception} ->
case Exception of
#payproc_InvalidPartyStatus{} ->
{ok, logic_error(invalidPartyStatus, <<"Invalid party status">>)};

View File

@ -14,27 +14,30 @@
Context :: capi_handler:processing_context()
) -> {ok, capi_handler:request_state()} | {error, noimpl}.
prepare(OperationID = 'GetContracts', Req, Context) ->
Party = capi_utils:unwrap(capi_handler_utils:get_party(Context)),
PartyID = capi_handler_utils:get_party_id(Context),
Authorize = fun() ->
Prototypes = [
{operation, #{party => Party#domain_Party.id, id => OperationID}}
{operation, #{party => PartyID, id => OperationID}}
],
{ok, capi_auth:authorize_operation(Prototypes, Context, Req)}
end,
Process = fun() ->
{ok, Party} = capi_party:get_party(PartyID, Context),
{ok, {200, #{}, decode_contracts_map(Party#domain_Party.contracts, Party#domain_Party.contractors)}}
end,
{ok, #{authorize => Authorize, process => Process}};
prepare(OperationID = 'GetContractByID', Req, Context) ->
ContractID = maps:get('contractID', Req),
Party = capi_utils:unwrap(capi_handler_utils:get_party(Context)),
PartyID = capi_handler_utils:get_party_id(Context),
Authorize = fun() ->
Prototypes = [
{operation, #{party => Party#domain_Party.id, contract => ContractID, id => OperationID}}
{operation, #{party => PartyID, contract => ContractID, id => OperationID}}
],
{ok, capi_auth:authorize_operation(Prototypes, Context, Req)}
end,
Process = fun() ->
% Получение Party требуется для извлечения domain_Party.contractors
{ok, Party} = capi_party:get_party(PartyID, Context),
case genlib_map:get(ContractID, Party#domain_Party.contracts) of
undefined ->
{ok, general_error(404, <<"Contract not found">>)};
@ -45,34 +48,34 @@ prepare(OperationID = 'GetContractByID', Req, Context) ->
{ok, #{authorize => Authorize, process => Process}};
prepare(OperationID = 'GetContractAdjustments', Req, Context) ->
ContractID = maps:get('contractID', Req),
Party = capi_utils:unwrap(capi_handler_utils:get_party(Context)),
PartyID = capi_handler_utils:get_party_id(Context),
Authorize = fun() ->
Prototypes = [
{operation, #{party => Party#domain_Party.id, contract => ContractID, id => OperationID}}
{operation, #{party => PartyID, contract => ContractID, id => OperationID}}
],
{ok, capi_auth:authorize_operation(Prototypes, Context, Req)}
end,
Process = fun() ->
case capi_handler_utils:get_contract_by_id(ContractID, Context) of
case capi_party:get_contract(PartyID, ContractID, Context) of
{ok, #domain_Contract{adjustments = Adjustments}} ->
Resp = [decode_contract_adjustment(A) || A <- Adjustments],
{ok, {200, #{}, Resp}};
{exception, #payproc_ContractNotFound{}} ->
{error, #payproc_ContractNotFound{}} ->
{ok, general_error(404, <<"Contract not found">>)}
end
end,
{ok, #{authorize => Authorize, process => Process}};
prepare(OperationID = 'GetContractAdjustmentByID', Req, Context) ->
ContractID = maps:get('contractID', Req),
Party = capi_utils:unwrap(capi_handler_utils:get_party(Context)),
PartyID = capi_handler_utils:get_party_id(Context),
Authorize = fun() ->
Prototypes = [
{operation, #{party => Party#domain_Party.id, contract => ContractID, id => OperationID}}
{operation, #{party => PartyID, contract => ContractID, id => OperationID}}
],
{ok, capi_auth:authorize_operation(Prototypes, Context, Req)}
end,
Process = fun() ->
case capi_handler_utils:get_contract_by_id(ContractID, Context) of
case capi_party:get_contract(PartyID, ContractID, Context) of
{ok, #domain_Contract{adjustments = Adjustments}} ->
AdjustmentID = maps:get('adjustmentID', Req),
case lists:keyfind(AdjustmentID, #domain_ContractAdjustment.id, Adjustments) of
@ -81,17 +84,13 @@ prepare(OperationID = 'GetContractAdjustmentByID', Req, Context) ->
false ->
{ok, general_error(404, <<"Adjustment not found">>)}
end;
{exception, #payproc_ContractNotFound{}} ->
{error, #payproc_ContractNotFound{}} ->
{ok, general_error(404, <<"Contract not found">>)}
end
end,
{ok, #{authorize => Authorize, process => Process}};
prepare(OperationID = 'GetContractsForParty', Req, Context) ->
PartyID = maps:get('partyID', Req),
% TODO
% Here we're relying on hellgate ownership check, thus no explicit authorization.
% Hovewer we're going to drop hellgate authz eventually, then we'll need to make sure that operation
% remains authorized.
Authorize = fun() ->
Prototypes = [
{operation, #{party => PartyID, id => OperationID}}
@ -99,12 +98,12 @@ prepare(OperationID = 'GetContractsForParty', Req, Context) ->
{ok, capi_auth:authorize_operation(Prototypes, Context, Req)}
end,
Process = fun() ->
case capi_handler_utils:get_party(PartyID, Context) of
case capi_party:get_party(PartyID, Context) of
{ok, Party} ->
{ok, {200, #{}, decode_contracts_map(Party#domain_Party.contracts, Party#domain_Party.contractors)}};
{exception, #payproc_InvalidUser{}} ->
{error, #payproc_InvalidUser{}} ->
{ok, general_error(404, <<"Party not found">>)};
{exception, #payproc_PartyNotFound{}} ->
{error, #payproc_PartyNotFound{}} ->
{ok, general_error(404, <<"Party not found">>)}
end
end,
@ -112,10 +111,6 @@ prepare(OperationID = 'GetContractsForParty', Req, Context) ->
prepare(OperationID = 'GetContractByIDForParty', Req, Context) ->
ContractID = maps:get('contractID', Req),
PartyID = maps:get('partyID', Req),
% TODO
% Here we're relying on hellgate ownership check, thus no explicit authorization.
% Hovewer we're going to drop hellgate authz eventually, then we'll need to make sure that operation
% remains authorized.
Authorize = fun() ->
Prototypes = [
{operation, #{party => PartyID, contract => ContractID, id => OperationID}}
@ -123,28 +118,19 @@ prepare(OperationID = 'GetContractByIDForParty', Req, Context) ->
{ok, capi_auth:authorize_operation(Prototypes, Context, Req)}
end,
Process = fun() ->
case capi_handler_utils:get_party(PartyID, Context) of
{ok, Party} ->
case genlib_map:get(ContractID, Party#domain_Party.contracts) of
undefined ->
{ok, general_error(404, <<"Contract not found">>)};
Contract ->
{ok, {200, #{}, decode_contract(Contract, Party#domain_Party.contractors)}}
end;
{exception, #payproc_InvalidUser{}} ->
{ok, general_error(404, <<"Party not found">>)};
{exception, #payproc_PartyNotFound{}} ->
{ok, general_error(404, <<"Party not found">>)}
case capi_party:get_contract(PartyID, ContractID, Context) of
{ok, Contract} ->
% Получение Party требуется для извлечения domain_Party.contractors
{ok, Party} = capi_party:get_party(PartyID, Context),
{ok, {200, #{}, decode_contract(Contract, Party#domain_Party.contractors)}};
{error, #payproc_ContractNotFound{}} ->
{ok, general_error(404, <<"Contract not found">>)}
end
end,
{ok, #{authorize => Authorize, process => Process}};
prepare(OperationID = 'GetContractAdjustmentsForParty', Req, Context) ->
ContractID = maps:get('contractID', Req),
PartyID = maps:get('partyID', Req),
% TODO
% Here we're relying on hellgate ownership check, thus no explicit authorization.
% Hovewer we're going to drop hellgate authz eventually, then we'll need to make sure that operation
% remains authorized.
Authorize = fun() ->
Prototypes = [
{operation, #{party => PartyID, contract => ContractID, id => OperationID}}
@ -152,15 +138,15 @@ prepare(OperationID = 'GetContractAdjustmentsForParty', Req, Context) ->
{ok, capi_auth:authorize_operation(Prototypes, Context, Req)}
end,
Process = fun() ->
case capi_handler_utils:get_contract_by_id(PartyID, ContractID, Context) of
case capi_party:get_contract(PartyID, ContractID, Context) of
{ok, #domain_Contract{adjustments = Adjustments}} ->
Resp = [decode_contract_adjustment(A) || A <- Adjustments],
{ok, {200, #{}, Resp}};
{exception, #payproc_InvalidUser{}} ->
{error, #payproc_InvalidUser{}} ->
{ok, general_error(404, <<"Party not found">>)};
{exception, #payproc_PartyNotFound{}} ->
{error, #payproc_PartyNotFound{}} ->
{ok, general_error(404, <<"Party not found">>)};
{exception, #payproc_ContractNotFound{}} ->
{error, #payproc_ContractNotFound{}} ->
{ok, general_error(404, <<"Contract not found">>)}
end
end,
@ -168,10 +154,6 @@ prepare(OperationID = 'GetContractAdjustmentsForParty', Req, Context) ->
prepare(OperationID = 'GetContractAdjustmentByIDForParty', Req, Context) ->
ContractID = maps:get('contractID', Req),
PartyID = maps:get('partyID', Req),
% TODO
% Here we're relying on hellgate ownership check, thus no explicit authorization.
% Hovewer we're going to drop hellgate authz eventually, then we'll need to make sure that operation
% remains authorized.
Authorize = fun() ->
Prototypes = [
{operation, #{party => PartyID, contract => ContractID, id => OperationID}}
@ -179,7 +161,7 @@ prepare(OperationID = 'GetContractAdjustmentByIDForParty', Req, Context) ->
{ok, capi_auth:authorize_operation(Prototypes, Context, Req)}
end,
Process = fun() ->
case capi_handler_utils:get_contract_by_id(PartyID, ContractID, Context) of
case capi_party:get_contract(PartyID, ContractID, Context) of
{ok, #domain_Contract{adjustments = Adjustments}} ->
AdjustmentID = maps:get('adjustmentID', Req),
case lists:keyfind(AdjustmentID, #domain_ContractAdjustment.id, Adjustments) of
@ -188,11 +170,11 @@ prepare(OperationID = 'GetContractAdjustmentByIDForParty', Req, Context) ->
false ->
{ok, general_error(404, <<"Adjustment not found">>)}
end;
{exception, #payproc_InvalidUser{}} ->
{error, #payproc_InvalidUser{}} ->
{ok, general_error(404, <<"Party not found">>)};
{exception, #payproc_PartyNotFound{}} ->
{error, #payproc_PartyNotFound{}} ->
{ok, general_error(404, <<"Party not found">>)};
{exception, #payproc_ContractNotFound{}} ->
{error, #payproc_ContractNotFound{}} ->
{ok, general_error(404, <<"Contract not found">>)}
end
end,

View File

@ -549,15 +549,15 @@ decode_bank_card(#domain_BankCardPaymentMethod{payment_system_deprecated = PS})
decode_tokenized_bank_cards([#domain_BankCardPaymentMethod{} | _] = TokenizedBankCards) ->
PropTokenizedBankCards = [
{TP, PS}
|| #domain_BankCardPaymentMethod{payment_system_deprecated = PS, token_provider_deprecated = TP} <-
TokenizedBankCards
|| #domain_BankCardPaymentMethod{payment_system_deprecated = PS, token_provider_deprecated = TP} <-
TokenizedBankCards
],
do_decode_tokenized_bank_cards(PropTokenizedBankCards);
decode_tokenized_bank_cards([#domain_TokenizedBankCard{} | _] = TokenizedBankCards) ->
PropTokenizedBankCards = [
{TP, PS}
|| #domain_TokenizedBankCard{payment_system_deprecated = PS, token_provider_deprecated = TP} <-
TokenizedBankCards
|| #domain_TokenizedBankCard{payment_system_deprecated = PS, token_provider_deprecated = TP} <-
TokenizedBankCards
],
do_decode_tokenized_bank_cards(PropTokenizedBankCards);
decode_tokenized_bank_cards([]) ->

View File

@ -257,9 +257,10 @@ prepare('GetInvoicePaymentMethodsByTemplateID' = OperationID, Req, Context) ->
Process = fun() ->
capi_handler:respond_if_undefined(InvoiceTemplate, general_error(404, <<"Invoice template not found">>)),
Timestamp = genlib_rfc3339:format_relaxed(erlang:system_time(microsecond), microsecond),
{ok, Party} = capi_handler_utils:get_party(Context),
Revision = Party#domain_Party.revision,
Args = {InvoiceTemplateID, Timestamp, {revision, Revision}},
PartyID = InvoiceTemplate#domain_InvoiceTemplate.owner_id,
% В данном контексте - Party не может не существовать
{ok, Party} = capi_party:get_party(PartyID, Context),
Args = {InvoiceTemplateID, Timestamp, {revision, Party#domain_Party.revision}},
case capi_handler_decoder_invoicing:construct_payment_methods(invoice_templating, Args, Context) of
{ok, PaymentMethods0} when is_list(PaymentMethods0) ->
PaymentMethods = capi_utils:deduplicate_payment_methods(PaymentMethods0),

View File

@ -256,18 +256,27 @@ prepare('GetInvoiceEvents' = OperationID, Req, Context) ->
{ok, #{authorize => Authorize, process => Process}};
prepare('GetInvoicePaymentMethods' = OperationID, Req, Context) ->
InvoiceID = maps:get(invoiceID, Req),
ResultInvoice =
case capi_handler_utils:get_invoice_by_id(InvoiceID, Context) of
{ok, Result} ->
Result;
{exception, _Exception} ->
undefined
end,
Authorize = fun() ->
Prototypes = [
{operation, #{id => OperationID, invoice => InvoiceID}},
{payproc, #{invoice => InvoiceID}}
{payproc, #{invoice => ResultInvoice}}
],
Resolution = capi_auth:authorize_operation(Prototypes, Context, Req),
{ok, Resolution}
end,
Process = fun() ->
Party = capi_utils:unwrap(capi_handler_utils:get_party(Context)),
Revision = Party#domain_Party.revision,
Args = {InvoiceID, {revision, Revision}},
capi_handler:respond_if_undefined(ResultInvoice, general_error(404, <<"Invoice not found">>)),
PartyID = ResultInvoice#payproc_Invoice.invoice#domain_Invoice.owner_id,
% В данном контексте - Party не может не существовать
{ok, Party} = capi_party:get_party(PartyID, Context),
Args = {InvoiceID, {revision, Party#domain_Party.revision}},
case capi_handler_decoder_invoicing:construct_payment_methods(invoicing, Args, Context) of
{ok, PaymentMethods0} when is_list(PaymentMethods0) ->
PaymentMethods = capi_utils:deduplicate_payment_methods(PaymentMethods0),

View File

@ -26,9 +26,9 @@ prepare('GetMyParty' = OperationID, Req, Context) ->
{ok, Party} ->
DecodedParty = capi_handler_decoder_party:decode_party(Party),
{ok, {200, #{}, DecodedParty}};
{exception, #payproc_InvalidUser{}} ->
{error, #payproc_InvalidUser{}} ->
{ok, logic_error(<<"invalidRequest">>, <<"Party not found">>)};
{exception, #payproc_PartyNotFound{}} ->
{error, #payproc_PartyNotFound{}} ->
{ok, logic_error(<<"invalidRequest">>, <<"Party not found">>)}
end
end,
@ -40,15 +40,14 @@ prepare('ActivateMyParty' = OperationID, Req, Context) ->
{ok, capi_auth:authorize_operation(Prototypes, Context, Req)}
end,
Process = fun() ->
Call = {party_management, 'Activate', {PartyID}},
case capi_handler_utils:service_call_with([user_info], Call, Context) of
{ok, _R} ->
case capi_party:activate_party(PartyID, Context) of
ok ->
{ok, {204, #{}, undefined}};
{exception, #payproc_InvalidUser{}} ->
{error, #payproc_InvalidUser{}} ->
{ok, logic_error(<<"invalidRequest">>, <<"Party not found">>)};
{exception, #payproc_PartyNotFound{}} ->
{error, #payproc_PartyNotFound{}} ->
{ok, logic_error(<<"invalidRequest">>, <<"Party not found">>)};
{exception, #payproc_InvalidPartyStatus{status = {suspension, {active, _}}}} ->
{error, #payproc_InvalidPartyStatus{status = {suspension, {active, _}}}} ->
{ok, logic_error(<<"invalidRequest">>, <<"Invalid party status">>)}
end
end,
@ -60,15 +59,14 @@ prepare('SuspendMyParty' = OperationID, Req, Context) ->
{ok, capi_auth:authorize_operation(Prototypes, Context, Req)}
end,
Process = fun() ->
Call = {party_management, 'Suspend', {PartyID}},
case capi_handler_utils:service_call_with([user_info], Call, Context) of
{ok, _R} ->
case capi_party:suspend_party(PartyID, Context) of
ok ->
{ok, {204, #{}, undefined}};
{exception, #payproc_InvalidUser{}} ->
{error, #payproc_InvalidUser{}} ->
{ok, logic_error(<<"invalidRequest">>, <<"Party not found">>)};
{exception, #payproc_PartyNotFound{}} ->
{error, #payproc_PartyNotFound{}} ->
{ok, logic_error(<<"invalidRequest">>, <<"Party not found">>)};
{exception, #payproc_InvalidPartyStatus{status = {suspension, {suspended, _}}}} ->
{error, #payproc_InvalidPartyStatus{status = {suspension, {suspended, _}}}} ->
{ok, logic_error(<<"invalidRequest">>, <<"Invalid party status">>)}
end
end,
@ -80,13 +78,13 @@ prepare('GetPartyByID' = OperationID, Req, Context) ->
{ok, capi_auth:authorize_operation(Prototypes, Context, Req)}
end,
Process = fun() ->
case capi_handler_utils:get_party(PartyID, Context) of
case capi_party:get_party(PartyID, Context) of
{ok, Party} ->
DecodedParty = capi_handler_decoder_party:decode_party(Party),
{ok, {200, #{}, DecodedParty}};
{exception, #payproc_InvalidUser{}} ->
{error, #payproc_InvalidUser{}} ->
{ok, general_error(404, <<"Party not found">>)};
{exception, #payproc_PartyNotFound{}} ->
{error, #payproc_PartyNotFound{}} ->
{ok, general_error(404, <<"Party not found">>)}
end
end,
@ -98,15 +96,14 @@ prepare('ActivatePartyByID' = OperationID, Req, Context) ->
{ok, capi_auth:authorize_operation(Prototypes, Context, Req)}
end,
Process = fun() ->
Call = {party_management, 'Activate', {PartyID}},
case capi_handler_utils:service_call_with([user_info], Call, Context) of
{ok, _R} ->
case capi_party:activate_party(PartyID, Context) of
ok ->
{ok, {204, #{}, undefined}};
{exception, #payproc_InvalidUser{}} ->
{error, #payproc_InvalidUser{}} ->
{ok, general_error(404, <<"Party not found">>)};
{exception, #payproc_PartyNotFound{}} ->
{error, #payproc_PartyNotFound{}} ->
{ok, general_error(404, <<"Party not found">>)};
{exception, #payproc_InvalidPartyStatus{status = {suspension, {active, _}}}} ->
{error, #payproc_InvalidPartyStatus{status = {suspension, {active, _}}}} ->
{ok, logic_error(<<"invalidRequest">>, <<"Invalid party status">>)}
end
end,
@ -118,15 +115,14 @@ prepare('SuspendPartyByID' = OperationID, Req, Context) ->
{ok, capi_auth:authorize_operation(Prototypes, Context, Req)}
end,
Process = fun() ->
Call = {party_management, 'Suspend', {PartyID}},
case capi_handler_utils:service_call_with([user_info], Call, Context) of
{ok, _R} ->
case capi_party:suspend_party(PartyID, Context) of
ok ->
{ok, {204, #{}, undefined}};
{exception, #payproc_InvalidUser{}} ->
{error, #payproc_InvalidUser{}} ->
{ok, general_error(404, <<"Party not found">>)};
{exception, #payproc_PartyNotFound{}} ->
{error, #payproc_PartyNotFound{}} ->
{ok, general_error(404, <<"Party not found">>)};
{exception, #payproc_InvalidPartyStatus{status = {suspension, {suspended, _}}}} ->
{error, #payproc_InvalidPartyStatus{status = {suspension, {suspended, _}}}} ->
{ok, logic_error(<<"invalidRequest">>, <<"Invalid party status">>)}
end
end,
@ -138,8 +134,8 @@ prepare(_OperationID, _Req, _Context) ->
-spec get_or_create_party(binary(), processing_context()) -> woody:result().
get_or_create_party(PartyID, Context) ->
case capi_handler_utils:get_party(PartyID, Context) of
{exception, #payproc_PartyNotFound{}} ->
case capi_party:get_party(PartyID, Context) of
{error, #payproc_PartyNotFound{}} ->
_ = logger:info("Attempting to create a missing party"),
create_party(PartyID, Context);
Reply ->
@ -156,12 +152,11 @@ create_party(PartyID, Context) ->
)
}
},
Call = {party_management, 'Create', {PartyID, PartyParams}},
case capi_handler_utils:service_call_with([user_info], Call, Context) of
{ok, _} ->
capi_handler_utils:get_party(PartyID, Context);
{exception, #payproc_PartyExists{}} ->
capi_handler_utils:get_party(PartyID, Context);
case capi_party:create_party(PartyID, PartyParams, Context) of
ok ->
capi_party:get_party(PartyID, Context);
{error, #payproc_PartyExists{}} ->
capi_party:get_party(PartyID, Context);
Error ->
Error
end.

View File

@ -60,7 +60,7 @@ prepare(OperationID = 'GetPaymentInstitutionPaymentTerms', Req, Context) ->
case compute_payment_institution_terms(PaymentInstitutionID, #payproc_Varset{}, Context) of
{ok, #domain_TermSet{payments = PaymentTerms}} ->
{ok, {200, #{}, decode_payment_terms(PaymentTerms)}};
{exception, #payproc_PaymentInstitutionNotFound{}} ->
{error, #payproc_PaymentInstitutionNotFound{}} ->
{ok, general_error(404, <<"Payment institution not found">>)}
end
end,
@ -74,7 +74,7 @@ prepare(OperationID = 'GetPaymentInstitutionPayoutMethods', Req, Context) ->
{ok, {200, #{}, decode_payout_methods_selector(PayoutMethods)}};
{ok, #domain_TermSet{payouts = undefined}} ->
{ok, general_error(404, <<"Automatic payouts not allowed">>)};
{exception, #payproc_PaymentInstitutionNotFound{}} ->
{error, #payproc_PaymentInstitutionNotFound{}} ->
{ok, general_error(404, <<"Payment institution not found">>)}
end
end,
@ -88,7 +88,7 @@ prepare(OperationID = 'GetPaymentInstitutionPayoutSchedules', Req, Context) ->
{ok, {200, #{}, decode_business_schedules_selector(Schedules)}};
{ok, #domain_TermSet{payouts = undefined}} ->
{ok, general_error(404, <<"Automatic payouts not allowed">>)};
{exception, #payproc_PaymentInstitutionNotFound{}} ->
{error, #payproc_PaymentInstitutionNotFound{}} ->
{ok, general_error(404, <<"Payment institution not found">>)}
end
end,
@ -125,9 +125,8 @@ check_payment_institution_residence(Residence, #domain_PaymentInstitutionObject{
ordsets:is_element(Residence, Residences).
compute_payment_institution_terms(PaymentInstitutionID, VS, Context) ->
CallArgs = {?payment_institution_ref(PaymentInstitutionID), VS},
Call = {party_management, 'ComputePaymentInstitutionTerms', CallArgs},
capi_handler_utils:service_call_with([user_info], Call, Context).
Ref = ?payment_institution_ref(PaymentInstitutionID),
capi_party:compute_payment_institution_terms(Ref, VS, Context).
prepare_request_varset(Req, Context) ->
#payproc_Varset{
@ -160,7 +159,7 @@ decode_payment_institution_obj(#domain_PaymentInstitutionObject{ref = Ref, data
<<"realm">> => genlib:to_binary(Data#domain_PaymentInstitution.realm),
<<"residences">> => [
capi_handler_decoder_party:decode_residence(R)
|| R <- ordsets:to_list(Data#domain_PaymentInstitution.residences)
|| R <- ordsets:to_list(Data#domain_PaymentInstitution.residences)
]
}).

View File

@ -364,7 +364,7 @@ prepare(OperationID = 'GetRefunds', Req, Context) ->
{ok,
{200, #{}, [
capi_handler_decoder_invoicing:decode_refund(R, Context)
|| #payproc_InvoicePaymentRefund{refund = R} <- Refunds
|| #payproc_InvoicePaymentRefund{refund = R} <- Refunds
]}};
{error, payment_not_found} ->
{ok, general_error(404, <<"Payment not found">>)}

View File

@ -77,32 +77,34 @@ prepare(OperationID, Req, Context) when OperationID =:= 'CreatePayout' ->
end,
{ok, #{authorize => Authorize, process => Process}};
prepare(OperationID, Req, Context) when OperationID =:= 'GetPayoutTools' ->
PartyID = capi_handler_utils:get_party_id(Context),
OperationContext = #{
id => OperationID,
party => capi_handler_utils:get_party_id(Context)
party => PartyID
},
Authorize = fun() ->
{ok, capi_auth:authorize_operation([{operation, OperationContext}], Context, Req)}
end,
Process = fun() ->
case capi_handler_utils:get_contract_by_id(maps:get('contractID', Req), Context) of
case capi_party:get_contract(PartyID, maps:get('contractID', Req), Context) of
{ok, #domain_Contract{payout_tools = PayoutTools}} ->
{ok, {200, #{}, [decode_payout_tool(P) || P <- PayoutTools]}};
{exception, #payproc_ContractNotFound{}} ->
{error, #payproc_ContractNotFound{}} ->
{ok, general_error(404, <<"Contract not found">>)}
end
end,
{ok, #{authorize => Authorize, process => Process}};
prepare(OperationID, Req, Context) when OperationID =:= 'GetPayoutToolByID' ->
PartyID = capi_handler_utils:get_party_id(Context),
OperationContext = #{
id => OperationID,
party => capi_handler_utils:get_party_id(Context)
party => PartyID
},
Authorize = fun() ->
{ok, capi_auth:authorize_operation([{operation, OperationContext}], Context, Req)}
end,
Process = fun() ->
case capi_handler_utils:get_contract_by_id(maps:get('contractID', Req), Context) of
case capi_party:get_contract(PartyID, maps:get('contractID', Req), Context) of
{ok, #domain_Contract{payout_tools = PayoutTools}} ->
PayoutToolID = maps:get('payoutToolID', Req),
case lists:keyfind(PayoutToolID, #domain_PayoutTool.id, PayoutTools) of
@ -111,7 +113,7 @@ prepare(OperationID, Req, Context) when OperationID =:= 'GetPayoutToolByID' ->
false ->
{ok, general_error(404, <<"PayoutTool not found">>)}
end;
{exception, #payproc_ContractNotFound{}} ->
{error, #payproc_ContractNotFound{}} ->
{ok, general_error(404, <<"Contract not found">>)}
end
end,
@ -127,10 +129,10 @@ prepare(OperationID, Req, Context) when OperationID =:= 'GetPayoutToolsForParty'
end,
Process = fun() ->
ContractID = maps:get('contractID', Req),
case capi_handler_utils:get_contract_by_id(PartyID, ContractID, Context) of
case capi_party:get_contract(PartyID, ContractID, Context) of
{ok, #domain_Contract{payout_tools = PayoutTools}} ->
{ok, {200, #{}, [decode_payout_tool(P) || P <- PayoutTools]}};
{exception, #payproc_ContractNotFound{}} ->
{error, #payproc_ContractNotFound{}} ->
{ok, general_error(404, <<"Contract not found">>)}
end
end,
@ -146,7 +148,7 @@ prepare(OperationID, Req, Context) when OperationID =:= 'GetPayoutToolByIDForPar
end,
Process = fun() ->
ContractID = maps:get('contractID', Req),
case capi_handler_utils:get_contract_by_id(PartyID, ContractID, Context) of
case capi_party:get_contract(PartyID, ContractID, Context) of
{ok, #domain_Contract{payout_tools = PayoutTools}} ->
PayoutToolID = maps:get('payoutToolID', Req),
case lists:keyfind(PayoutToolID, #domain_PayoutTool.id, PayoutTools) of
@ -155,7 +157,7 @@ prepare(OperationID, Req, Context) when OperationID =:= 'GetPayoutToolByIDForPar
false ->
{ok, general_error(404, <<"PayoutTool not found">>)}
end;
{exception, #payproc_ContractNotFound{}} ->
{error, #payproc_ContractNotFound{}} ->
{ok, general_error(404, <<"Contract not found">>)}
end
end,

View File

@ -21,11 +21,10 @@ prepare(OperationID = 'ActivateShop', Req, Context) ->
{ok, capi_auth:authorize_operation(Prototypes, Context, Req)}
end,
Process = fun() ->
Call = {party_management, 'ActivateShop', {PartyID, ShopID}},
case capi_handler_utils:service_call_with([user_info], Call, Context) of
{ok, _R} ->
case capi_party:activate_shop(PartyID, ShopID, Context) of
ok ->
{ok, {204, #{}, undefined}};
{exception, Exception} ->
{error, Exception} ->
case Exception of
#payproc_ShopNotFound{} ->
{ok, general_error(404, <<"Shop not found">>)};
@ -43,11 +42,10 @@ prepare(OperationID = 'SuspendShop', Req, Context) ->
{ok, capi_auth:authorize_operation(Prototypes, Context, Req)}
end,
Process = fun() ->
Call = {party_management, 'SuspendShop', {PartyID, ShopID}},
case capi_handler_utils:service_call_with([user_info], Call, Context) of
{ok, _R} ->
case capi_party:suspend_shop(PartyID, ShopID, Context) of
ok ->
{ok, {204, #{}, undefined}};
{exception, Exception} ->
{error, Exception} ->
case Exception of
#payproc_ShopNotFound{} ->
{ok, general_error(404, <<"Shop not found">>)};
@ -64,7 +62,7 @@ prepare(OperationID = 'GetShops', Req, Context) ->
{ok, capi_auth:authorize_operation(Prototypes, Context, Req)}
end,
Process = fun() ->
Party = capi_utils:unwrap(capi_handler_utils:get_party(Context)),
Party = capi_utils:unwrap(capi_party:get_party(PartyID, Context)),
{ok, {200, #{}, decode_shops_map(Party#domain_Party.shops)}}
end,
{ok, #{authorize => Authorize, process => Process}};
@ -76,11 +74,10 @@ prepare(OperationID = 'GetShopByID', Req, Context) ->
{ok, capi_auth:authorize_operation(Prototypes, Context, Req)}
end,
Process = fun() ->
Call = {party_management, 'GetShop', {PartyID, ShopID}},
case capi_handler_utils:service_call_with([user_info], Call, Context) of
case capi_party:get_shop(PartyID, ShopID, Context) of
{ok, Shop} ->
{ok, {200, #{}, decode_shop(Shop)}};
{exception, #payproc_ShopNotFound{}} ->
{error, #payproc_ShopNotFound{}} ->
{ok, general_error(404, <<"Shop not found">>)}
end
end,
@ -96,12 +93,12 @@ prepare(OperationID = 'GetShopsForParty', Req, Context) ->
% Here we're relying on hellgate ownership check, thus no explicit authorization.
% Hovewer we're going to drop hellgate authz eventually, then we'll need to make sure that operation
% remains authorized.
case capi_handler_utils:get_party(PartyID, Context) of
case capi_party:get_party(PartyID, Context) of
{ok, Party} ->
{ok, {200, #{}, decode_shops_map(Party#domain_Party.shops)}};
{exception, #payproc_InvalidUser{}} ->
{error, #payproc_InvalidUser{}} ->
{ok, general_error(404, <<"Party not found">>)};
{exception, #payproc_PartyNotFound{}} ->
{error, #payproc_PartyNotFound{}} ->
{ok, general_error(404, <<"Party not found">>)}
end
end,
@ -114,19 +111,18 @@ prepare(OperationID = 'GetShopByIDForParty', Req, Context) ->
{ok, capi_auth:authorize_operation(Prototypes, Context, Req)}
end,
Process = fun() ->
Call = {party_management, 'GetShop', {PartyID, ShopID}},
% TODO
% Here we're relying on hellgate ownership check, thus no explicit authorization.
% Hovewer we're going to drop hellgate authz eventually, then we'll need to make sure that operation
% remains authorized.
case capi_handler_utils:service_call_with([user_info], Call, Context) of
case capi_party:get_shop(PartyID, ShopID, Context) of
{ok, Shop} ->
{ok, {200, #{}, decode_shop(Shop)}};
{exception, #payproc_InvalidUser{}} ->
{error, #payproc_InvalidUser{}} ->
{ok, general_error(404, <<"Party not found">>)};
{exception, #payproc_PartyNotFound{}} ->
{error, #payproc_PartyNotFound{}} ->
{ok, general_error(404, <<"Party not found">>)};
{exception, #payproc_ShopNotFound{}} ->
{error, #payproc_ShopNotFound{}} ->
{ok, general_error(404, <<"Shop not found">>)}
end
end,
@ -139,15 +135,14 @@ prepare(OperationID = 'ActivateShopForParty', Req, Context) ->
{ok, capi_auth:authorize_operation(Prototypes, Context, Req)}
end,
Process = fun() ->
Call = {party_management, 'ActivateShop', {PartyID, ShopID}},
% TODO
% Here we're relying on hellgate ownership check, thus no explicit authorization.
% Hovewer we're going to drop hellgate authz eventually, then we'll need to make sure that operation
% remains authorized.
case capi_handler_utils:service_call_with([user_info], Call, Context) of
{ok, _R} ->
case capi_party:activate_shop(PartyID, ShopID, Context) of
ok ->
{ok, {204, #{}, undefined}};
{exception, Exception} ->
{error, Exception} ->
case Exception of
#payproc_InvalidUser{} ->
{ok, general_error(404, <<"Party not found">>)};
@ -169,15 +164,10 @@ prepare(OperationID = 'SuspendShopForParty', Req, Context) ->
{ok, capi_auth:authorize_operation(Prototypes, Context, Req)}
end,
Process = fun() ->
Call = {party_management, 'SuspendShop', {PartyID, ShopID}},
% TODO
% Here we're relying on hellgate ownership check, thus no explicit authorization.
% Hovewer we're going to drop hellgate authz eventually, then we'll need to make sure that operation
% remains authorized.
case capi_handler_utils:service_call_with([user_info], Call, Context) of
{ok, _R} ->
case capi_party:suspend_shop(PartyID, ShopID, Context) of
ok ->
{ok, {204, #{}, undefined}};
{exception, Exception} ->
{error, Exception} ->
case Exception of
#payproc_InvalidUser{} ->
{ok, general_error(404, <<"Party not found">>)};

View File

@ -13,10 +13,8 @@
-export([service_call_with/3]).
-export([service_call/2]).
-export([get_party/1]).
-export([get_party/2]).
-export([get_auth_context/1]).
-export([get_user_info/1]).
-export([get_user_id/1]).
-export([get_party_id/1]).
-export([get_extra_properties/1]).
@ -34,8 +32,6 @@
-export([get_invoice_by_id/2]).
-export([get_payment_by_id/3]).
-export([get_refund_by_id/4]).
-export([get_contract_by_id/2]).
-export([get_contract_by_id/3]).
-export([create_dsl/3]).
@ -107,6 +103,7 @@ service_call({ServiceName, Function, Args}, #{woody_context := WoodyContext}) ->
get_auth_context(#{swagger_context := #{auth_context := AuthContext}}) ->
AuthContext.
-spec get_user_info(processing_context()) -> dmsl_payment_processing_thrift:'UserInfo'().
get_user_info(Context) ->
#payproc_UserInfo{
id = get_user_id(Context),
@ -126,18 +123,6 @@ get_extra_properties(Context) ->
Claims = capi_auth:get_legacy_claims(get_auth_context(Context)),
maps:with(capi_auth_legacy:get_extra_properties(), Claims).
%% Common functions
-spec get_party(processing_context()) -> woody:result().
get_party(Context) ->
Call = {party_management, 'Get', {}},
service_call_with([user_info, party_id], Call, Context).
-spec get_party(binary(), processing_context()) -> woody:result().
get_party(PartyID, Context) ->
Call = {party_management, 'Get', {PartyID}},
service_call_with([user_info], Call, Context).
%% Utils
-spec append_to_tuple(any(), tuple()) -> tuple().
@ -275,16 +260,6 @@ get_payment_by_id(InvoiceID, PaymentID, Context) ->
get_refund_by_id(InvoiceID, PaymentID, RefundID, Context) ->
service_call_with([user_info], {invoicing, 'GetPaymentRefund', {InvoiceID, PaymentID, RefundID}}, Context).
-spec get_contract_by_id(binary(), processing_context()) -> woody:result().
get_contract_by_id(ContractID, Context) ->
Call = {party_management, 'GetContract', {ContractID}},
service_call_with([user_info, party_id], Call, Context).
-spec get_contract_by_id(binary(), binary(), processing_context()) -> woody:result().
get_contract_by_id(PartyID, ContractID, Context) ->
Call = {party_management, 'GetContract', {PartyID, ContractID}},
service_call_with([user_info], Call, Context).
-spec create_dsl(atom(), map(), map()) -> map().
create_dsl(QueryType, QueryBody, QueryParams) ->
merge_and_compact(

View File

@ -26,8 +26,7 @@ prepare('CreateWebhook' = OperationID, Req, Context) ->
Process = fun() ->
WebhookParams = encode_webhook_params(PartyID, Params),
ShopID = validate_webhook_params(WebhookParams),
Call = {party_management, 'GetShop', {PartyID, ShopID}},
case capi_handler_utils:service_call_with([user_info], Call, Context) of
case capi_party:get_shop(PartyID, ShopID, Context) of
{ok, _} ->
case capi_handler_utils:service_call({webhook_manager, 'Create', {WebhookParams}}, Context) of
{ok, Webhook} ->
@ -35,9 +34,9 @@ prepare('CreateWebhook' = OperationID, Req, Context) ->
{exception, #webhooker_LimitExceeded{}} ->
{ok, general_error(429, <<"Webhook limit exceeded">>)}
end;
{exception, #payproc_InvalidUser{}} ->
{error, #payproc_InvalidUser{}} ->
{ok, logic_error(invalidPartyID, <<"Party not found">>)};
{exception, #payproc_ShopNotFound{}} ->
{error, #payproc_ShopNotFound{}} ->
{ok, logic_error(invalidShopID, <<"Shop not found">>)}
end
end,
@ -269,11 +268,11 @@ decode_invoice_event_type({status_changed, #webhooker_InvoiceStatusChanged{value
% TODO seems unmaintainable
[
decode_invoice_status_event_type(V)
|| V <- [
?invpaid(),
?invcancelled(),
?invfulfilled()
]
|| V <- [
?invpaid(),
?invcancelled(),
?invfulfilled()
]
];
decode_invoice_event_type({status_changed, #webhooker_InvoiceStatusChanged{value = Value}}) ->
[decode_invoice_status_event_type(Value)];
@ -283,13 +282,13 @@ decode_invoice_event_type({payment, {status_changed, #webhooker_InvoicePaymentSt
% TODO seems unmaintainable
[
decode_payment_status_event_type(V)
|| V <- [
?pmtprocessed(),
?pmtcaptured(),
?pmtcancelled(),
?pmtrefunded(),
?pmtfailed()
]
|| V <- [
?pmtprocessed(),
?pmtcaptured(),
?pmtcancelled(),
?pmtrefunded(),
?pmtfailed()
]
];
decode_invoice_event_type({payment, {status_changed, #webhooker_InvoicePaymentStatusChanged{value = Value}}}) ->
[decode_payment_status_event_type(Value)];

View File

@ -0,0 +1,133 @@
-module(capi_party).
-export([create_party/3]).
-export([get_party/2]).
-export([checkout_party/3]).
-export([activate_party/2]).
-export([suspend_party/2]).
-export([get_contract/3]).
-export([get_shop/3]).
-export([activate_shop/3]).
-export([suspend_shop/3]).
-export([compute_payment_institution_terms/3]).
-export([create_claim/3]).
-export([revoke_claim/5]).
-export([get_claim/3]).
-export([get_claims/2]).
-export([get_account_state/3]).
-type result() :: ok | {ok, woody:result()} | {error, woody_error:business_error()}.
-type processing_context() :: capi_handler:processing_context().
-type party_id() :: party_client_thrift:party_id().
-type party_params() :: party_client_thrift:party_params().
-type party_revision_param() :: party_client_thrift:party_revision_param().
-type payment_institution_ref() :: party_client_thrift:payment_institution_ref().
-type varset() :: party_client_thrift:varset().
-type contract_id() :: party_client_thrift:contract_id().
-type shop_id() :: party_client_thrift:shop_id().
-type claim_id() :: party_client_thrift:claim_id().
-type claim_revision() :: party_client_thrift:claim_revision().
-type changeset() :: party_client_thrift:changeset().
-type revoke_reason() :: party_client_thrift:revoke_reason().
-type account_id() :: party_client_thrift:account_id().
-spec create_party(party_id(), party_params(), processing_context()) -> result().
create_party(PartyID, PartyParams, Context) ->
{Client, ClientContext} = client_context(Context),
party_client_thrift:create(PartyID, PartyParams, Client, ClientContext).
-spec get_party(party_id(), processing_context()) -> result().
get_party(PartyID, Context) ->
{Client, ClientContext} = client_context(Context),
party_client_thrift:get(PartyID, Client, ClientContext).
-spec checkout_party(party_id(), party_revision_param(), processing_context()) -> result().
checkout_party(PartyID, PartyRevision, Context) ->
{Client, ClientContext} = client_context(Context),
party_client_thrift:checkout(PartyID, PartyRevision, Client, ClientContext).
-spec activate_party(party_id(), processing_context()) -> result().
activate_party(PartyID, Context) ->
{Client, ClientContext} = client_context(Context),
party_client_thrift:activate(PartyID, Client, ClientContext).
-spec suspend_party(party_id(), processing_context()) -> result().
suspend_party(PartyID, Context) ->
{Client, ClientContext} = client_context(Context),
party_client_thrift:suspend(PartyID, Client, ClientContext).
-spec get_contract(party_id(), contract_id(), processing_context()) -> result().
get_contract(PartyID, ContractID, Context) ->
{Client, ClientContext} = client_context(Context),
party_client_thrift:get_contract(PartyID, ContractID, Client, ClientContext).
-spec get_shop(party_id(), shop_id(), processing_context()) -> result().
get_shop(PartyID, ShopID, Context) ->
{Client, ClientContext} = client_context(Context),
party_client_thrift:get_shop(PartyID, ShopID, Client, ClientContext).
-spec activate_shop(party_id(), shop_id(), processing_context()) -> result().
activate_shop(PartyID, ShopID, Context) ->
{Client, ClientContext} = client_context(Context),
party_client_thrift:activate_shop(PartyID, ShopID, Client, ClientContext).
-spec suspend_shop(party_id(), shop_id(), processing_context()) -> result().
suspend_shop(PartyID, ShopID, Context) ->
{Client, ClientContext} = client_context(Context),
party_client_thrift:suspend_shop(PartyID, ShopID, Client, ClientContext).
-spec compute_payment_institution_terms(
payment_institution_ref(),
varset(),
processing_context()
) -> result().
compute_payment_institution_terms(Ref, Varset, Context) ->
{Client, ClientContext} = client_context(Context),
party_client_thrift:compute_payment_institution_terms(
Ref,
Varset,
Client,
ClientContext
).
-spec create_claim(party_id(), changeset(), processing_context()) -> result().
create_claim(PartyID, Changeset, Context) ->
{Client, ClientContext} = client_context(Context),
party_client_thrift:create_claim(PartyID, Changeset, Client, ClientContext).
-spec revoke_claim(
party_id(),
claim_id(),
claim_revision(),
revoke_reason(),
processing_context()
) -> result().
revoke_claim(PartyID, ClaimID, Revision, Reason, Context) ->
{Client, ClientContext} = client_context(Context),
party_client_thrift:revoke_claim(
PartyID,
ClaimID,
Revision,
Reason,
Client,
ClientContext
).
-spec get_claim(party_id(), claim_id(), processing_context()) -> result().
get_claim(PartyID, ClaimID, Context) ->
{Client, ClientContext} = client_context(Context),
party_client_thrift:get_claim(PartyID, ClaimID, Client, ClientContext).
-spec get_claims(party_id(), processing_context()) -> result().
get_claims(PartyID, Context) ->
{Client, ClientContext} = client_context(Context),
party_client_thrift:get_claims(PartyID, Client, ClientContext).
-spec get_account_state(party_id(), account_id(), processing_context()) -> result().
get_account_state(PartyID, AccountID, Context) ->
{Client, ClientContext} = client_context(Context),
party_client_thrift:get_account_state(PartyID, AccountID, Client, ClientContext).
client_context(#{party_client := Client, party_client_context := ClientContext}) ->
{Client, ClientContext}.

View File

@ -23,26 +23,30 @@ start_link() ->
-spec init([]) -> {ok, {supervisor:sup_flags(), [supervisor:child_spec()]}}.
init([]) ->
UacConf = get_uac_config(),
ok = uac:configure(UacConf),
LechiffreOpts = genlib_app:env(capi, lechiffre_opts),
LechiffreSpec = lechiffre:child_spec(lechiffre, LechiffreOpts),
{LogicHandler, LogicHandlerSpecs} = get_logic_handler_info(),
HealthCheck = enable_health_logging(genlib_app:env(?APP, health_check, #{})),
BlacklistSpec = capi_api_key_blacklist:child_spec(),
PartyClient = party_client:create_client(),
PartyClientSpec = party_client:child_spec(party_client, PartyClient),
{LogicHandler, []} = get_logic_handler_info(#{party_client => PartyClient}),
AdditionalRoutes = [{'_', [erl_health_handle:get_route(HealthCheck), get_prometheus_route()]}],
SwaggerHandlerOpts = genlib_app:env(?APP, swagger_handler_opts, #{}),
SwaggerSpec = capi_swagger_server:child_spec({AdditionalRoutes, LogicHandler, SwaggerHandlerOpts}),
BlacklistSpecs = capi_api_key_blacklist:child_spec(),
UacConf = get_uac_config(),
ok = uac:configure(UacConf),
{ok, {
{one_for_all, 0, 1},
[LechiffreSpec] ++ LogicHandlerSpecs ++ [SwaggerSpec] ++ [BlacklistSpecs]
}}.
{ok,
{
{one_for_all, 0, 1},
[LechiffreSpec, SwaggerSpec, BlacklistSpec, PartyClientSpec]
}}.
-spec get_logic_handler_info() -> {Handler :: atom(), [Spec :: supervisor:child_spec()] | []}.
get_logic_handler_info() ->
-spec get_logic_handler_info(capi_handler:handler_opts()) ->
{Handler :: swag_server:logic_handler(_), [Spec :: supervisor:child_spec()] | []}.
get_logic_handler_info(HandlerOpts) ->
case genlib_app:env(?APP, service_type) of
real ->
{capi_handler, []};
{{capi_handler, HandlerOpts}, []};
undefined ->
exit(undefined_service_type)
end.

View File

@ -10,7 +10,11 @@
-define(START_TIME_TAG, processing_start_time).
-type params() :: {cowboy_router:routes(), module(), swag_server_router:swagger_handler_opts()}.
-type params() :: {
cowboy_router:routes(),
swag_server:logic_handler(_),
swag_server_router:swagger_handler_opts()
}.
-spec child_spec(params()) -> supervisor:child_spec().
child_spec({AdditionalRoutes, LogicHandler, SwaggerHandlerOpts}) ->

View File

@ -112,7 +112,15 @@ authorization_far_future_deadline_ok_test(_Config) ->
-spec authorization_permission_ok_test(config()) -> _.
authorization_permission_ok_test(Config) ->
_ = capi_ct_helper:mock_services([{party_management, fun('Get', _) -> {ok, ?PARTY} end}], Config),
_ = capi_ct_helper:mock_services(
[
{party_management, fun
('GetRevision', _) -> {ok, ?INTEGER};
('Checkout', _) -> {ok, ?PARTY}
end}
],
Config
),
{ok, Token} = capi_ct_helper:issue_token([{[party], read}], unlimited),
{ok, _} = capi_client_parties:get_my_party(capi_ct_helper:get_context(Token)).

View File

@ -1102,7 +1102,15 @@ get_account_by_id_ok_test(Config) ->
-spec get_my_party_ok_test(config()) -> _.
get_my_party_ok_test(Config) ->
_ = capi_ct_helper:mock_services([{party_management, fun('Get', _) -> {ok, ?PARTY} end}], Config),
_ = capi_ct_helper:mock_services(
[
{party_management, fun
('GetRevision', _) -> {ok, ?INTEGER};
('Checkout', _) -> {ok, ?PARTY}
end}
],
Config
),
_ = capi_ct_helper_bouncer:mock_assert_party_op_ctx(<<"GetMyParty">>, ?STRING, Config),
{ok, _} = capi_client_parties:get_my_party(?config(context, Config)).
@ -1120,7 +1128,15 @@ activate_my_party_ok_test(Config) ->
-spec get_party_by_id_ok_test(config()) -> _.
get_party_by_id_ok_test(Config) ->
_ = capi_ct_helper:mock_services([{party_management, fun('Get', _) -> {ok, ?PARTY} end}], Config),
_ = capi_ct_helper:mock_services(
[
{party_management, fun
('GetRevision', _) -> {ok, ?INTEGER};
('Checkout', _) -> {ok, ?PARTY}
end}
],
Config
),
_ = capi_ct_helper_bouncer:mock_assert_party_op_ctx(<<"GetPartyByID">>, ?STRING, Config),
{ok, _} = capi_client_parties:get_party_by_id(?config(context, Config), ?STRING).
@ -1175,7 +1191,15 @@ get_shop_by_id_for_party_error_test(Config) ->
-spec get_shops_ok_test(config()) -> _.
get_shops_ok_test(Config) ->
_ = capi_ct_helper:mock_services([{party_management, fun('Get', _) -> {ok, ?PARTY} end}], Config),
_ = capi_ct_helper:mock_services(
[
{party_management, fun
('GetRevision', _) -> {ok, ?INTEGER};
('Checkout', _) -> {ok, ?PARTY}
end}
],
Config
),
_ = capi_ct_helper_bouncer:mock_assert_party_op_ctx(<<"GetShops">>, ?STRING, Config),
{ok, _} = capi_client_shops:get_shops(?config(context, Config)).
@ -1183,7 +1207,10 @@ get_shops_ok_test(Config) ->
get_shops_for_party_ok_test(Config) ->
_ = capi_ct_helper:mock_services(
[
{party_management, fun('Get', _) -> {ok, ?PARTY} end}
{party_management, fun
('GetRevision', _) -> {ok, ?INTEGER};
('Checkout', _) -> {ok, ?PARTY}
end}
],
Config
),
@ -1193,9 +1220,10 @@ get_shops_for_party_ok_test(Config) ->
-spec get_shops_for_party_error_test(config()) -> _.
get_shops_for_party_error_test(Config) ->
_ = capi_ct_helper:mock_services(
[{party_management, fun('Get', {_, <<"WrongPartyID">>}) -> {throwing, #payproc_InvalidUser{}} end}],
[{party_management, fun('GetRevision', {_, <<"WrongPartyID">>}) -> {throwing, #payproc_InvalidUser{}} end}],
Config
),
_ = capi_ct_helper_bouncer:mock_assert_party_op_ctx(<<"GetShopsForParty">>, <<"WrongPartyID">>, Config),
?assertMatch(
{error, {404, _}},
@ -1487,7 +1515,17 @@ create_claim_invalid_residence_test(Config) ->
-spec get_contract_by_id_ok_test(config()) -> _.
get_contract_by_id_ok_test(Config) ->
_ = capi_ct_helper:mock_services([{party_management, fun('Get', _) -> {ok, ?PARTY} end}], Config),
_ = capi_ct_helper:mock_services(
[
{party_management, fun
('GetRevision', _) -> {ok, ?INTEGER};
('Checkout', _) -> {ok, ?PARTY};
('GetContract', _) -> {ok, ?CONTRACT}
end}
],
Config
),
_ = capi_ct_helper_bouncer:mock_arbiter(
?assertContextMatches(
#bctx_v1_ContextFragment{
@ -1501,7 +1539,17 @@ get_contract_by_id_ok_test(Config) ->
-spec get_contract_by_id_for_party_ok_test(config()) -> _.
get_contract_by_id_for_party_ok_test(Config) ->
_ = capi_ct_helper:mock_services([{party_management, fun('Get', _) -> {ok, ?PARTY} end}], Config),
_ = capi_ct_helper:mock_services(
[
{party_management, fun
('GetRevision', _) -> {ok, ?INTEGER};
('Checkout', _) -> {ok, ?PARTY};
('GetContract', _) -> {ok, ?CONTRACT}
end}
],
Config
),
_ = capi_ct_helper_bouncer:mock_assert_contract_op_ctx(
<<"GetContractByIDForParty">>,
?STRING,
@ -1512,13 +1560,30 @@ get_contract_by_id_for_party_ok_test(Config) ->
-spec get_contracts_ok_test(config()) -> _.
get_contracts_ok_test(Config) ->
_ = capi_ct_helper:mock_services([{party_management, fun('Get', _) -> {ok, ?PARTY} end}], Config),
_ = capi_ct_helper:mock_services(
[
{party_management, fun
('GetRevision', _) -> {ok, ?INTEGER};
('Checkout', _) -> {ok, ?PARTY}
end}
],
Config
),
_ = capi_ct_helper_bouncer:mock_assert_party_op_ctx(<<"GetContracts">>, ?STRING, Config),
{ok, [_First, _Second]} = capi_client_contracts:get_contracts(?config(context, Config)).
-spec get_contracts_for_party_ok_test(config()) -> _.
get_contracts_for_party_ok_test(Config) ->
_ = capi_ct_helper:mock_services([{party_management, fun('Get', _) -> {ok, ?PARTY} end}], Config),
_ = capi_ct_helper:mock_services(
[
{party_management, fun
('GetRevision', _) -> {ok, ?INTEGER};
('Checkout', _) -> {ok, ?PARTY}
end}
],
Config
),
_ = capi_ct_helper_bouncer:mock_assert_party_op_ctx(<<"GetContractsForParty">>, ?STRING, Config),
{ok, [_First, _Second]} = capi_client_contracts:get_contracts_for_party(?config(context, Config), ?STRING).
@ -1527,8 +1592,9 @@ get_contract_adjustments_ok_test(Config) ->
_ = capi_ct_helper:mock_services(
[
{party_management, fun
('GetContract', _) -> {ok, ?CONTRACT};
('Get', _) -> {ok, ?PARTY}
('GetRevision', _) -> {ok, ?INTEGER};
('Checkout', _) -> {ok, ?PARTY};
('GetContract', _) -> {ok, ?CONTRACT}
end}
],
Config
@ -1557,8 +1623,9 @@ get_contract_adjustment_by_id_ok_test(Config) ->
_ = capi_ct_helper:mock_services(
[
{party_management, fun
('GetContract', _) -> {ok, ?CONTRACT};
('Get', _) -> {ok, ?PARTY}
('GetRevision', _) -> {ok, ?INTEGER};
('Checkout', _) -> {ok, ?PARTY};
('GetContract', _) -> {ok, ?CONTRACT}
end}
],
Config

View File

@ -40,8 +40,7 @@ init_suite(Module, Config) ->
-spec init_suite(module(), config(), any()) -> config().
init_suite(Module, Config, CapiEnv) ->
SupPid = start_mocked_service_sup(Module),
Apps1 =
start_app(woody),
WoodyApp = start_app(woody),
ServiceURLs = mock_services_(
[
{
@ -52,11 +51,15 @@ init_suite(Module, Config, CapiEnv) ->
],
SupPid
),
Apps2 =
start_app(dmt_client, [{max_cache_size, #{}}, {service_urls, ServiceURLs}, {cache_update_interval, 50000}]) ++
start_capi(Config, CapiEnv) ++
capi_ct_helper_bouncer:mock_client(SupPid),
[{apps, lists:reverse(Apps1 ++ Apps2)}, {suite_test_sup, SupPid} | Config].
DmtApp = start_app(dmt_client, [
{max_cache_size, #{}},
{service_urls, ServiceURLs},
{cache_update_interval, 50000}
]),
CapiApp = start_capi(Config, CapiEnv),
BouncerApp = capi_ct_helper_bouncer:mock_client(SupPid),
Apps = lists:reverse([WoodyApp, DmtApp, CapiApp, BouncerApp]),
[{apps, Apps}, {suite_test_sup, SupPid} | Config].
-spec start_app(app_name()) -> [app_name()].
start_app(woody = AppName) ->
@ -184,15 +187,27 @@ stop_mocked_service_sup(SupPid) ->
-spec mock_services(_, _) -> _.
mock_services(Services, SupOrConfig) ->
{BenderClientServices, WoodyServices} = lists:partition(
fun({ServiceName, _}) ->
ServiceName == generator
{PartyClientServices, Other} = lists:partition(
fun
({party_management, _}) -> true;
(_) -> false
end,
Services
),
{BenderClientServices, WoodyServices} = lists:partition(
fun
({generator, _}) -> true;
(_) -> false
end,
Other
),
_ = start_party_client(mock_services_(PartyClientServices, SupOrConfig)),
_ = start_bender_client(mock_services_(BenderClientServices, SupOrConfig)),
start_woody_client(mock_services_(WoodyServices, SupOrConfig)).
start_party_client(Services) ->
start_app(party_client, [{services, Services}]).
start_bender_client(Services) ->
start_app(bender_client, [{services, Services}]).
@ -201,6 +216,8 @@ start_woody_client(Services) ->
-spec mock_services_(_, _) -> _.
% TODO need a better name
mock_services_([], _Config) ->
#{};
mock_services_(Services, Config) when is_list(Config) ->
mock_services_(Services, ?config(test_sup, Config));
mock_services_(Services, SupPid) when is_pid(SupPid) ->
@ -234,6 +251,8 @@ get_service_name({ServiceName, _WoodyService, _Fun}) ->
mock_service_handler({generator, Fun}) ->
mock_service_handler('Generator', {bender_thrift, 'Generator'}, Fun);
mock_service_handler({party_management, Fun}) ->
mock_service_handler(party_management, {dmsl_payment_processing_thrift, 'PartyManagement'}, Fun);
mock_service_handler({ServiceName, Fun}) ->
mock_service_handler(ServiceName, capi_woody_client:get_service_modname(ServiceName), Fun);
mock_service_handler({ServiceName, WoodyService, Fun}) ->

View File

@ -3,6 +3,7 @@
-include_lib("common_test/include/ct.hrl").
-include_lib("damsel/include/dmsl_domain_thrift.hrl").
-include_lib("damsel/include/dmsl_payment_processing_thrift.hrl").
-include_lib("capi_dummy_data.hrl").
-export([all/0]).
@ -118,16 +119,16 @@ deadline_absolute_ok_test(Config) ->
Context = ?config(context_with_absolute_deadline, Config),
_ = capi_ct_helper:mock_services(
[
{party_management, fun('Get', _) ->
timer:sleep(5000),
{ok, ?PARTY}
{invoicing, fun('Get', _) ->
timer:sleep(10000),
{ok, ?PAYPROC_INVOICE}
end}
],
Config
),
Deadline = woody_deadline:from_timeout(3000),
BinDeadline = woody_deadline:to_binary(Deadline),
?badresp(504) = capi_client_parties:get_my_party(Context#{deadline => BinDeadline}),
?badresp(504) = capi_client_invoices:get_invoice_by_id(Context#{deadline => BinDeadline}, ?STRING),
Deadline2 = woody_deadline:from_timeout(3000),
BinDeadline2 = woody_deadline:to_binary(Deadline2),
{ok, _} = capi_client_categories:get_categories(Context#{deadline => BinDeadline2}).
@ -137,14 +138,14 @@ deadline_relative_ok_test(Config) ->
Context = ?config(context_with_relative_deadline, Config),
_ = capi_ct_helper:mock_services(
[
{party_management, fun('Get', _) ->
{invoicing, fun('Get', _) ->
timer:sleep(10000),
{ok, ?PARTY}
{ok, ?PAYPROC_INVOICE}
end}
],
Config
),
?badresp(504) = capi_client_parties:get_my_party(Context),
?badresp(504) = capi_client_invoices:get_invoice_by_id(Context, ?STRING),
{ok, _} = capi_client_categories:get_categories(Context).
get_context(Token, Deadline) ->

View File

@ -143,10 +143,12 @@ init_per_group(payment_creation, Config) ->
SupPid = capi_ct_helper:start_mocked_service_sup(?MODULE),
Apps1 = capi_ct_helper_tk:mock_service(capi_ct_helper_tk:user_session_handler(), SupPid),
Apps2 = capi_ct_helper_bouncer:mock_arbiter(capi_ct_helper_bouncer:judge_always_allowed(), SupPid),
{{ok, #{
{
{ok, #{
<<"invoiceAccessToken">> := #{<<"payload">> := InvAccToken}
}},
_} =
_
} =
with_feature_storage(fun() ->
capi_client_invoices:create_invoice(capi_ct_helper:get_context(Token, ExtraProperties), Req)
end),
@ -854,7 +856,7 @@ create_customers(BenderKey, Requests, Config) ->
),
[
with_feature_storage(fun() -> capi_client_customers:create_customer(Context, R) end)
|| R <- Requests
|| R <- Requests
]
end
).
@ -886,7 +888,7 @@ create_customer_bindings(BenderKey, Requests, Config) ->
),
[
with_feature_storage(fun() -> capi_client_customers:create_binding(Context, ?STRING, R) end)
|| R <- Requests
|| R <- Requests
]
end
).
@ -911,7 +913,7 @@ create_invoice_templates(BenderKey, Requests, Config) ->
),
[
with_feature_storage(fun() -> capi_client_invoice_templates:create(Context, R) end)
|| R <- Requests
|| R <- Requests
]
end
).
@ -941,7 +943,7 @@ create_invoices_with_templates(BenderKey, Requests, Config) ->
with_feature_storage(fun() ->
capi_client_invoice_templates:create_invoice(Context, InvoiceTemplateID, Request)
end)
|| {InvoiceTemplateID, Request} <- Requests
|| {InvoiceTemplateID, Request} <- Requests
]
end
).

View File

@ -234,7 +234,10 @@ get_invoice_payment_methods_ok_test(Config) ->
('ComputeTerms', _) -> {ok, ?TERM_SET};
('Get', _) -> {ok, ?PAYPROC_INVOICE}
end},
{party_management, fun('Get', _) -> {ok, ?PARTY} end}
{party_management, fun
('GetRevision', _) -> {ok, ?INTEGER};
('Checkout', _) -> {ok, ?PARTY}
end}
],
Config
),

View File

@ -176,7 +176,10 @@ get_invoice_payment_methods_by_tpl_id_ok_test(Config) ->
('ComputeTerms', _) -> {ok, ?TERM_SET};
('Get', _) -> {ok, ?INVOICE_TPL}
end},
{party_management, fun('Get', _) -> {ok, ?PARTY} end}
{party_management, fun
('GetRevision', _) -> {ok, ?INTEGER};
('Checkout', _) -> {ok, ?PARTY}
end}
],
Config
),

View File

@ -111,9 +111,10 @@ end_per_testcase(_Name, C) ->
-spec oops_body_test(config()) -> _.
oops_body_test(Config) ->
_ = capi_ct_helper:mock_services([{party_management, fun('Get', _) -> {ok, "spanish inquisition"} end}], Config),
_ = capi_ct_helper:mock_services([{invoicing, fun('Get', _) -> {ok, "spanish inquisition"} end}], Config),
Context = ?config(context, Config),
{Endpoint, PreparedParams, Opts0} = capi_client_lib:make_request(Context, #{}),
Params = #{binding => #{<<"invoiceID">> => ?STRING}},
{Endpoint, PreparedParams, Opts0} = capi_client_lib:make_request(Context, Params),
Url = swag_client_utils:get_url(Endpoint, "/v2/processing/me"),
Headers = maps:to_list(maps:get(header, PreparedParams)),
Body = <<"{}">>,

View File

@ -1,6 +1,8 @@
-module(capi_woody_tests_SUITE).
-include_lib("common_test/include/ct.hrl").
-include_lib("damsel/include/dmsl_domain_thrift.hrl").
-include_lib("capi_dummy_data.hrl").
-export([all/0]).
-export([groups/0]).
@ -102,38 +104,38 @@ end_per_testcase(_Name, C) ->
-spec woody_unexpected_test(config()) -> _.
woody_unexpected_test(Config) ->
_ = capi_ct_helper:mock_services([{party_management, fun('Get', _) -> {ok, "spanish inquisition"} end}], Config),
?badresp(500) = capi_client_parties:get_my_party(?config(context, Config)).
_ = capi_ct_helper:mock_services([{invoicing, fun('Get', _) -> {ok, "spanish inquisition"} end}], Config),
?badresp(500) = capi_client_invoices:get_invoice_by_id(?config(context, Config), ?STRING).
-spec woody_unavailable_test(config()) -> _.
woody_unavailable_test(Config) ->
_ = capi_ct_helper:start_app(capi_woody_client, [
{services, #{
party_management => #{url => <<"http://spanish.inquision/v1/partymgmt">>}
invoicing => #{url => <<"http://spanish.inquision/v1/partymgmt">>}
}}
]),
?badresp(503) = capi_client_parties:get_my_party(?config(context, Config)).
?badresp(503) = capi_client_invoices:get_invoice_by_id(?config(context, Config), ?STRING).
-spec woody_retry_test(config()) -> _.
woody_retry_test(Config) ->
_ = capi_ct_helper:start_app(capi_woody_client, [
{services, #{
party_management => #{url => <<"http://spanish.inquision/v1/partymgmt">>}
invoicing => #{url => <<"http://spanish.inquision/v1/partymgmt">>}
}},
{service_retries, #{
party_management => #{
invoicing => #{
'Get' => {linear, 30, 1000},
'_' => finish
}
}},
{service_deadlines, #{
party_management => 5000
invoicing => 5000
}}
]),
{Time, ?badresp(503)} = timer:tc(capi_client_parties, get_my_party, [?config(context, Config)]),
{Time, ?badresp(503)} = timer:tc(capi_client_invoices, get_invoice_by_id, [?config(context, Config), ?STRING]),
true = (Time > 3000000) and (Time < 10000000).
-spec woody_unknown_test(config()) -> _.
woody_unknown_test(Config) ->
_ = capi_ct_helper:mock_services([{party_management, fun('Get', _) -> timer:sleep(60000) end}], Config),
?badresp(504) = capi_client_parties:get_my_party(?config(context, Config)).
_ = capi_ct_helper:mock_services([{invoicing, fun('Get', _) -> timer:sleep(60000) end}], Config),
?badresp(504) = capi_client_invoices:get_invoice_by_id(?config(context, Config), ?STRING).

View File

@ -13,7 +13,10 @@
transport_opts => woody_client_thrift_http_transport:transport_options()
}.
-spec call_service(service_name(), woody:func(), tuple(), woody_context:ctx()) -> woody:result().
-spec call_service(service_name(), woody:func(), tuple(), woody_context:ctx()) ->
{ok, woody:result()}
| {exception, woody_error:business_error()}
| no_return().
call_service(ServiceName, Function, Args, Context0) ->
Deadline = get_service_deadline(ServiceName),
Context1 = set_deadline(Deadline, Context0),

@ -1 +1 @@
Subproject commit c67c2590c921274e0d03fbdb437c893bb035fba4
Subproject commit a7655bc60c877a65cdfe3d9b668021d970d88a76

View File

@ -122,6 +122,31 @@
}}
]},
{party_client, [
{services, #{
'party_management' => "http://hellgate:8022/v1/processing/partymgmt"
}},
{woody, #{
cache_mode => safe, % disabled | safe | aggressive
options => #{
woody_client => #{
event_handler => {scoper_woody_event_handler, #{
event_handler_opts => #{
formatter_opts => #{
max_length => 1000
}
}
}}
}
},
%retries => #{
% 'GetRevision' => finish,
% '_' => finish
%},
deadline_timeout => 60000
}}
]},
{bender_client, [
{services, #{
'Bender' => <<"http://bender:8022/v1/bender">>,

View File

@ -48,7 +48,8 @@
{prometheus_cowboy, "0.1.8"},
{bouncer_proto, {git, "https://github.com/rbkmoney/bouncer-proto.git", {branch, master}}},
{bouncer_client, {git, "https://github.com/rbkmoney/bouncer_client_erlang.git", {branch, master}}},
{token_keeper_client, {git, "git@github.com:rbkmoney/token-keeper-client.git", {branch, master}}}
{token_keeper_client, {git, "git@github.com:rbkmoney/token-keeper-client.git", {branch, master}}},
{party_client, {git, "https://github.com/rbkmoney/party_client_erlang.git", {branch, master}}}
]}.
%% XRef checks
@ -120,7 +121,7 @@
]}.
{plugins, [
{erlfmt, "0.10.0"}
{erlfmt, "0.15.1"}
]}.
{erlfmt, [

View File

@ -15,10 +15,10 @@
0},
{<<"bouncer_proto">>,
{git,"https://github.com/rbkmoney/bouncer-proto.git",
{ref,"584e0edf326ad77948f26b19d2e280b0da3e01a5"}},
{ref,"60cedce6c0147558e3ba322387151d23b001d68b"}},
0},
{<<"cache">>,{pkg,<<"cache">>,<<"2.3.3">>},1},
{<<"certifi">>,{pkg,<<"certifi">>,<<"2.5.3">>},1},
{<<"certifi">>,{pkg,<<"certifi">>,<<"2.6.1">>},1},
{<<"cg_mon">>,
{git,"https://github.com/rbkmoney/cg_mon.git",
{ref,"5a87a37694e42b6592d3b4164ae54e0e87e24e18"}},
@ -43,16 +43,16 @@
0},
{<<"dmt_client">>,
{git,"https://github.com/rbkmoney/dmt_client.git",
{ref,"9e11f50e9c4db32fe46d6f8a2429ca060a3acd57"}},
{ref,"37f376e239a2182cbb2a7a052797e99955edbaad"}},
0},
{<<"dmt_core">>,
{git,"https://github.com/rbkmoney/dmt_core.git",
{ref,"5a0ff399dee3fd606bb864dd0e27ddde539345e2"}},
1},
{<<"email_validator">>,{pkg,<<"email_validator">>,<<"1.0.0">>},0},
{<<"email_validator">>,{pkg,<<"email_validator">>,<<"1.1.0">>},0},
{<<"erl_health">>,
{git,"https://github.com/rbkmoney/erlang-health.git",
{ref,"982af88738ca062eea451436d830eef8c1fbe3f9"}},
{ref,"5958e2f35cd4d09f40685762b82b82f89b4d9333"}},
0},
{<<"folsom">>,
{git,"https://github.com/folsom-project/folsom.git",
@ -62,12 +62,12 @@
{git,"https://github.com/rbkmoney/genlib.git",
{ref,"3e1776536802739d8819351b15d54ec70568aba7"}},
0},
{<<"gproc">>,{pkg,<<"gproc">>,<<"0.8.0">>},1},
{<<"gproc">>,{pkg,<<"gproc">>,<<"0.9.0">>},1},
{<<"gun">>,
{git,"https://github.com/ninenines/gun.git",
{ref,"e7dd9f227e46979d8073e71c683395a809b78cb4"}},
1},
{<<"hackney">>,{pkg,<<"hackney">>,<<"1.17.0">>},0},
{<<"hackney">>,{pkg,<<"hackney">>,<<"1.17.4">>},0},
{<<"how_are_you">>,
{git,"https://github.com/rbkmoney/how_are_you.git",
{ref,"8f11d17eeb6eb74096da7363a9df272fd3099718"}},
@ -78,10 +78,10 @@
{ref,"9b980b7f9ce09b6a136fe5a23d404d1b903f3061"}},
0},
{<<"jose">>,{pkg,<<"jose">>,<<"1.11.1">>},0},
{<<"jsx">>,{pkg,<<"jsx">>,<<"3.0.0">>},0},
{<<"jsx">>,{pkg,<<"jsx">>,<<"3.1.0">>},0},
{<<"lechiffre">>,
{git,"https://github.com/rbkmoney/lechiffre.git",
{ref,"a9ea635b9db03ec58e7cb2f015f124aa9edf0c4b"}},
{ref,"7915b7650abc80535d8c183642c5a409c942edf0"}},
0},
{<<"metrics">>,{pkg,<<"metrics">>,<<"1.0.1">>},1},
{<<"mimerl">>,{pkg,<<"mimerl">>,<<"1.2.0">>},1},
@ -93,9 +93,10 @@
{git,"git@github.com:rbkmoney/org-management-proto.git",
{ref,"06c5c8430e445cb7874e54358e457cbb5697fc32"}},
1},
{<<"parse_trans">>,
{git,"https://github.com/uwiger/parse_trans.git",
{ref,"8ba366f81789c913cd63d69c6d1da948c200d18a"}},
{<<"parse_trans">>,{pkg,<<"parse_trans">>,<<"3.4.0">>},0},
{<<"party_client">>,
{git,"https://github.com/rbkmoney/party_client_erlang.git",
{ref,"a6471d4074f8098f8db0da57a2e676a22804d3ff"}},
0},
{<<"payproc_errors">>,
{git,"https://github.com/rbkmoney/payproc-errors-erlang.git",
@ -107,7 +108,7 @@
{<<"ranch">>,{pkg,<<"ranch">>,<<"1.7.1">>},1},
{<<"reporter_proto">>,
{git,"https://github.com/rbkmoney/reporter-proto.git",
{ref,"fa3631e940d544003ce4c25787d91d80cc9b386f"}},
{ref,"aafbfac4463711d43f8e8ed4da103967b95e1fb6"}},
0},
{<<"scoper">>,
{git,"https://github.com/rbkmoney/scoper.git",
@ -137,7 +138,7 @@
{<<"unicode_util_compat">>,{pkg,<<"unicode_util_compat">>,<<"0.7.0">>},1},
{<<"woody">>,
{git,"https://github.com/rbkmoney/woody_erlang.git",
{ref,"f2cd30883d58eb1c3ab2172556956f757bc27e23"}},
{ref,"d9fca6da55a46e39bdb7ad2c0dba0b7205a7e70b"}},
0},
{<<"woody_user_identity">>,
{git,"https://github.com/rbkmoney/woody_erlang_user_identity.git",
@ -148,17 +149,18 @@
{<<"accept">>, <<"B33B127ABCA7CC948BBE6CAA4C263369ABF1347CFA9D8E699C6D214660F10CD1">>},
{<<"bear">>, <<"16264309AE5D005D03718A5C82641FCC259C9E8F09ADEB6FD79CA4271168656F">>},
{<<"cache">>, <<"B23A5FE7095445A88412A6E614C933377E0137B44FFED77C9B3FEF1A731A20B2">>},
{<<"certifi">>, <<"70BDD7E7188C804F3A30EE0E7C99655BC35D8AC41C23E12325F36AB449B70651">>},
{<<"certifi">>, <<"DBAB8E5E155A0763EEA978C913CA280A6B544BFA115633FA20249C3D396D9493">>},
{<<"cowboy">>, <<"91ED100138A764355F43316B1D23D7FF6BDB0DE4EA618CB5D8677C93A7A2F115">>},
{<<"cowlib">>, <<"FD0FF1787DB84AC415B8211573E9A30A3EBE71B5CBFF7F720089972B2319C8A4">>},
{<<"email_validator">>, <<"3F942B6AF1A309165B9399C71D5251EF5933774CEBC59EEAF18A7D9C4A8FA092">>},
{<<"gproc">>, <<"CEA02C578589C61E5341FCE149EA36CCEF236CC2ECAC8691FBA408E7EA77EC2F">>},
{<<"hackney">>, <<"717EA195FD2F898D9FE9F1CE0AFCC2621A41ECFE137FAE57E7FE6E9484B9AA99">>},
{<<"email_validator">>, <<"7E09A862E9AA99AE2CA6FD2A718D2B94360E32940A1339B53DFEE6B774BCDB03">>},
{<<"gproc">>, <<"853CCB7805E9ADA25D227A157BA966F7B34508F386A3E7E21992B1B484230699">>},
{<<"hackney">>, <<"99DA4674592504D3FB0CFEF0DB84C3BA02B4508BAE2DFF8C0108BAA0D6E0977C">>},
{<<"idna">>, <<"8A63070E9F7D0C62EB9D9FCB360A7DE382448200FBBD1B106CC96D3D8099DF8D">>},
{<<"jose">>, <<"59DA64010C69AAD6CDE2F5B9248B896B84472E99BD18F246085B7B9FE435DCDB">>},
{<<"jsx">>, <<"20A170ABD4335FC6DB24D5FAD1E5D677C55DADF83D1B20A8A33B5FE159892A39">>},
{<<"jsx">>, <<"D12516BAA0BB23A59BB35DCCAF02A1BD08243FCBB9EFE24F2D9D056CCFF71268">>},
{<<"metrics">>, <<"25F094DEA2CDA98213CECC3AEFF09E940299D950904393B2A29D191C346A8486">>},
{<<"mimerl">>, <<"67E2D3F571088D5CFD3E550C383094B47159F3EEE8FFA08E64106CDF5E981BE3">>},
{<<"parse_trans">>, <<"BB87AC362A03CA674EBB7D9D498F45C03256ADED7214C9101F7035EF44B798C7">>},
{<<"prometheus">>, <<"20510F381DB1CCAB818B4CF2FAC5FA6AB5CC91BC364A154399901C001465F46F">>},
{<<"prometheus_cowboy">>, <<"CFCE0BC7B668C5096639084FCD873826E6220EA714BF60A716F5BD080EF2A99C">>},
{<<"prometheus_httpd">>, <<"F616ED9B85B536B195D94104063025A91F904A4CFC20255363F49A197D96C896">>},
@ -169,17 +171,18 @@
{<<"accept">>, <<"11B18C220BCC2EAB63B5470C038EF10EB6783BCB1FCDB11AA4137DEFA5AC1BB8">>},
{<<"bear">>, <<"534217DCE6A719D59E54FB0EB7A367900DBFC5F85757E8C1F94269DF383F6D9B">>},
{<<"cache">>, <<"44516CE6FA03594D3A2AF025DD3A87BFE711000EB730219E1DDEFC816E0AA2F4">>},
{<<"certifi">>, <<"ED516ACB3929B101208A9D700062D520F3953DA3B6B918D866106FFA980E1C10">>},
{<<"certifi">>, <<"524C97B4991B3849DD5C17A631223896272C6B0AF446778BA4675A1DFF53BB7E">>},
{<<"cowboy">>, <<"04FD8C6A39EDC6AAA9C26123009200FC61F92A3A94F3178C527B70B767C6E605">>},
{<<"cowlib">>, <<"79F954A7021B302186A950A32869DBC185523D99D3E44CE430CD1F3289F41ED4">>},
{<<"email_validator">>, <<"44CBDB6E9615FE3D558715E4E6D60610E934CD3FE4B8C650FEC5C560304526D6">>},
{<<"gproc">>, <<"580ADAFA56463B75263EF5A5DF4C86AF321F68694E7786CB057FD805D1E2A7DE">>},
{<<"hackney">>, <<"64C22225F1EA8855F584720C0E5B3CD14095703AF1C9FBC845BA042811DC671C">>},
{<<"email_validator">>, <<"2B1E6DF7BB14155C8D7D131F1C95CF4676200BC056EEBA82123396833FF94DA2">>},
{<<"gproc">>, <<"587E8AF698CCD3504CF4BA8D90F893EDE2B0F58CABB8A916E2BF9321DE3CF10B">>},
{<<"hackney">>, <<"DE16FF4996556C8548D512F4DBE22DD58A587BF3332E7FD362430A7EF3986B16">>},
{<<"idna">>, <<"92376EB7894412ED19AC475E4A86F7B413C1B9FBB5BD16DCCD57934157944CEA">>},
{<<"jose">>, <<"078F6C9FB3CD2F4CFAFC972C814261A7D1E8D2B3685C0A76EB87E158EFFF1AC5">>},
{<<"jsx">>, <<"37BECA0435F5CA8A2F45F76A46211E76418FBEF80C36F0361C249FC75059DC6D">>},
{<<"jsx">>, <<"0C5CC8FDC11B53CC25CF65AC6705AD39E54ECC56D1C22E4ADB8F5A53FB9427F3">>},
{<<"metrics">>, <<"69B09ADDDC4F74A40716AE54D140F93BEB0FB8978D8636EADED0C31B6F099F16">>},
{<<"mimerl">>, <<"F278585650AA581986264638EBF698F8BB19DF297F66AD91B18910DFC6E19323">>},
{<<"parse_trans">>, <<"F99E368830BEA44552224E37E04943A54874F08B8590485DE8D13832B63A2DC3">>},
{<<"prometheus">>, <<"4905FD2992F8038ECCD7AA0CD22F40637ED618C0BED1F75C05AACEC15B7545DE">>},
{<<"prometheus_cowboy">>, <<"BA286BECA9302618418892D37BCD5DC669A6CC001F4EB6D6AF85FF81F3F4F34C">>},
{<<"prometheus_httpd">>, <<"0BBE831452CFDF9588538EB2F570B26F30C348ADAE5E95A7D87F35A5910BCF92">>},