mirror of
https://github.com/valitydev/capi-v2.git
synced 2024-11-06 01:55:20 +00:00
Erlang OTP 21 to v2 (#342)
* CAPI-351: Erlang 21 to CAPI V2 (#339) * First step of migration * spec fix, changed headers to map * Bumped back swag commit * Bumped swag commit * reverted bump * Second migration step * Linter fixes * Bump build_image_tag * Update build utils * Gave up on using deprecated ranch child spec * Updated plt version * Bumped service-erlang * Actually use stream_handlers, bump woody * removed commeted funnctions * CAPI-353: OTP 21 logger (#341) * Initial lager migration * Added missing comma * Fix config typos and indentation, bumped formatter * Fixed oops body responce * Fixed wrong reply format, refactored oops body retrieval * Bumped hackney and thrift, fixed inet version * Renamed and fixed stream handler, fixed wrong handlers order * Test for oops_body * Use join to make file path * MSPF-476: Add operation_id to access log * Upgrade to Erlang 21.3.8.4 * Refactor access log configuration * lager -> logger * Upgrade woody * Fix default logger config
This commit is contained in:
parent
83543f1aec
commit
456b9a91e1
2
Jenkinsfile
vendored
2
Jenkinsfile
vendored
@ -33,7 +33,7 @@ build('capi', 'docker-host', finalHook) {
|
||||
sh 'make wc_xref'
|
||||
}
|
||||
runStage('dialyze') {
|
||||
withWsCache("_build/default/rebar3_19.3_plt") {
|
||||
withWsCache("_build/default/rebar3_21.3.8.4_plt") {
|
||||
sh 'make wc_dialyze'
|
||||
}
|
||||
}
|
||||
|
6
Makefile
6
Makefile
@ -16,10 +16,10 @@ SERVICE_IMAGE_TAG ?= $(shell git rev-parse HEAD)
|
||||
SERVICE_IMAGE_PUSH_TAG ?= $(SERVICE_IMAGE_TAG)
|
||||
|
||||
# Base image for the service
|
||||
BASE_IMAGE_NAME := service_erlang
|
||||
BASE_IMAGE_TAG := 16e2b3ef17e5fdefac8554ced9c2c74e5c6e9e11
|
||||
BASE_IMAGE_NAME := service-erlang
|
||||
BASE_IMAGE_TAG := 294d280ff42e6c0cc68ab40fe81e76a6262636c4
|
||||
|
||||
BUILD_IMAGE_TAG := 562313697353c29d4b34fb081a8b70e8c2207134
|
||||
BUILD_IMAGE_TAG := cd38c35976f3684fe7552533b6175a4c3460e88b
|
||||
|
||||
CALL_ANYWHERE := \
|
||||
submodules \
|
||||
|
@ -1,4 +1 @@
|
||||
{erl_opts, [
|
||||
{parse_transform, lager_transform},
|
||||
{lager_extra_sinks, [capi_access]}
|
||||
]}.
|
||||
|
||||
|
@ -7,8 +7,7 @@
|
||||
kernel,
|
||||
stdlib,
|
||||
public_key,
|
||||
lager,
|
||||
lager_logstash_formatter,
|
||||
logger_logstash_formatter,
|
||||
genlib,
|
||||
woody,
|
||||
capi_woody_client,
|
||||
|
@ -42,7 +42,7 @@ authorize_api_key(OperationID, ApiKey) ->
|
||||
end.
|
||||
|
||||
log_auth_error(OperationID, Error) ->
|
||||
lager:info("API Key authorization failed for ~p due to ~p", [OperationID, Error]).
|
||||
logger:info("API Key authorization failed for ~p due to ~p", [OperationID, Error]).
|
||||
|
||||
-spec parse_api_key(ApiKey :: swag_server:api_key()) ->
|
||||
{ok, {bearer, Credentials :: binary()}} | {error, Reason :: atom()}.
|
||||
|
@ -97,7 +97,7 @@ ensure_store_key(Keyname, Source) ->
|
||||
{ok, KeyInfo} ->
|
||||
KeyInfo;
|
||||
{error, Reason} ->
|
||||
_ = lager:error("Error importing key ~p: ~p", [Keyname, Reason]),
|
||||
_ = logger:error("Error importing key ~p: ~p", [Keyname, Reason]),
|
||||
exit({import_error, Keyname, Source, Reason})
|
||||
end.
|
||||
|
||||
@ -106,10 +106,10 @@ select_signee({ok, Keyname}, KeyInfos) ->
|
||||
{ok, #{sign := true}} ->
|
||||
set_signee(Keyname);
|
||||
{ok, KeyInfo} ->
|
||||
_ = lager:error("Error setting signee: signing with ~p is not allowed", [Keyname]),
|
||||
_ = logger:error("Error setting signee: signing with ~p is not allowed", [Keyname]),
|
||||
exit({invalid_signee, Keyname, KeyInfo});
|
||||
error ->
|
||||
_ = lager:error("Error setting signee: no key named ~p", [Keyname]),
|
||||
_ = logger:error("Error setting signee: no key named ~p", [Keyname]),
|
||||
exit({nonexstent_signee, Keyname})
|
||||
end;
|
||||
select_signee(error, _KeyInfos) ->
|
||||
|
@ -11,26 +11,25 @@
|
||||
policy_init(Req) ->
|
||||
{ok, Req, undefined_state}.
|
||||
|
||||
-spec allowed_origins(cowboy_req:req(), any()) -> {'*', cowboy_req:req(), any()}.
|
||||
-spec allowed_origins(cowboy_req:req(), any()) -> {'*', any()}.
|
||||
|
||||
allowed_origins(Req, State) ->
|
||||
{'*', Req, State}.
|
||||
allowed_origins(_, State) ->
|
||||
{'*', State}.
|
||||
|
||||
-spec allowed_headers(cowboy_req:req(), any()) -> {[binary()], cowboy_req:req(), any()}.
|
||||
-spec allowed_headers(cowboy_req:req(), any()) -> {[binary()], any()}.
|
||||
|
||||
allowed_headers(Req, State) ->
|
||||
allowed_headers(_, State) ->
|
||||
{[
|
||||
<<"access-control-allow-headers">>,
|
||||
<<"origin">>,
|
||||
<<"x-requested-with">>,
|
||||
<<"content-type">>,
|
||||
<<"accept">>,
|
||||
<<"authorization">>,
|
||||
<<"x-request-id">>,
|
||||
<<"x-request-deadline">>
|
||||
], Req, State}.
|
||||
], State}.
|
||||
|
||||
-spec allowed_methods(cowboy_req:req(), any()) -> {[binary()], cowboy_req:req(), any()}.
|
||||
-spec allowed_methods(cowboy_req:req(), any()) -> {[binary()], any()}.
|
||||
|
||||
allowed_methods(Req, State) ->
|
||||
{[<<"GET">>, <<"POST">>, <<"PUT">>, <<"DELETE">>, <<"OPTIONS">>], Req, State}.
|
||||
allowed_methods(_, State) ->
|
||||
{[<<"GET">>, <<"POST">>, <<"PUT">>, <<"DELETE">>, <<"OPTIONS">>], State}.
|
||||
|
@ -7,8 +7,8 @@
|
||||
-behaviour(swag_server_logic_handler).
|
||||
|
||||
%% API callbacks
|
||||
-export([authorize_api_key/2]).
|
||||
-export([handle_request/3]).
|
||||
-export([authorize_api_key/3]).
|
||||
-export([handle_request/4]).
|
||||
|
||||
%% Handler behaviour
|
||||
|
||||
@ -30,10 +30,10 @@
|
||||
%% @WARNING Must be refactored in case of different classes of users using this API
|
||||
-define(REALM, <<"external">>).
|
||||
|
||||
-spec authorize_api_key(swag_server:operation_id(), swag_server:api_key()) ->
|
||||
-spec authorize_api_key(swag_server:operation_id(), swag_server:api_key(), handler_opts()) ->
|
||||
Result :: false | {true, capi_auth:context()}.
|
||||
|
||||
authorize_api_key(OperationID, ApiKey) ->
|
||||
authorize_api_key(OperationID, ApiKey, _HandlerOpts) ->
|
||||
_ = capi_utils:logtag_process(operation_id, OperationID),
|
||||
capi_auth:authorize_api_key(OperationID, ApiKey).
|
||||
|
||||
@ -41,7 +41,8 @@ authorize_api_key(OperationID, ApiKey) ->
|
||||
|
||||
-type operation_id() :: swag_server:operation_id().
|
||||
-type request_context() :: swag_server:request_context().
|
||||
-type response() :: swag_server_logic_handler:response().
|
||||
-type response() :: swag_server:response().
|
||||
-type handler_opts() :: swag_server:handler_opts(_).
|
||||
-type processing_context() :: #{
|
||||
swagger_context := swag_server:request_context(),
|
||||
woody_context := woody_context:ctx()
|
||||
@ -72,12 +73,13 @@ get_handlers() ->
|
||||
-spec handle_request(
|
||||
OperationID :: operation_id(),
|
||||
Req :: request_data(),
|
||||
SwagContext :: request_context()
|
||||
SwagContext :: request_context(),
|
||||
HandlerOpts :: handler_opts()
|
||||
) ->
|
||||
{ok | error, response()}.
|
||||
|
||||
handle_request(OperationID, Req, SwagContext = #{auth_context := AuthContext}) ->
|
||||
_ = lager:info("Processing request ~p", [OperationID]),
|
||||
handle_request(OperationID, Req, SwagContext = #{auth_context := AuthContext}, _HandlerOpts) ->
|
||||
_ = logger:info("Processing request ~p", [OperationID]),
|
||||
try
|
||||
case capi_auth:authorize_operation(OperationID, Req, AuthContext) of
|
||||
ok ->
|
||||
@ -85,14 +87,14 @@ handle_request(OperationID, Req, SwagContext = #{auth_context := AuthContext}) -
|
||||
Context = create_processing_context(SwagContext, WoodyContext),
|
||||
process_request(OperationID, Req, Context, get_handlers());
|
||||
{error, _} = Error ->
|
||||
_ = lager:info("Operation ~p authorization failed due to ~p", [OperationID, Error]),
|
||||
{ok, {401, [], undefined}}
|
||||
_ = logger:info("Operation ~p authorization failed due to ~p", [OperationID, Error]),
|
||||
{ok, {401, #{}, undefined}}
|
||||
end
|
||||
catch
|
||||
error:{woody_error, {Source, Class, Details}} ->
|
||||
process_woody_error(Source, Class, Details);
|
||||
throw:{bad_deadline, Deadline} ->
|
||||
_ = lager:warning("Operation ~p failed due to invalid deadline ~p", [OperationID, Deadline]),
|
||||
_ = logger:warning("Operation ~p failed due to invalid deadline ~p", [OperationID, Deadline]),
|
||||
{ok, logic_error(invalidDeadline, <<"Invalid data in X-Request-Deadline header">>)}
|
||||
end.
|
||||
|
||||
@ -124,7 +126,7 @@ create_processing_context(SwaggerContext, WoodyContext) ->
|
||||
|
||||
create_woody_context(#{'X-Request-ID' := RequestID}, AuthContext) ->
|
||||
RpcID = #{trace_id := TraceID} = woody_context:new_rpc_id(genlib:to_binary(RequestID)),
|
||||
_ = lager:debug("Created TraceID:~p for RequestID:~p", [TraceID , RequestID]),
|
||||
_ = logger:debug("Created TraceID:~p for RequestID:~p", [TraceID , RequestID]),
|
||||
woody_user_identity:put(collect_user_identity(AuthContext), woody_context:new(RpcID)).
|
||||
|
||||
collect_user_identity(AuthContext) ->
|
||||
|
@ -17,7 +17,7 @@ process_request('GetAccountByID', Req, Context) ->
|
||||
Call = {party_management, 'GetAccountState', [genlib:to_int(maps:get('accountID', Req))]},
|
||||
case capi_handler_utils:service_call_with([user_info, party_id, party_creation], Call, Context) of
|
||||
{ok, S} ->
|
||||
{ok, {200, [], decode_account_state(S)}};
|
||||
{ok, {200, #{}, decode_account_state(S)}};
|
||||
{exception, #payproc_AccountNotFound{}} ->
|
||||
{ok, general_error(404, <<"Account not found">>)}
|
||||
end;
|
||||
|
@ -70,13 +70,13 @@ process_merchant_stat_result(customers_rate_stat = StatType, {ok, #merchstat_Sta
|
||||
[ ] -> #{<<"uniqueCount">> => 0};
|
||||
[StatResponse] -> decode_stat_info(StatType, StatResponse)
|
||||
end,
|
||||
{ok, {200, [], Resp}};
|
||||
{ok, {200, #{}, Resp}};
|
||||
|
||||
process_merchant_stat_result(StatType, Result) ->
|
||||
case Result of
|
||||
{ok, #merchstat_StatResponse{data = {'records', Stats}}} ->
|
||||
Resp = [decode_stat_info(StatType, S) || S <- Stats],
|
||||
{ok, {200, [], Resp}};
|
||||
{ok, {200, #{}, Resp}};
|
||||
{exception, #'InvalidRequest'{errors = Errors}} ->
|
||||
FormattedErrors = capi_handler_utils:format_request_errors(Errors),
|
||||
{ok, logic_error(invalidRequest, FormattedErrors)};
|
||||
|
@ -15,12 +15,12 @@
|
||||
|
||||
process_request('GetCategories', _Req, #{woody_context := WoodyContext}) ->
|
||||
Categories = capi_utils:unwrap(capi_domain:get_categories(WoodyContext)),
|
||||
{ok, {200, [], [decode_category(C) || C <- Categories]}};
|
||||
{ok, {200, #{}, [decode_category(C) || C <- Categories]}};
|
||||
|
||||
process_request('GetCategoryByRef', Req, Context) ->
|
||||
case get_category_by_id(genlib:to_int(maps:get(categoryID, Req)), Context) of
|
||||
{ok, Category} ->
|
||||
{ok, {200, [], decode_category(Category)}};
|
||||
{ok, {200, #{}, decode_category(Category)}};
|
||||
{error, not_found} ->
|
||||
{ok, general_error(404, <<"Category not found">>)}
|
||||
end;
|
||||
|
@ -18,7 +18,7 @@ process_request('GetClaims', Req, Context) ->
|
||||
Claims = capi_utils:unwrap(
|
||||
capi_handler_utils:service_call_with([user_info, party_id, party_creation], Call, Context)
|
||||
),
|
||||
{ok, {200, [], decode_claims(filter_claims(maps:get('claimStatus', Req), Claims))}};
|
||||
{ok, {200, #{}, decode_claims(filter_claims(maps:get('claimStatus', Req), Claims))}};
|
||||
|
||||
process_request('GetClaimByID', Req, Context) ->
|
||||
Call = {
|
||||
@ -33,7 +33,7 @@ process_request('GetClaimByID', Req, Context) ->
|
||||
%% filter this out
|
||||
{ok, general_error(404, <<"Claim not found">>)};
|
||||
false ->
|
||||
{ok, {200, [], decode_claim(Claim)}}
|
||||
{ok, {200, #{}, decode_claim(Claim)}}
|
||||
end;
|
||||
{exception, #payproc_ClaimNotFound{}} ->
|
||||
{ok, general_error(404, <<"Claim not found">>)}
|
||||
@ -45,7 +45,7 @@ process_request('CreateClaim', Req, Context) ->
|
||||
Call = {party_management, 'CreateClaim', [capi_handler_utils:get_party_id(Context), Changeset]},
|
||||
case capi_handler_utils:service_call_with([user_info, party_creation], Call, Context) of
|
||||
{ok, Claim} ->
|
||||
{ok, {201, [], decode_claim(Claim)}};
|
||||
{ok, {201, #{}, decode_claim(Claim)}};
|
||||
{exception, Exception} ->
|
||||
case Exception of
|
||||
#payproc_InvalidPartyStatus{} ->
|
||||
@ -81,7 +81,7 @@ process_request('CreateClaim', Req, Context) ->
|
||||
% Party = capi_utils:unwrap(
|
||||
% capi_handler_utils:service_call_with([user_info, party_id, party_creation], Call, Context)
|
||||
% ),
|
||||
% {ok, {200, [], capi_handler_utils:capi_handler_decoder_party:decode_party(Party)}};
|
||||
% {ok, {200, #{}, capi_handler_utils:capi_handler_decoder_party:decode_party(Party)}};
|
||||
|
||||
process_request('RevokeClaimByID', Req, Context) ->
|
||||
Call =
|
||||
@ -92,7 +92,7 @@ process_request('RevokeClaimByID', Req, Context) ->
|
||||
]},
|
||||
case capi_handler_utils:service_call_with([user_info, party_id, party_creation], Call, Context) of
|
||||
{ok, _} ->
|
||||
{ok, {204, [], undefined}};
|
||||
{ok, {204, #{}, undefined}};
|
||||
{exception, Exception} ->
|
||||
case Exception of
|
||||
#payproc_InvalidPartyStatus{} ->
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
process_request('GetContracts', _Req, Context) ->
|
||||
Party = capi_utils:unwrap(capi_handler_utils:get_my_party(Context)),
|
||||
{ok, {200, [], decode_contracts_map(Party#domain_Party.contracts, Party#domain_Party.contractors)}};
|
||||
{ok, {200, #{}, decode_contracts_map(Party#domain_Party.contracts, Party#domain_Party.contractors)}};
|
||||
|
||||
process_request('GetContractByID', Req, Context) ->
|
||||
ContractID = maps:get('contractID', Req),
|
||||
@ -25,14 +25,14 @@ process_request('GetContractByID', Req, Context) ->
|
||||
undefined ->
|
||||
{ok, general_error(404, <<"Contract not found">>)};
|
||||
Contract ->
|
||||
{ok, {200, [], decode_contract(Contract, Party#domain_Party.contractors)}}
|
||||
{ok, {200, #{}, decode_contract(Contract, Party#domain_Party.contractors)}}
|
||||
end;
|
||||
|
||||
process_request('GetContractAdjustments', Req, Context) ->
|
||||
case capi_handler_utils:get_contract_by_id(maps:get('contractID', Req), Context) of
|
||||
{ok, #domain_Contract{adjustments = Adjustments}} ->
|
||||
Resp = [decode_contract_adjustment(A) || A <- Adjustments],
|
||||
{ok, {200, [], Resp}};
|
||||
{ok, {200, #{}, Resp}};
|
||||
{exception, #payproc_ContractNotFound{}} ->
|
||||
{ok, general_error(404, <<"Contract not found">>)}
|
||||
end;
|
||||
@ -43,7 +43,7 @@ process_request('GetContractAdjustmentByID', Req, Context) ->
|
||||
AdjustmentID = maps:get('adjustmentID', Req),
|
||||
case lists:keyfind(AdjustmentID, #domain_ContractAdjustment.id, Adjustments) of
|
||||
#domain_ContractAdjustment{} = A ->
|
||||
{ok, {200, [], decode_contract_adjustment(A)}};
|
||||
{ok, {200, #{}, decode_contract_adjustment(A)}};
|
||||
false ->
|
||||
{ok, general_error(404, <<"Adjustment not found">>)}
|
||||
end;
|
||||
|
@ -18,7 +18,7 @@ process_request('CreateCustomer', Req, Context) ->
|
||||
Call = {customer_management, 'Create', [encode_customer_params(PartyID, maps:get('Customer', Req))]},
|
||||
case capi_handler_utils:service_call_with([party_creation], Call, Context) of
|
||||
{ok, Customer} ->
|
||||
{ok, {201, [], make_customer_and_token(Customer, PartyID)}};
|
||||
{ok, {201, #{}, make_customer_and_token(Customer, PartyID)}};
|
||||
{exception, Exception} ->
|
||||
case Exception of
|
||||
#'InvalidRequest'{errors = Errors} ->
|
||||
@ -42,7 +42,7 @@ process_request('CreateCustomer', Req, Context) ->
|
||||
process_request('GetCustomerById', Req, Context) ->
|
||||
case get_customer_by_id(maps:get('customerID', Req), Context) of
|
||||
{ok, Customer} ->
|
||||
{ok, {200, [], decode_customer(Customer)}};
|
||||
{ok, {200, #{}, decode_customer(Customer)}};
|
||||
{exception, Exception} ->
|
||||
case Exception of
|
||||
#payproc_InvalidUser{} ->
|
||||
@ -55,7 +55,7 @@ process_request('GetCustomerById', Req, Context) ->
|
||||
process_request('DeleteCustomer', Req, Context) ->
|
||||
case capi_handler_utils:service_call({customer_management, 'Delete', [maps:get(customerID, Req)]}, Context) of
|
||||
{ok, _} ->
|
||||
{ok, {204, [], undefined}};
|
||||
{ok, {204, #{}, undefined}};
|
||||
{exception, Exception} ->
|
||||
case Exception of
|
||||
#payproc_InvalidUser{} ->
|
||||
@ -77,7 +77,7 @@ process_request('CreateCustomerAccessToken', Req, Context) ->
|
||||
capi_handler_utils:get_party_id(Context),
|
||||
{customer, CustomerID}
|
||||
),
|
||||
{ok, {201, [], Response}};
|
||||
{ok, {201, #{}, Response}};
|
||||
{exception, Exception} ->
|
||||
case Exception of
|
||||
#payproc_InvalidUser{} ->
|
||||
@ -99,7 +99,7 @@ process_request('CreateBinding', Req, Context) ->
|
||||
|
||||
case Result of
|
||||
{ok, CustomerBinding} ->
|
||||
{ok, {201, [], decode_customer_binding(CustomerBinding, Context)}};
|
||||
{ok, {201, #{}, decode_customer_binding(CustomerBinding, Context)}};
|
||||
{exception, Exception} ->
|
||||
case Exception of
|
||||
#'InvalidRequest'{errors = Errors} ->
|
||||
@ -137,7 +137,7 @@ process_request('CreateBinding', Req, Context) ->
|
||||
process_request('GetBindings', Req, Context) ->
|
||||
case get_customer_by_id(maps:get(customerID, Req), Context) of
|
||||
{ok, #payproc_Customer{bindings = Bindings}} ->
|
||||
{ok, {200, [], [decode_customer_binding(B, Context) || B <- Bindings]}};
|
||||
{ok, {200, #{}, [decode_customer_binding(B, Context) || B <- Bindings]}};
|
||||
{exception, Exception} ->
|
||||
case Exception of
|
||||
#payproc_InvalidUser{} ->
|
||||
@ -152,7 +152,7 @@ process_request('GetBinding', Req, Context) ->
|
||||
{ok, #payproc_Customer{bindings = Bindings}} ->
|
||||
case lists:keyfind(maps:get(customerBindingID, Req), #payproc_CustomerBinding.id, Bindings) of
|
||||
#payproc_CustomerBinding{} = B ->
|
||||
{ok, {200, [], decode_customer_binding(B, Context)}};
|
||||
{ok, {200, #{}, decode_customer_binding(B, Context)}};
|
||||
false ->
|
||||
{ok, general_error(404, <<"Customer binding not found">>)}
|
||||
end;
|
||||
@ -183,7 +183,7 @@ process_request('GetCustomerEvents', Req, Context) ->
|
||||
),
|
||||
case Result of
|
||||
{ok, Events} when is_list(Events) ->
|
||||
{ok, {200, [], Events}};
|
||||
{ok, {200, #{}, Events}};
|
||||
{exception, Exception} ->
|
||||
case Exception of
|
||||
#payproc_InvalidUser{} ->
|
||||
|
@ -24,7 +24,7 @@ process_request('GetLocationsNames', Req, Context) ->
|
||||
[],
|
||||
LocationNames
|
||||
),
|
||||
{ok, {200, [], PreparedLocationNames}};
|
||||
{ok, {200, #{}, PreparedLocationNames}};
|
||||
{exception, #'InvalidRequest'{errors = Errors}} ->
|
||||
FormattedErrors = capi_handler_utils:format_request_errors(Errors),
|
||||
{ok, logic_error(invalidRequest, FormattedErrors)}
|
||||
|
@ -26,7 +26,7 @@ process_request('CreateInvoiceTemplate', Req, Context) ->
|
||||
)
|
||||
of
|
||||
{ok, InvoiceTpl} ->
|
||||
{ok, {201, [], make_invoice_tpl_and_token(InvoiceTpl, PartyID, ExtraProperties)}};
|
||||
{ok, {201, #{}, make_invoice_tpl_and_token(InvoiceTpl, PartyID, ExtraProperties)}};
|
||||
{exception, Exception} ->
|
||||
case Exception of
|
||||
#'InvalidRequest'{errors = Errors} ->
|
||||
@ -50,7 +50,7 @@ process_request('GetInvoiceTemplateByID', Req, Context) ->
|
||||
Call = {invoice_templating, 'Get', [maps:get('invoiceTemplateID', Req)]},
|
||||
case capi_handler_utils:service_call_with([user_info, party_creation], Call, Context) of
|
||||
{ok, InvoiceTpl} ->
|
||||
{ok, {200, [], decode_invoice_tpl(InvoiceTpl)}};
|
||||
{ok, {200, #{}, decode_invoice_tpl(InvoiceTpl)}};
|
||||
{exception, E} when
|
||||
E == #payproc_InvalidUser{};
|
||||
E == #payproc_InvoiceTemplateNotFound{};
|
||||
@ -66,7 +66,7 @@ process_request('UpdateInvoiceTemplate', Req, Context) ->
|
||||
capi_handler_utils:service_call_with([user_info, party_creation], Call, Context)
|
||||
of
|
||||
{ok, InvoiceTpl} ->
|
||||
{ok, {200, [], decode_invoice_tpl(InvoiceTpl)}};
|
||||
{ok, {200, #{}, decode_invoice_tpl(InvoiceTpl)}};
|
||||
{exception, Exception} ->
|
||||
case Exception of
|
||||
#payproc_InvalidUser{} ->
|
||||
@ -100,7 +100,7 @@ process_request('DeleteInvoiceTemplate', Req, Context) ->
|
||||
Call = {invoice_templating, 'Delete', [maps:get('invoiceTemplateID', Req)]},
|
||||
case capi_handler_utils:service_call_with([user_info, party_creation], Call, Context) of
|
||||
{ok, _R} ->
|
||||
{ok, {204, [], undefined}};
|
||||
{ok, {204, #{}, undefined}};
|
||||
{exception, Exception} ->
|
||||
case Exception of
|
||||
#payproc_InvalidUser{} ->
|
||||
@ -123,7 +123,7 @@ process_request('CreateInvoiceWithTemplate' = OperationID, Req, Context) ->
|
||||
ExtraProperties = capi_handler_utils:get_extra_properties(Context),
|
||||
try create_invoice(PartyID, InvoiceTplID, InvoiceParams, Context, OperationID) of
|
||||
{ok, #'payproc_Invoice'{invoice = Invoice}} ->
|
||||
{ok, {201, [], capi_handler_decoder_invoicing:make_invoice_and_token(
|
||||
{ok, {201, #{}, capi_handler_decoder_invoicing:make_invoice_and_token(
|
||||
Invoice, capi_handler_utils:get_party_id(Context), ExtraProperties)
|
||||
}};
|
||||
{exception, Exception} ->
|
||||
@ -161,7 +161,7 @@ process_request('GetInvoicePaymentMethodsByTemplateID', Req, Context) ->
|
||||
case Result of
|
||||
{ok, PaymentMethods0} when is_list(PaymentMethods0) ->
|
||||
PaymentMethods = capi_utils:deduplicate_payment_methods(PaymentMethods0),
|
||||
{ok, {200, [], PaymentMethods}};
|
||||
{ok, {200, #{}, PaymentMethods}};
|
||||
{exception, E} when
|
||||
E == #payproc_InvalidUser{};
|
||||
E == #payproc_InvoiceTemplateNotFound{};
|
||||
|
@ -20,7 +20,7 @@ process_request('CreateInvoice' = OperationID, Req, Context) ->
|
||||
InvoiceParams = maps:get('InvoiceParams', Req),
|
||||
try create_invoice(PartyID, InvoiceParams, Context, OperationID) of
|
||||
{ok, #'payproc_Invoice'{invoice = Invoice}} ->
|
||||
{ok, {201, [], capi_handler_decoder_invoicing:make_invoice_and_token(Invoice, PartyID, ExtraProperties)}};
|
||||
{ok, {201, #{}, capi_handler_decoder_invoicing:make_invoice_and_token(Invoice, PartyID, ExtraProperties)}};
|
||||
{exception, Exception} ->
|
||||
case Exception of
|
||||
#'InvalidRequest'{errors = Errors} ->
|
||||
@ -50,7 +50,7 @@ process_request('CreateInvoiceAccessToken', Req, Context) ->
|
||||
capi_handler_utils:get_party_id(Context),
|
||||
{invoice, InvoiceID}
|
||||
),
|
||||
{ok, {201, [], Response}};
|
||||
{ok, {201, #{}, Response}};
|
||||
{exception, Exception} ->
|
||||
case Exception of
|
||||
#payproc_InvalidUser{} ->
|
||||
@ -63,7 +63,7 @@ process_request('CreateInvoiceAccessToken', Req, Context) ->
|
||||
process_request('GetInvoiceByID', Req, Context) ->
|
||||
case capi_handler_utils:get_invoice_by_id(maps:get(invoiceID, Req), Context) of
|
||||
{ok, #'payproc_Invoice'{invoice = Invoice}} ->
|
||||
{ok, {200, [], capi_handler_decoder_invoicing:decode_invoice(Invoice)}};
|
||||
{ok, {200, #{}, capi_handler_decoder_invoicing:decode_invoice(Invoice)}};
|
||||
{exception, Exception} ->
|
||||
case Exception of
|
||||
#payproc_InvalidUser{} ->
|
||||
@ -77,7 +77,7 @@ process_request('FulfillInvoice', Req, Context) ->
|
||||
Call = {invoicing, 'Fulfill', [maps:get(invoiceID, Req), maps:get(<<"reason">>, maps:get('Reason', Req))]},
|
||||
case capi_handler_utils:service_call_with([user_info], Call, Context) of
|
||||
{ok, _} ->
|
||||
{ok, {204, [], undefined}};
|
||||
{ok, {204, #{}, undefined}};
|
||||
{exception, Exception} ->
|
||||
case Exception of
|
||||
#payproc_InvalidInvoiceStatus{} ->
|
||||
@ -97,7 +97,7 @@ process_request('RescindInvoice', Req, Context) ->
|
||||
Call = {invoicing, 'Rescind', [maps:get(invoiceID, Req), maps:get(<<"reason">>, maps:get('Reason', Req))]},
|
||||
case capi_handler_utils:service_call_with([user_info], Call, Context) of
|
||||
{ok, _} ->
|
||||
{ok, {204, [], undefined}};
|
||||
{ok, {204, #{}, undefined}};
|
||||
{exception, Exception} ->
|
||||
case Exception of
|
||||
#payproc_InvalidInvoiceStatus{} ->
|
||||
@ -133,7 +133,7 @@ process_request('GetInvoiceEvents', Req, Context) ->
|
||||
),
|
||||
case Result of
|
||||
{ok, Events} when is_list(Events) ->
|
||||
{ok, {200, [], Events}};
|
||||
{ok, {200, #{}, Events}};
|
||||
{exception, Exception} ->
|
||||
case Exception of
|
||||
#payproc_InvalidUser{} ->
|
||||
@ -152,7 +152,7 @@ process_request('GetInvoicePaymentMethods', Req, Context) ->
|
||||
case capi_handler_decoder_invoicing:construct_payment_methods(invoicing, [maps:get(invoiceID, Req)], Context) of
|
||||
{ok, PaymentMethods0} when is_list(PaymentMethods0) ->
|
||||
PaymentMethods = capi_utils:deduplicate_payment_methods(PaymentMethods0),
|
||||
{ok, {200, [], PaymentMethods}};
|
||||
{ok, {200, #{}, PaymentMethods}};
|
||||
{exception, Exception} ->
|
||||
case Exception of
|
||||
#payproc_InvalidUser{} ->
|
||||
|
@ -14,22 +14,22 @@
|
||||
|
||||
process_request('GetMyParty', _Req, Context) ->
|
||||
Party = capi_utils:unwrap(capi_handler_utils:get_my_party(Context)),
|
||||
{ok, {200, [], capi_handler_decoder_party:decode_party(Party)}};
|
||||
{ok, {200, #{}, capi_handler_decoder_party:decode_party(Party)}};
|
||||
process_request('ActivateMyParty', _Req, Context) ->
|
||||
Call = {party_management, 'Activate', []},
|
||||
case capi_handler_utils:service_call_with([user_info, party_id, party_creation], Call, Context) of
|
||||
{ok, _R} ->
|
||||
{ok, {204, [], undefined}};
|
||||
{ok, {204, #{}, undefined}};
|
||||
{exception, #payproc_InvalidPartyStatus{status = {suspension, {active, _}}}} ->
|
||||
{ok, {204, [], undefined}}
|
||||
{ok, {204, #{}, undefined}}
|
||||
end;
|
||||
process_request('SuspendMyParty', _Req, Context) ->
|
||||
Call = {party_management, 'Suspend', []},
|
||||
case capi_handler_utils:service_call_with([user_info, party_id, party_creation], Call, Context) of
|
||||
{ok, _R} ->
|
||||
{ok, {204, [], undefined}};
|
||||
{ok, {204, #{}, undefined}};
|
||||
{exception, #payproc_InvalidPartyStatus{status = {suspension, {suspended, _}}}} ->
|
||||
{ok, {204, [], undefined}}
|
||||
{ok, {204, #{}, undefined}}
|
||||
end;
|
||||
|
||||
%%
|
||||
|
@ -34,7 +34,7 @@ process_request('GetPaymentInstitutions', Req, #{woody_context := WoodyContext})
|
||||
end,
|
||||
PaymentInstObjects
|
||||
),
|
||||
{ok, {200, [], Resp}}
|
||||
{ok, {200, #{}, Resp}}
|
||||
catch
|
||||
throw:{encode_residence, invalid_residence} ->
|
||||
{ok, logic_error(invalidRequest, <<"Invalid residence">>)}
|
||||
@ -44,7 +44,7 @@ process_request('GetPaymentInstitutionByRef', Req, #{woody_context := WoodyConte
|
||||
PaymentInstitutionID = genlib:to_int(maps:get(paymentInstitutionID, Req)),
|
||||
case capi_domain:get({payment_institution, ?payment_institution_ref(PaymentInstitutionID)}, WoodyContext) of
|
||||
{ok, PaymentInstitution} ->
|
||||
{ok, {200, [], decode_payment_institution_obj(PaymentInstitution)}};
|
||||
{ok, {200, #{}, decode_payment_institution_obj(PaymentInstitution)}};
|
||||
{error, not_found} ->
|
||||
{ok, general_error(404, <<"Payment institution not found">>)}
|
||||
end;
|
||||
@ -53,7 +53,7 @@ process_request('GetPaymentInstitutionPaymentTerms', Req, Context) ->
|
||||
PaymentInstitutionID = genlib:to_int(maps:get(paymentInstitutionID, Req)),
|
||||
case compute_payment_institution_terms(PaymentInstitutionID, #payproc_Varset{}, Context) of
|
||||
{ok, #domain_TermSet{payments = PaymentTerms}} ->
|
||||
{ok, {200, [], decode_payment_terms(PaymentTerms)}};
|
||||
{ok, {200, #{}, decode_payment_terms(PaymentTerms)}};
|
||||
{exception, #payproc_PaymentInstitutionNotFound{}} ->
|
||||
{ok, general_error(404, <<"Payment institution not found">>)}
|
||||
end;
|
||||
@ -62,7 +62,7 @@ process_request('GetPaymentInstitutionPayoutMethods', Req, Context) ->
|
||||
PaymentInstitutionID = genlib:to_int(maps:get(paymentInstitutionID, Req)),
|
||||
case compute_payment_institution_terms(PaymentInstitutionID, prepare_varset(Req), Context) of
|
||||
{ok, #domain_TermSet{payouts = #domain_PayoutsServiceTerms{payout_methods = PayoutMethods}}} ->
|
||||
{ok, {200, [], decode_payout_methods_selector(PayoutMethods)}};
|
||||
{ok, {200, #{}, decode_payout_methods_selector(PayoutMethods)}};
|
||||
{ok, #domain_TermSet{payouts = undefined}} ->
|
||||
{ok, general_error(404, <<"Automatic payouts not allowed">>)};
|
||||
{exception, #payproc_PaymentInstitutionNotFound{}} ->
|
||||
@ -73,7 +73,7 @@ process_request('GetPaymentInstitutionPayoutSchedules', Req, Context) ->
|
||||
PaymentInstitutionID = genlib:to_int(maps:get(paymentInstitutionID, Req)),
|
||||
case compute_payment_institution_terms(PaymentInstitutionID, prepare_varset(Req), Context) of
|
||||
{ok, #domain_TermSet{payouts = #domain_PayoutsServiceTerms{payout_schedules = Schedules}}} ->
|
||||
{ok, {200, [], decode_business_schedules_selector(Schedules)}};
|
||||
{ok, {200, #{}, decode_business_schedules_selector(Schedules)}};
|
||||
{ok, #domain_TermSet{payouts = undefined}} ->
|
||||
{ok, general_error(404, <<"Automatic payouts not allowed">>)};
|
||||
{exception, #payproc_PaymentInstitutionNotFound{}} ->
|
||||
|
@ -33,7 +33,7 @@ process_request('CreatePayment' = OperationID, Req, Context) ->
|
||||
|
||||
case Result of
|
||||
{ok, Payment} ->
|
||||
{ok, {201, [], decode_invoice_payment(InvoiceID, Payment, Context)}};
|
||||
{ok, {201, #{}, decode_invoice_payment(InvoiceID, Payment, Context)}};
|
||||
{exception, Exception} ->
|
||||
case Exception of
|
||||
#payproc_InvalidInvoiceStatus{} ->
|
||||
@ -86,7 +86,7 @@ process_request('GetPayments', Req, Context) ->
|
||||
InvoiceID = maps:get(invoiceID, Req),
|
||||
case capi_handler_utils:get_invoice_by_id(InvoiceID, Context) of
|
||||
{ok, #'payproc_Invoice'{payments = Payments}} ->
|
||||
{ok, {200, [], [decode_invoice_payment(InvoiceID, P, Context) || P <- Payments]}};
|
||||
{ok, {200, #{}, [decode_invoice_payment(InvoiceID, P, Context) || P <- Payments]}};
|
||||
{exception, Exception} ->
|
||||
case Exception of
|
||||
#payproc_InvalidUser{} ->
|
||||
@ -100,7 +100,7 @@ process_request('GetPaymentByID', Req, Context) ->
|
||||
InvoiceID = maps:get(invoiceID, Req),
|
||||
case capi_handler_utils:get_payment_by_id(InvoiceID, maps:get(paymentID, Req), Context) of
|
||||
{ok, Payment} ->
|
||||
{ok, {200, [], decode_invoice_payment(InvoiceID, Payment, Context)}};
|
||||
{ok, {200, #{}, decode_invoice_payment(InvoiceID, Payment, Context)}};
|
||||
{exception, Exception} ->
|
||||
case Exception of
|
||||
#payproc_InvoicePaymentNotFound{} ->
|
||||
@ -116,7 +116,7 @@ process_request('GetPaymentByExternalID', Req, Context) ->
|
||||
ExternalID = maps:get(externalID, Req),
|
||||
case get_payment_by_external_id(ExternalID, Context) of
|
||||
{ok, InvoiceID, Payment} ->
|
||||
{ok, {200, [], decode_invoice_payment(InvoiceID, Payment, Context)}};
|
||||
{ok, {200, #{}, decode_invoice_payment(InvoiceID, Payment, Context)}};
|
||||
{error, internal_id_not_found} ->
|
||||
{ok, general_error(404, <<"Payment not found">>)};
|
||||
{error, invoice_not_found} ->
|
||||
@ -137,7 +137,7 @@ process_request('CancelPayment', Req, Context) ->
|
||||
Call = {invoicing, 'CancelPayment', CallArgs},
|
||||
case capi_handler_utils:service_call_with([user_info], Call, Context) of
|
||||
{ok, _} ->
|
||||
{ok, {202, [], undefined}};
|
||||
{ok, {202, #{}, undefined}};
|
||||
{exception, Exception} ->
|
||||
case Exception of
|
||||
#payproc_InvoicePaymentNotFound{} ->
|
||||
@ -179,7 +179,7 @@ process_request('CapturePayment', Req, Context) ->
|
||||
Call = {invoicing, 'CapturePaymentNew', CallArgs},
|
||||
case capi_handler_utils:service_call_with([user_info], Call, Context) of
|
||||
{ok, _} ->
|
||||
{ok, {202, [], undefined}};
|
||||
{ok, {202, #{}, undefined}};
|
||||
{exception, Exception} ->
|
||||
case Exception of
|
||||
#payproc_InvoicePaymentNotFound{} ->
|
||||
@ -227,7 +227,7 @@ process_request('CreateRefund', Req, Context) ->
|
||||
Call = {invoicing, 'RefundPayment', [InvoiceID, PaymentID, Params]},
|
||||
case capi_handler_utils:service_call_with([user_info], Call, Context) of
|
||||
{ok, Refund} ->
|
||||
{ok, {201, [], capi_handler_decoder_invoicing:decode_refund(Refund, Context)}};
|
||||
{ok, {201, #{}, capi_handler_decoder_invoicing:decode_refund(Refund, Context)}};
|
||||
{exception, Exception} ->
|
||||
case Exception of
|
||||
#payproc_InvalidUser{} ->
|
||||
@ -284,7 +284,7 @@ process_request('CreateRefund', Req, Context) ->
|
||||
process_request('GetRefunds', Req, Context) ->
|
||||
case capi_handler_utils:get_payment_by_id(maps:get(invoiceID, Req), maps:get(paymentID, Req), Context) of
|
||||
{ok, #payproc_InvoicePayment{refunds = Refunds}} ->
|
||||
{ok, {200, [], [capi_handler_decoder_invoicing:decode_refund(R, Context) || R <- Refunds]}};
|
||||
{ok, {200, #{}, [capi_handler_decoder_invoicing:decode_refund(R, Context) || R <- Refunds]}};
|
||||
{exception, Exception} ->
|
||||
case Exception of
|
||||
#payproc_InvalidUser{} ->
|
||||
@ -301,7 +301,7 @@ process_request('GetRefundByID', Req, Context) ->
|
||||
{invoicing, 'GetPaymentRefund', [maps:get(invoiceID, Req), maps:get(paymentID, Req), maps:get(refundID, Req)]},
|
||||
case capi_handler_utils:service_call_with([user_info], Call, Context) of
|
||||
{ok, Refund} ->
|
||||
{ok, {200, [], capi_handler_decoder_invoicing:decode_refund(Refund, Context)}};
|
||||
{ok, {200, #{}, capi_handler_decoder_invoicing:decode_refund(Refund, Context)}};
|
||||
{exception, Exception} ->
|
||||
case Exception of
|
||||
#payproc_InvoicePaymentRefundNotFound{} ->
|
||||
|
@ -18,7 +18,7 @@
|
||||
process_request('GetPayoutTools', Req, Context) ->
|
||||
case capi_handler_utils:get_contract_by_id(maps:get('contractID', Req), Context) of
|
||||
{ok, #domain_Contract{payout_tools = PayoutTools}} ->
|
||||
{ok, {200, [], [decode_payout_tool(P) || P <- PayoutTools]}};
|
||||
{ok, {200, #{}, [decode_payout_tool(P) || P <- PayoutTools]}};
|
||||
{exception, #payproc_ContractNotFound{}} ->
|
||||
{ok, general_error(404, <<"Contract not found">>)}
|
||||
end;
|
||||
@ -29,7 +29,7 @@ process_request('GetPayoutToolByID', Req, Context) ->
|
||||
PayoutToolID = maps:get('payoutToolID', Req),
|
||||
case lists:keyfind(PayoutToolID, #domain_PayoutTool.id, PayoutTools) of
|
||||
#domain_PayoutTool{} = P ->
|
||||
{ok, {200, [], decode_payout_tool(P)}};
|
||||
{ok, {200, #{}, decode_payout_tool(P)}};
|
||||
false ->
|
||||
{ok, general_error(404, <<"PayoutTool not found">>)}
|
||||
end;
|
||||
@ -43,7 +43,7 @@ process_request('GetPayout', Req, Context) ->
|
||||
{ok, Payout} ->
|
||||
case check_party_in_payout(capi_handler_utils:get_party_id(Context), Payout) of
|
||||
true ->
|
||||
{ok, {200, [], decode_payout(Payout)}};
|
||||
{ok, {200, #{}, decode_payout(Payout)}};
|
||||
false ->
|
||||
{ok, general_error(404, <<"Payout not found">>)}
|
||||
end;
|
||||
@ -58,7 +58,7 @@ process_request('CreatePayout', Req, Context) ->
|
||||
),
|
||||
case capi_handler_utils:service_call({payouts, 'CreatePayout', [CreateRequest]}, Context) of
|
||||
{ok, Payout} ->
|
||||
{ok, {201, [], decode_payout(Payout)}};
|
||||
{ok, {201, #{}, decode_payout(Payout)}};
|
||||
{exception, Exception} ->
|
||||
case Exception of
|
||||
#'payout_processing_InvalidPayoutTool'{} ->
|
||||
@ -74,7 +74,7 @@ process_request('CreatePayout', Req, Context) ->
|
||||
process_request('GetScheduleByRef', Req, Context) ->
|
||||
case get_schedule_by_id(genlib:to_int(maps:get(scheduleID, Req)), Context) of
|
||||
{ok, Schedule} ->
|
||||
{ok, {200, [], decode_business_schedule(Schedule)}};
|
||||
{ok, {200, #{}, decode_business_schedule(Schedule)}};
|
||||
{error, not_found} ->
|
||||
{ok, general_error(404, <<"Schedule not found">>)}
|
||||
end;
|
||||
|
@ -30,7 +30,7 @@ process_request('GetReports', Req, Context) ->
|
||||
Call = {reporting, 'GetReports', [ReportRequest, ReportTypes]},
|
||||
case capi_handler_utils:service_call(Call, Context) of
|
||||
{ok, Reports} ->
|
||||
{ok, {200, [], [decode_report(R) || R <- Reports]}};
|
||||
{ok, {200, #{}, [decode_report(R) || R <- Reports]}};
|
||||
{exception, Exception} ->
|
||||
case Exception of
|
||||
#'InvalidRequest'{errors = Errors} ->
|
||||
@ -48,7 +48,7 @@ process_request('GetReport', Req, Context) ->
|
||||
Call = {reporting, 'GetReport', [PartyId, ShopId, ReportId]},
|
||||
case capi_handler_utils:service_call(Call, Context) of
|
||||
{ok, Report} ->
|
||||
{ok, {200, [], decode_report(Report)}};
|
||||
{ok, {200, #{}, decode_report(Report)}};
|
||||
{exception, #reports_ReportNotFound{}} ->
|
||||
{ok, general_error(404, <<"Report not found">>)}
|
||||
end;
|
||||
@ -73,7 +73,7 @@ process_request('CreateReport', Req, Context) ->
|
||||
{reporting, 'GetReport', [PartyId, ShopId, ReportId]},
|
||||
Context
|
||||
),
|
||||
{ok, {201, [], decode_report(Report)}};
|
||||
{ok, {201, #{}, decode_report(Report)}};
|
||||
{exception, Exception} ->
|
||||
case Exception of
|
||||
#'InvalidRequest'{errors = Errors} ->
|
||||
@ -113,7 +113,7 @@ generate_report_presigned_url(FileID, Context) ->
|
||||
Call = {reporting, 'GeneratePresignedUrl', [FileID, ExpiresAt]},
|
||||
case capi_handler_utils:service_call(Call, Context) of
|
||||
{ok, URL} ->
|
||||
{ok, {200, [], #{<<"url">> => URL}}};
|
||||
{ok, {200, #{}, #{<<"url">> => URL}}};
|
||||
{exception, Exception} ->
|
||||
case Exception of
|
||||
#'InvalidRequest'{errors = Errors} ->
|
||||
|
@ -144,7 +144,7 @@ process_search_request_result(QueryType, Result, Context, #{decode_fun := Decode
|
||||
<<"totalCount">> => TotalCount,
|
||||
<<"continuationToken">> => ContinuationToken
|
||||
}),
|
||||
{ok, {200, [], Resp}};
|
||||
{ok, {200, #{}, Resp}};
|
||||
{exception, #'InvalidRequest'{errors = Errors}} ->
|
||||
FormattedErrors = capi_handler_utils:format_request_errors(Errors),
|
||||
{ok, logic_error(invalidRequest, FormattedErrors)};
|
||||
|
@ -17,13 +17,13 @@ process_request('ActivateShop', Req, Context) ->
|
||||
Call = {party_management, 'ActivateShop', [maps:get(shopID, Req)]},
|
||||
case capi_handler_utils:service_call_with([user_info, party_id, party_creation], Call, Context) of
|
||||
{ok, _R} ->
|
||||
{ok, {204, [], undefined}};
|
||||
{ok, {204, #{}, undefined}};
|
||||
{exception, Exception} ->
|
||||
case Exception of
|
||||
#payproc_ShopNotFound{} ->
|
||||
{ok, general_error(404, <<"Shop not found">>)};
|
||||
#payproc_InvalidShopStatus{status = {suspension, {active, _}}} ->
|
||||
{ok, {204, [], undefined}}
|
||||
{ok, {204, #{}, undefined}}
|
||||
end
|
||||
end;
|
||||
|
||||
@ -31,25 +31,25 @@ process_request('SuspendShop', Req, Context) ->
|
||||
Call = {party_management, 'SuspendShop', [maps:get(shopID, Req)]},
|
||||
case capi_handler_utils:service_call_with([user_info, party_id, party_creation], Call, Context) of
|
||||
{ok, _R} ->
|
||||
{ok, {204, [], undefined}};
|
||||
{ok, {204, #{}, undefined}};
|
||||
{exception, Exception} ->
|
||||
case Exception of
|
||||
#payproc_ShopNotFound{} ->
|
||||
{ok, general_error(404, <<"Shop not found">>)};
|
||||
#payproc_InvalidShopStatus{status = {suspension, {suspended, _}}} ->
|
||||
{ok, {204, [], undefined}}
|
||||
{ok, {204, #{}, undefined}}
|
||||
end
|
||||
end;
|
||||
|
||||
process_request('GetShops', _Req, Context) ->
|
||||
Party = capi_utils:unwrap(capi_handler_utils:get_my_party(Context)),
|
||||
{ok, {200, [], decode_shops_map(Party#domain_Party.shops)}};
|
||||
{ok, {200, #{}, decode_shops_map(Party#domain_Party.shops)}};
|
||||
|
||||
process_request('GetShopByID', Req, Context) ->
|
||||
Call = {party_management, 'GetShop', [maps:get(shopID, Req)]},
|
||||
case capi_handler_utils:service_call_with([user_info, party_id, party_creation], Call, Context) of
|
||||
{ok, Shop} ->
|
||||
{ok, {200, [], decode_shop(Shop)}};
|
||||
{ok, {200, #{}, decode_shop(Shop)}};
|
||||
{exception, #payproc_ShopNotFound{}} ->
|
||||
{ok, general_error(404, <<"Shop not found">>)}
|
||||
end;
|
||||
|
@ -47,7 +47,7 @@ process_request('CreatePaymentResource' = OperationID, Req, Context) ->
|
||||
payment_session_id = PaymentSessionID,
|
||||
client_info = capi_handler_encoder:encode_client_info(ClientInfo)
|
||||
},
|
||||
{ok, {201, [], capi_handler_decoder_party:decode_disposable_payment_resource(PaymentResource)}}
|
||||
{ok, {201, #{}, capi_handler_decoder_party:decode_disposable_payment_resource(PaymentResource)}}
|
||||
catch
|
||||
Result -> Result
|
||||
end;
|
||||
@ -66,7 +66,7 @@ enrich_client_info(ClientInfo, Context) ->
|
||||
false ->
|
||||
prepare_client_ip(Context);
|
||||
Value ->
|
||||
_ = lager:notice("Unexpected ip_replacement_allowed value: ~p", [Value]),
|
||||
_ = logger:notice("Unexpected ip_replacement_allowed value: ~p", [Value]),
|
||||
prepare_client_ip(Context)
|
||||
end,
|
||||
ClientInfo#{<<"ip">> => IP}.
|
||||
|
@ -35,11 +35,11 @@
|
||||
-type processing_context() :: capi_handler:processing_context().
|
||||
-type response() :: capi_handler:response().
|
||||
|
||||
-spec general_error(integer(), binary()) ->
|
||||
-spec general_error(cowboy:http_status(), binary()) ->
|
||||
response().
|
||||
|
||||
general_error(Code, Message) ->
|
||||
create_erorr_resp(Code, #{<<"message">> => genlib:to_binary(Message)}).
|
||||
create_error_resp(Code, #{<<"message">> => genlib:to_binary(Message)}).
|
||||
|
||||
-spec logic_error
|
||||
(term(), io_lib:chars() | binary()) -> response();
|
||||
@ -52,26 +52,26 @@ logic_error(externalIDConflict, {ID, ExternalID}) ->
|
||||
<<"externalID">> => ExternalID,
|
||||
<<"id">> => ID,
|
||||
<<"message">> => <<"This 'externalID' has been used by another request">>},
|
||||
create_erorr_resp(409, Data);
|
||||
create_error_resp(409, Data);
|
||||
logic_error(externalIDConflict, ExternalID) ->
|
||||
Data = #{
|
||||
<<"externalID">> => ExternalID,
|
||||
<<"message">> => <<"This 'externalID' has been used by another request">>},
|
||||
create_erorr_resp(409, Data);
|
||||
create_error_resp(409, Data);
|
||||
logic_error(Code, Message) ->
|
||||
Data = #{<<"code">> => genlib:to_binary(Code), <<"message">> => genlib:to_binary(Message)},
|
||||
create_erorr_resp(400, Data).
|
||||
create_error_resp(400, Data).
|
||||
|
||||
create_erorr_resp(Code, Data) ->
|
||||
create_erorr_resp(Code, [], Data).
|
||||
create_erorr_resp(Code, Headers, Data) ->
|
||||
create_error_resp(Code, Data) ->
|
||||
create_error_resp(Code, #{}, Data).
|
||||
create_error_resp(Code, Headers, Data) ->
|
||||
{Code, Headers, Data}.
|
||||
|
||||
-spec server_error(integer()) ->
|
||||
{integer(), [], <<>>}.
|
||||
{integer(), #{}, <<>>}.
|
||||
|
||||
server_error(Code) when Code >= 500 andalso Code < 600 ->
|
||||
{Code, [], <<>>}.
|
||||
{Code, #{}, <<>>}.
|
||||
|
||||
-spec format_request_errors(list()) ->
|
||||
binary().
|
||||
@ -98,7 +98,7 @@ service_call_with_([party_id|T], {ServiceName, Function, Args}, Context) ->
|
||||
service_call_with_([party_creation|T], Call, Context) ->
|
||||
case service_call_with_(T, Call, Context) of
|
||||
{exception, #payproc_PartyNotFound{}} ->
|
||||
_ = lager:info("Attempting to create a missing party"),
|
||||
_ = logger:info("Attempting to create a missing party"),
|
||||
CreateCall = {party_management, 'Create', [get_party_params(Context)]},
|
||||
case service_call_with([user_info, party_id], CreateCall, Context) of
|
||||
{ok , _ } -> service_call_with_(T, Call, Context);
|
||||
|
@ -23,7 +23,7 @@ process_request('CreateWebhook', Req, Context) ->
|
||||
Webhook = capi_utils:unwrap(
|
||||
capi_handler_utils:service_call({webhook_manager, 'Create', [WebhookParams]}, Context)
|
||||
),
|
||||
{ok, {201, [], decode_webhook(Webhook)}};
|
||||
{ok, {201, #{}, decode_webhook(Webhook)}};
|
||||
{exception, #payproc_ShopNotFound{}} ->
|
||||
{ok, logic_error(invalidShopID, <<"Shop not found">>)}
|
||||
end;
|
||||
@ -32,14 +32,14 @@ process_request('GetWebhooks', _Req, Context) ->
|
||||
Webhooks = capi_utils:unwrap(
|
||||
capi_handler_utils:service_call_with([party_id], {webhook_manager, 'GetList', []}, Context)
|
||||
),
|
||||
{ok, {200, [], [decode_webhook(V) || V <- Webhooks]}};
|
||||
{ok, {200, #{}, [decode_webhook(V) || V <- Webhooks]}};
|
||||
|
||||
process_request('GetWebhookByID', Req, Context) ->
|
||||
case encode_webhook_id(maps:get(webhookID, Req)) of
|
||||
{ok, WebhookID} ->
|
||||
case get_webhook(WebhookID, Context) of
|
||||
{ok, Webhook} ->
|
||||
{ok, {200, [], decode_webhook(Webhook)}};
|
||||
{ok, {200, #{}, decode_webhook(Webhook)}};
|
||||
{exception, #webhooker_WebhookNotFound{}} ->
|
||||
{ok, general_error(404, <<"Webhook not found">>)}
|
||||
end;
|
||||
@ -52,9 +52,9 @@ process_request('DeleteWebhookByID', Req, Context) ->
|
||||
{ok, WebhookID} ->
|
||||
case delete_webhook(WebhookID, Context) of
|
||||
{ok, _} ->
|
||||
{ok, {204, [], undefined}};
|
||||
{ok, {204, #{}, undefined}};
|
||||
{exception, #webhooker_WebhookNotFound{}} ->
|
||||
{ok, {204, [], undefined}}
|
||||
{ok, {204, #{}, undefined}}
|
||||
end;
|
||||
error ->
|
||||
{ok, general_error(404, <<"Webhook not found">>)}
|
||||
|
79
apps/capi/src/capi_stream_h.erl
Normal file
79
apps/capi/src/capi_stream_h.erl
Normal file
@ -0,0 +1,79 @@
|
||||
-module(capi_stream_h).
|
||||
-behaviour(cowboy_stream).
|
||||
|
||||
-define(APP, capi).
|
||||
|
||||
%% callback exports
|
||||
|
||||
-export([init/3]).
|
||||
-export([data/4]).
|
||||
-export([info/3]).
|
||||
-export([terminate/3]).
|
||||
-export([early_error/5]).
|
||||
|
||||
-type state() :: #{
|
||||
next := any()
|
||||
}.
|
||||
|
||||
%% callbacks
|
||||
|
||||
-spec init(cowboy_stream:streamid(), cowboy_req:req(), cowboy:opts())
|
||||
-> {cowboy_stream:commands(), state()}.
|
||||
init(StreamID, Req, Opts) ->
|
||||
{Commands0, Next} = cowboy_stream:init(StreamID, Req, Opts),
|
||||
{Commands0, #{next => Next}}.
|
||||
|
||||
-spec data(cowboy_stream:streamid(), cowboy_stream:fin(), cowboy_req:resp_body(), State)
|
||||
-> {cowboy_stream:commands(), State} when State::state().
|
||||
data(StreamID, IsFin, Data, #{next := Next0} = State) ->
|
||||
{Commands0, Next} = cowboy_stream:data(StreamID, IsFin, Data, Next0),
|
||||
{Commands0, State#{next => Next}}.
|
||||
|
||||
-spec info(cowboy_stream:streamid(), any(), State)
|
||||
-> {cowboy_stream:commands(), State} when State::state().
|
||||
info(StreamID, {response, _, _, _} = Info, #{next := Next0} = State) ->
|
||||
Resp1 = handle_response(Info),
|
||||
{Commands0, Next} = cowboy_stream:info(StreamID, Resp1, Next0),
|
||||
{Commands0, State#{next => Next}};
|
||||
info(StreamID, Info, #{next := Next0} = State) ->
|
||||
{Commands0, Next} = cowboy_stream:info(StreamID, Info, Next0),
|
||||
{Commands0, State#{next => Next}}.
|
||||
|
||||
-spec terminate(cowboy_stream:streamid(), cowboy_stream:reason(), state()) -> any().
|
||||
terminate(StreamID, Reason, #{next := Next}) ->
|
||||
cowboy_stream:terminate(StreamID, Reason, Next).
|
||||
|
||||
-spec early_error(cowboy_stream:streamid(), cowboy_stream:reason(),
|
||||
cowboy_stream:partial_req(), Resp, cowboy:opts()) -> Resp
|
||||
when Resp::cowboy_stream:resp_command().
|
||||
early_error(StreamID, Reason, PartialReq, Resp, Opts) ->
|
||||
Resp1 = handle_response(Resp),
|
||||
cowboy_stream:early_error(StreamID, Reason, PartialReq, Resp1, Opts).
|
||||
|
||||
%% private functions
|
||||
|
||||
handle_response({response, Code, Headers, Body}) when Code >= 500 ->
|
||||
send_oops_resp(Code, Headers, get_oops_body_safe(Code), Body);
|
||||
handle_response({response, _, _, _} = Resp) ->
|
||||
Resp.
|
||||
|
||||
send_oops_resp(Code, Headers, undefined, Body) ->
|
||||
{response, Code, Headers, Body};
|
||||
send_oops_resp(Code, Headers0, File, _) ->
|
||||
FileSize = filelib:file_size(File),
|
||||
Headers = maps:merge(Headers0, #{
|
||||
<<"content-type">> => <<"text/plain; charset=utf-8">>,
|
||||
<<"content-length">> => integer_to_list(FileSize)
|
||||
}),
|
||||
{response, Code, Headers, {sendfile, 0, FileSize, File}}.
|
||||
|
||||
get_oops_body_safe(Code) ->
|
||||
try get_oops_body(Code)
|
||||
catch
|
||||
Error:Reason ->
|
||||
_ = logger:warning("Invalid oops body config for code: ~p. Error: ~p:~p", [Code, Error, Reason]),
|
||||
undefined
|
||||
end.
|
||||
|
||||
get_oops_body(Code) ->
|
||||
genlib_map:get(Code, genlib_app:env(?APP, oops_bodies, #{}), undefined).
|
@ -1,8 +1,6 @@
|
||||
-module(capi_swagger_server).
|
||||
|
||||
-export([child_spec /1]).
|
||||
-export([request_hook /1]).
|
||||
-export([response_hook/4]).
|
||||
-export([child_spec /1]).
|
||||
|
||||
-define(APP, capi).
|
||||
-define(DEFAULT_ACCEPTORS_POOLSIZE, 100).
|
||||
@ -18,14 +16,13 @@
|
||||
child_spec({HealthRoutes, LogicHandler}) ->
|
||||
{Transport, TransportOpts} = get_socket_transport(),
|
||||
CowboyOpts = get_cowboy_config(HealthRoutes, LogicHandler),
|
||||
AcceptorsPool = genlib_app:env(?APP, acceptors_poolsize, ?DEFAULT_ACCEPTORS_POOLSIZE),
|
||||
ranch:child_spec(?MODULE, AcceptorsPool,
|
||||
Transport, TransportOpts, cowboy_protocol, CowboyOpts).
|
||||
ranch:child_spec(?MODULE, Transport, TransportOpts, cowboy_clear, CowboyOpts).
|
||||
|
||||
get_socket_transport() ->
|
||||
{ok, IP} = inet:parse_address(genlib_app:env(?APP, ip, ?DEFAULT_IP_ADDR)),
|
||||
Port = genlib_app:env(?APP, port, ?DEFAULT_PORT),
|
||||
{ranch_tcp, [{ip, IP}, {port, Port}]}.
|
||||
AcceptorsPool = genlib_app:env(?APP, acceptors_poolsize, ?DEFAULT_ACCEPTORS_POOLSIZE),
|
||||
{ranch_tcp, #{socket_opts => [{ip, IP}, {port, Port}], num_acceptors => AcceptorsPool}}.
|
||||
|
||||
get_cowboy_config(HealthRoutes, LogicHandler) ->
|
||||
Dispatch =
|
||||
@ -33,19 +30,25 @@ get_cowboy_config(HealthRoutes, LogicHandler) ->
|
||||
HealthRoutes ++
|
||||
swag_server_router:get_paths(LogicHandler)
|
||||
)),
|
||||
[
|
||||
{env, [
|
||||
{dispatch, Dispatch},
|
||||
{cors_policy, capi_cors_policy}
|
||||
]},
|
||||
{middlewares, [
|
||||
CowboyOpts = #{
|
||||
env => #{
|
||||
dispatch => Dispatch,
|
||||
cors_policy => capi_cors_policy
|
||||
},
|
||||
middlewares => [
|
||||
cowboy_router,
|
||||
cowboy_cors,
|
||||
cowboy_handler
|
||||
]},
|
||||
{onrequest, cowboy_access_log:get_request_hook()},
|
||||
{onresponse, fun ?MODULE:response_hook/4}
|
||||
].
|
||||
],
|
||||
stream_handlers => [
|
||||
cowboy_access_log_h, capi_stream_h, cowboy_stream_h
|
||||
]
|
||||
},
|
||||
cowboy_access_log_h:set_extra_info_fun(
|
||||
mk_operation_id_getter(CowboyOpts),
|
||||
CowboyOpts
|
||||
).
|
||||
|
||||
|
||||
squash_routes(Routes) ->
|
||||
orddict:to_list(lists:foldl(
|
||||
@ -54,73 +57,18 @@ squash_routes(Routes) ->
|
||||
Routes
|
||||
)).
|
||||
|
||||
-spec request_hook(cowboy_req:req()) ->
|
||||
cowboy_req:req().
|
||||
|
||||
request_hook(Req) ->
|
||||
cowboy_req:set_meta(?START_TIME_TAG, genlib_time:ticks(), Req).
|
||||
|
||||
-spec response_hook(cowboy:http_status(), cowboy:http_headers(), iodata(), cowboy_req:req()) ->
|
||||
cowboy_req:req().
|
||||
|
||||
response_hook(Code, Headers, Body, Req) ->
|
||||
try
|
||||
{Code1, Headers1, Req1} = handle_response(Code, Headers, Req),
|
||||
_ = log_access(Code1, Headers1, Body, Req1),
|
||||
Req1
|
||||
catch
|
||||
Class:Reason ->
|
||||
Stack = genlib_format:format_stacktrace(erlang:get_stacktrace(), [newlines]),
|
||||
_ = lager:warning(
|
||||
"Response hook failed for: [~p, ~p, ~p]~nwith: ~p:~p~nstacktrace: ~ts",
|
||||
[Code, Headers, Req, Class, Reason, Stack]
|
||||
),
|
||||
Req
|
||||
end.
|
||||
|
||||
handle_response(Code, Headers, Req) when Code >= 500 ->
|
||||
send_oops_resp(Code, Headers, get_oops_body_safe(Code), Req);
|
||||
handle_response(Code, Headers, Req) ->
|
||||
{Code, Headers, Req}.
|
||||
|
||||
%% cowboy_req:reply/4 has a faulty spec in case of response body fun.
|
||||
-dialyzer({[no_contracts, no_fail_call], send_oops_resp/4}).
|
||||
|
||||
send_oops_resp(Code, Headers, undefined, Req) ->
|
||||
{Code, Headers, Req};
|
||||
send_oops_resp(Code, Headers, File, Req) ->
|
||||
FileSize = filelib:file_size(File),
|
||||
F = fun(Socket, Transport) ->
|
||||
case Transport:sendfile(Socket, File) of
|
||||
{ok, _} ->
|
||||
ok;
|
||||
{error, Error} ->
|
||||
_ = lager:warning("Failed to send oops body: ~p", [Error]),
|
||||
ok
|
||||
mk_operation_id_getter(#{env := Env}) ->
|
||||
fun (Req) ->
|
||||
case cowboy_router:execute(Req, Env) of
|
||||
{ok, _, #{handler_opts := {Operations, _Handler}}} ->
|
||||
Method = cowboy_req:method(Req),
|
||||
case maps:find(Method, Operations) of
|
||||
error ->
|
||||
#{};
|
||||
{ok, OperationID} ->
|
||||
#{operation_id => OperationID}
|
||||
end;
|
||||
_ ->
|
||||
#{}
|
||||
end
|
||||
end,
|
||||
Headers1 = lists:foldl(
|
||||
fun({K, V}, Acc) -> lists:keystore(K, 1, Acc, {K, V}) end,
|
||||
Headers,
|
||||
[
|
||||
{<<"content-type">>, <<"text/plain; charset=utf-8">>},
|
||||
{<<"content-length">>, integer_to_list(FileSize)}
|
||||
]
|
||||
),
|
||||
{ok, Req1} = cowboy_req:reply(Code, Headers1, {FileSize, F}, Req),
|
||||
{Code, Headers1, Req1}.
|
||||
|
||||
get_oops_body_safe(Code) ->
|
||||
try get_oops_body(Code)
|
||||
catch
|
||||
Error:Reason ->
|
||||
_ = lager:warning("Invalid oops body config for code: ~p. Error: ~p:~p", [Code, Error, Reason]),
|
||||
undefined
|
||||
end.
|
||||
|
||||
get_oops_body(Code) ->
|
||||
genlib_map:get(Code, genlib_app:env(?APP, oops_bodies, #{}), undefined).
|
||||
|
||||
log_access(Code, Headers, Body, Req) ->
|
||||
LogFun = cowboy_access_log:get_response_hook(capi_access_lager_event),
|
||||
LogFun(Code, Headers, Body, Req).
|
||||
end.
|
@ -13,6 +13,7 @@
|
||||
-export([unwrap/1]).
|
||||
-export([define/2]).
|
||||
|
||||
-export([get_process_metadata/0]).
|
||||
-export([deduplicate_payment_methods/1]).
|
||||
|
||||
-define(MAX_DEADLINE_TIME, 1*60*1000). % 1 min
|
||||
@ -21,14 +22,14 @@
|
||||
|
||||
logtag_process(Key, Value) when is_atom(Key) ->
|
||||
% TODO preformat into binary?
|
||||
lager:md(orddict:store(Key, Value, lager:md())).
|
||||
logger:update_process_metadata(maps:put(Key, Value, capi_utils:get_process_metadata())).
|
||||
|
||||
-spec base64url_to_map(binary()) -> map() | no_return().
|
||||
base64url_to_map(Base64) when is_binary(Base64) ->
|
||||
try jsx:decode(base64url:decode(Base64), [return_maps])
|
||||
catch
|
||||
Class:Reason ->
|
||||
_ = lager:debug("decoding base64 ~p to map failed with ~p:~p", [Base64, Class, Reason]),
|
||||
_ = logger:debug("decoding base64 ~p to map failed with ~p:~p", [Base64, Class, Reason]),
|
||||
erlang:error(badarg)
|
||||
end.
|
||||
|
||||
@ -37,7 +38,7 @@ map_to_base64url(Map) when is_map(Map) ->
|
||||
try base64url:encode(jsx:encode(Map))
|
||||
catch
|
||||
Class:Reason ->
|
||||
_ = lager:debug("encoding map ~p to base64 failed with ~p:~p", [Map, Class, Reason]),
|
||||
_ = logger:debug("encoding map ~p to base64 failed with ~p:~p", [Map, Class, Reason]),
|
||||
erlang:error(badarg)
|
||||
end.
|
||||
|
||||
@ -159,6 +160,14 @@ clamp_max_deadline(Value) when is_integer(Value)->
|
||||
Value
|
||||
end.
|
||||
|
||||
-spec get_process_metadata() -> logger:metadata().
|
||||
get_process_metadata() ->
|
||||
% perhaps use scopper:collect()?
|
||||
case logger:get_process_metadata() of
|
||||
undefined -> #{};
|
||||
Metadata -> Metadata
|
||||
end.
|
||||
|
||||
-spec deduplicate_payment_methods(list()) -> list().
|
||||
|
||||
deduplicate_payment_methods(Methods) ->
|
||||
|
@ -5,9 +5,11 @@
|
||||
-include_lib("dmsl/include/dmsl_domain_config_thrift.hrl").
|
||||
|
||||
-export([init_suite/2]).
|
||||
-export([init_suite/3]).
|
||||
-export([start_app/1]).
|
||||
-export([start_app/2]).
|
||||
-export([start_capi/1]).
|
||||
-export([start_capi/2]).
|
||||
-export([issue_token/2]).
|
||||
-export([issue_token/3]).
|
||||
-export([issue_token/4]).
|
||||
@ -32,10 +34,15 @@
|
||||
|
||||
-spec init_suite(module(), config()) ->
|
||||
config().
|
||||
|
||||
init_suite(Module, Config) ->
|
||||
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(lager) ++
|
||||
start_app(woody),
|
||||
ServiceURLs = mock_services_([
|
||||
{
|
||||
@ -46,23 +53,12 @@ init_suite(Module, Config) ->
|
||||
], SupPid),
|
||||
Apps2 =
|
||||
start_app(dmt_client, [{max_cache_size, #{}}, {service_urls, ServiceURLs}, {cache_update_interval, 50000}]) ++
|
||||
start_capi(Config),
|
||||
start_capi(Config, CapiEnv),
|
||||
[{apps, lists:reverse(Apps2 ++ Apps1)}, {suite_test_sup, SupPid} | Config].
|
||||
|
||||
-spec start_app(app_name()) ->
|
||||
[app_name()].
|
||||
|
||||
start_app(lager = AppName) ->
|
||||
start_app(AppName, [
|
||||
{async_threshold, 1},
|
||||
{async_threshold_window, 0},
|
||||
{error_logger_hwm, 600},
|
||||
{suppress_application_start_stop, true},
|
||||
{handlers, [
|
||||
{lager_common_test_backend, [warning, {lager_logstash_formatter, []}]}
|
||||
]}
|
||||
]);
|
||||
|
||||
start_app(woody = AppName) ->
|
||||
start_app(AppName, [
|
||||
{acceptors_pool_size, 4}
|
||||
@ -81,7 +77,13 @@ start_app(AppName, Env) ->
|
||||
[app_name()].
|
||||
|
||||
start_capi(Config) ->
|
||||
CapiEnv = [
|
||||
start_capi(Config, []).
|
||||
|
||||
-spec start_capi(config(), list()) ->
|
||||
[app_name()].
|
||||
|
||||
start_capi(Config, ExtraEnv) ->
|
||||
CapiEnv = ExtraEnv ++ [
|
||||
{ip, ?CAPI_IP},
|
||||
{port, ?CAPI_PORT},
|
||||
{service_type, real},
|
||||
|
131
apps/capi/test/capi_self_tests_SUITE.erl
Normal file
131
apps/capi/test/capi_self_tests_SUITE.erl
Normal file
@ -0,0 +1,131 @@
|
||||
-module(capi_self_tests_SUITE).
|
||||
|
||||
-include_lib("common_test/include/ct.hrl").
|
||||
|
||||
-include_lib("dmsl/include/dmsl_domain_config_thrift.hrl").
|
||||
-include_lib("capi_dummy_data.hrl").
|
||||
-include_lib("jose/include/jose_jwk.hrl").
|
||||
|
||||
-export([all/0]).
|
||||
-export([groups/0]).
|
||||
-export([init_per_suite/1]).
|
||||
-export([end_per_suite/1]).
|
||||
-export([init_per_group/2]).
|
||||
-export([end_per_group/2]).
|
||||
-export([init_per_testcase/2]).
|
||||
-export([end_per_testcase/2]).
|
||||
|
||||
-export([init/1]).
|
||||
|
||||
-export([
|
||||
oops_body_test/1
|
||||
]).
|
||||
|
||||
-type test_case_name() :: atom().
|
||||
-type config() :: [{atom(), any()}].
|
||||
-type group_name() :: atom().
|
||||
|
||||
-behaviour(supervisor).
|
||||
|
||||
-define(OOPS_BODY, filename:join(?config(data_dir, Config), "cutest_cat_alive")).
|
||||
|
||||
-spec init([]) ->
|
||||
{ok, {supervisor:sup_flags(), [supervisor:child_spec()]}}.
|
||||
init([]) ->
|
||||
{ok, {#{strategy => one_for_all, intensity => 1, period => 1}, []}}.
|
||||
|
||||
-spec all() ->
|
||||
[test_case_name()].
|
||||
all() ->
|
||||
[
|
||||
{group, stream_handler_tests}
|
||||
].
|
||||
|
||||
-spec groups() ->
|
||||
[{group_name(), list(), [test_case_name()]}].
|
||||
groups() ->
|
||||
[
|
||||
{stream_handler_tests, [],
|
||||
[
|
||||
oops_body_test
|
||||
]
|
||||
}
|
||||
].
|
||||
|
||||
%%
|
||||
%% starting/stopping
|
||||
%%
|
||||
-spec init_per_suite(config()) ->
|
||||
config().
|
||||
init_per_suite(Config) ->
|
||||
capi_ct_helper:init_suite(?MODULE, Config, [{oops_bodies, #{
|
||||
500 => ?OOPS_BODY
|
||||
}}]).
|
||||
|
||||
-spec end_per_suite(config()) ->
|
||||
_.
|
||||
end_per_suite(C) ->
|
||||
_ = capi_ct_helper:stop_mocked_service_sup(?config(suite_test_sup, C)),
|
||||
[application:stop(App) || App <- proplists:get_value(apps, C)],
|
||||
ok.
|
||||
|
||||
-spec init_per_group(group_name(), config()) ->
|
||||
config().
|
||||
init_per_group(stream_handler_tests, Config) ->
|
||||
BasePermissions = [
|
||||
{[invoices], write},
|
||||
{[invoices], read},
|
||||
{[party], write},
|
||||
{[party], read},
|
||||
{[invoices, payments], write},
|
||||
{[invoices, payments], read},
|
||||
{[customers], write},
|
||||
{[payouts], write},
|
||||
{[payouts], read}
|
||||
],
|
||||
{ok, Token} = capi_ct_helper:issue_token(BasePermissions, unlimited),
|
||||
Context = capi_ct_helper:get_context(Token),
|
||||
[{context, Context} | Config];
|
||||
|
||||
init_per_group(_, Config) ->
|
||||
Config.
|
||||
|
||||
-spec end_per_group(group_name(), config()) ->
|
||||
_.
|
||||
end_per_group(_Group, _C) ->
|
||||
ok.
|
||||
|
||||
-spec init_per_testcase(test_case_name(), config()) ->
|
||||
config().
|
||||
init_per_testcase(_Name, C) ->
|
||||
[{test_sup, capi_ct_helper:start_mocked_service_sup(?MODULE)} | C].
|
||||
|
||||
-spec end_per_testcase(test_case_name(), config()) ->
|
||||
config().
|
||||
end_per_testcase(_Name, C) ->
|
||||
capi_ct_helper:stop_mocked_service_sup(?config(test_sup, C)),
|
||||
ok.
|
||||
|
||||
%%% Tests
|
||||
|
||||
-spec oops_body_test(config()) ->
|
||||
_.
|
||||
|
||||
oops_body_test(Config) ->
|
||||
_ = capi_ct_helper:mock_services([{party_management, fun('Get', _) -> {ok, "spanish inquisition"} end}], Config),
|
||||
Context = ?config(context, Config),
|
||||
Token = maps:get(token, Context),
|
||||
{ok, 500, _, OopsBody} = hackney:request(
|
||||
get,
|
||||
"localhost:8080/v2/processing/me",
|
||||
[
|
||||
{<<"Authorization">>, <<<<"Bearer ">>/binary, Token/binary>>},
|
||||
{<<"Content-Type">>, <<"application/json; charset=UTF-8">>},
|
||||
{<<"X-Request-ID">>, list_to_binary(integer_to_list(rand:uniform(100000)))}
|
||||
],
|
||||
<<"{}">>,
|
||||
[
|
||||
with_body
|
||||
]
|
||||
),
|
||||
{ok, OopsBody} = file:read_file(?OOPS_BODY).
|
@ -0,0 +1,3 @@
|
||||
|\__/,| (`\
|
||||
_.|o o |_ ) )
|
||||
-(((---(((--------
|
@ -0,0 +1,9 @@
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIBOwIBAAJBAK9fx7qOJT7Aoseu7KKgaLagBh3wvDzg7F/ZMtGbPFikJnnvRWvF
|
||||
B5oEGbMPblvtF0/fjqfu+eqjP3Z1tUSn7TkCAwEAAQJABUY5KIgr4JZEjwLYxQ9T
|
||||
9uIbLP1Xe/E7yqoqmBk2GGhSrPY0OeRkYnUVLcP96UPQhF63iuG8VF6uZ7oAPsq+
|
||||
gQIhANZy3jSCzPjXYHRU1kRqQzpt2S+OqoEiqQ6YG1HrC/VxAiEA0Vq6JlQK2tOX
|
||||
37SS00dK0Qog4Qi8dN73GliFQNP18EkCIQC4epSA48zkfJMzQBAbRraSuxDNApPX
|
||||
BzQbo+pMrEDbYQIgY4AncQgIkLB4Qk5kah48JNYXglzQlQtTjiX8Ty9ueGECIQCM
|
||||
GD3UbQKiA0gf5plBA24I4wFVKxxa4wXbW/7SfP6XmQ==
|
||||
-----END RSA PRIVATE KEY-----
|
@ -40,13 +40,13 @@
|
||||
-type protocol() :: ipv4 | ipv6.
|
||||
-export_type([protocol/0]).
|
||||
|
||||
-type protocol_opts() :: [{connect_options, [inet4 | inet6]}].
|
||||
-type protocol_opts() :: [{connect_options, [inet | inet6]}].
|
||||
-export_type([protocol_opts/0]).
|
||||
|
||||
-spec protocol_to_opt(protocol()) ->
|
||||
protocol_opts().
|
||||
protocol_to_opt(ipv4) ->
|
||||
[{connect_options, [inet4]}];
|
||||
[{connect_options, [inet]}];
|
||||
protocol_to_opt(ipv6) ->
|
||||
[{connect_options, [inet6]}].
|
||||
|
||||
|
@ -7,7 +7,6 @@
|
||||
thrift,
|
||||
dmsl,
|
||||
bender_proto,
|
||||
genlib,
|
||||
lager
|
||||
genlib
|
||||
]}
|
||||
]}.
|
||||
|
@ -70,26 +70,27 @@ format_event(_EventType, _RpcID, _EventMeta, _Msg) ->
|
||||
%%
|
||||
|
||||
log(RpcID, {Level, {Format, Args}}, MD) ->
|
||||
lager:log(Level, [{pid, self()}] ++ rpc_id_to_md(RpcID) ++ orddict:to_list(MD), Format, Args).
|
||||
logger:log(Level, Format, Args, maps:merge(MD, rpc_id_to_md(RpcID))).
|
||||
|
||||
rpc_id_to_md(undefined) ->
|
||||
[];
|
||||
#{};
|
||||
rpc_id_to_md(RpcID = #{}) ->
|
||||
maps:to_list(RpcID).
|
||||
RpcID.
|
||||
|
||||
%%
|
||||
|
||||
enter(Name, Meta) ->
|
||||
lager:md(collect(Name, Meta)).
|
||||
logger:update_process_metadata(collect(Name, Meta)).
|
||||
|
||||
leave(Name) ->
|
||||
lager:md(orddict:erase(Name, lager:md())).
|
||||
logger:set_process_metadata(maps:remove(Name, capi_utils:get_process_metadata())).
|
||||
|
||||
collect(Name, Meta) ->
|
||||
orddict:store(Name, maps:merge(find_scope(Name), Meta), lager:md()).
|
||||
% basically an update?
|
||||
PreparedMeta = maps:merge(find_scope(Name), Meta),
|
||||
maps:put(Name, PreparedMeta, capi_utils:get_process_metadata()).
|
||||
|
||||
find_scope(Name) ->
|
||||
case orddict:find(Name, lager:md()) of
|
||||
case maps:find(Name, capi_utils:get_process_metadata()) of
|
||||
{ok, V = #{}} -> V;
|
||||
error -> #{}
|
||||
end.
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 269686d735abef363f9f40a1bf4e1b7c751f3722
|
||||
Subproject commit ea4aa042f482551d624fd49a570d28488f479e93
|
@ -1,28 +1,31 @@
|
||||
[
|
||||
|
||||
{lager, [
|
||||
{error_logger_hwm, 600},
|
||||
{log_root, "/var/log/capi"},
|
||||
{handlers, [
|
||||
{lager_console_backend, debug},
|
||||
{lager_file_backend, [
|
||||
{file, "console.json"},
|
||||
{level, debug},
|
||||
{formatter, lager_logstash_formatter}
|
||||
]}
|
||||
]},
|
||||
{extra_sinks, [
|
||||
{capi_access_lager_event, [
|
||||
{handlers, [
|
||||
{lager_file_backend, [
|
||||
{file, "access_log.json"},
|
||||
{level, info},
|
||||
{formatter, lager_logstash_formatter}
|
||||
]}
|
||||
]},
|
||||
{async_threshold, 20},
|
||||
{async_threshold_window, 5}
|
||||
]}
|
||||
{kernel, [
|
||||
{logger_level, info},
|
||||
{logger, [
|
||||
{handler, default, logger_std_h, #{
|
||||
level => debug,
|
||||
config => #{
|
||||
type => {file, "/var/log/capi/console.json"},
|
||||
sync_mode_qlen => 20,
|
||||
burst_limit_enable => true,
|
||||
burst_limit_max_count => 600,
|
||||
burst_limit_window_time => 1000
|
||||
},
|
||||
filters => [{access_log, {fun logger_filters:domain/2, {stop, equal, [cowboy_access_log]}}}],
|
||||
formatter => {logger_logstash_formatter, #{}}
|
||||
}},
|
||||
{handler, access_logger, logger_std_h, #{
|
||||
level => info,
|
||||
config => #{
|
||||
type => {file, "/var/log/capi/access_log.json"},
|
||||
sync_mode_qlen => 20,
|
||||
burst_limit_enable => true,
|
||||
burst_limit_max_count => 600,
|
||||
burst_limit_window_time => 1000
|
||||
},
|
||||
filters => [{access_log, {fun logger_filters:domain/2, {stop, not_equal, [cowboy_access_log]}}}],
|
||||
formatter => {logger_logstash_formatter, #{}}
|
||||
}}
|
||||
]}
|
||||
]},
|
||||
|
||||
|
@ -23,7 +23,7 @@
|
||||
]
|
||||
}},
|
||||
{elvis_style, no_if_expression},
|
||||
{elvis_style, invalid_dynamic_call, #{ignore => [capi_swagger_server]}},
|
||||
{elvis_style, invalid_dynamic_call, #{ignore => [capi_swagger_server, capi_stream_handler]}},
|
||||
{elvis_style, used_ignored_variable},
|
||||
{elvis_style, no_behavior_info},
|
||||
{elvis_style, module_naming_convention, #{regex => "^[a-z]([a-z0-9]*_?)*(_SUITE)?$"}},
|
||||
|
12
rebar.config
12
rebar.config
@ -17,20 +17,18 @@
|
||||
warn_shadow_vars,
|
||||
warn_unused_import,
|
||||
warn_unused_function,
|
||||
warn_deprecated_function,
|
||||
warn_deprecated_function
|
||||
|
||||
% at will
|
||||
% bin_opt_info
|
||||
% no_auto_import
|
||||
% warn_missing_spec_all
|
||||
{parse_transform, lager_transform}
|
||||
]}.
|
||||
|
||||
%% Common project dependencies.
|
||||
{deps, [
|
||||
{cowboy, "1.0.4"},
|
||||
{cowboy, "2.5.0"},
|
||||
{jose, "1.7.9"},
|
||||
{lager, "3.2.4"},
|
||||
{base64url, "0.0.1"},
|
||||
{rfc3339,
|
||||
{git, "https://github.com/rbkmoney/rfc3339.git",
|
||||
@ -72,13 +70,13 @@
|
||||
{branch, "master"}
|
||||
}
|
||||
},
|
||||
{lager_logstash_formatter,
|
||||
{git, "git@github.com:rbkmoney/lager_logstash_formatter.git",
|
||||
{logger_logstash_formatter,
|
||||
{git, "git@github.com:rbkmoney/logger_logstash_formatter.git",
|
||||
{branch, "master"}
|
||||
}
|
||||
},
|
||||
{cowboy_cors,
|
||||
{git, "https://github.com/danielwhite/cowboy_cors.git",
|
||||
{git, "https://github.com/rbkmoney/cowboy_cors.git",
|
||||
{branch, "master"}
|
||||
}
|
||||
},
|
||||
|
58
rebar.lock
58
rebar.lock
@ -9,28 +9,29 @@
|
||||
{git,"git@github.com:rbkmoney/binbase-proto.git",
|
||||
{ref,"13bcd24e994ccfd1f25af1cda081399b9b58a014"}},
|
||||
0},
|
||||
{<<"cache">>,{pkg,<<"cache">>,<<"2.2.0">>},1},
|
||||
{<<"certifi">>,{pkg,<<"certifi">>,<<"0.4.0">>},1},
|
||||
{<<"cg_mon">>,
|
||||
{git,"https://github.com/rbkmoney/cg_mon.git",
|
||||
{ref,"5a87a37694e42b6592d3b4164ae54e0e87e24e18"}},
|
||||
1},
|
||||
{<<"cowboy">>,{pkg,<<"cowboy">>,<<"1.0.4">>},0},
|
||||
{<<"cowboy">>,{pkg,<<"cowboy">>,<<"2.5.0">>},0},
|
||||
{<<"cowboy_access_log">>,
|
||||
{git,"git@github.com:rbkmoney/cowboy_access_log.git",
|
||||
{ref,"c91ae2316f3daf5465ec12e9fdd0ae37082885c0"}},
|
||||
{ref,"de3ebbf8705dbd18a445ac179ab564c1cfd1fd24"}},
|
||||
0},
|
||||
{<<"cowboy_cors">>,
|
||||
{git,"https://github.com/danielwhite/cowboy_cors.git",
|
||||
{ref,"392f5804b63fff2bd0fda67671d5b2fbe0badd37"}},
|
||||
{git,"https://github.com/rbkmoney/cowboy_cors.git",
|
||||
{ref,"4cac7528845a8610d471b6fbb92321f79d93f0b8"}},
|
||||
0},
|
||||
{<<"cowlib">>,{pkg,<<"cowlib">>,<<"1.0.2">>},1},
|
||||
{<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.6.0">>},1},
|
||||
{<<"dmsl">>,
|
||||
{git,"git@github.com:rbkmoney/damsel.git",
|
||||
{ref,"b45975832a5c5911c58ad8f206bf9ba465eadfa3"}},
|
||||
0},
|
||||
{<<"dmt_client">>,
|
||||
{git,"git@github.com:rbkmoney/dmt_client.git",
|
||||
{ref,"ea5b1fd6d0812b7f8d7dbe95996cfdf9318ad830"}},
|
||||
{ref,"6bb0b65a183910c2031b5b81eb84fee045b7de8a"}},
|
||||
0},
|
||||
{<<"dmt_core">>,
|
||||
{git,"git@github.com:rbkmoney/dmt_core.git",
|
||||
@ -38,7 +39,7 @@
|
||||
1},
|
||||
{<<"erl_health">>,
|
||||
{git,"https://github.com/rbkmoney/erlang-health.git",
|
||||
{ref,"ab3ca1ccab6e77905810aa270eb936dbe70e02f8"}},
|
||||
{ref,"2575c7b63d82a92de54d2d27e504413675e64811"}},
|
||||
0},
|
||||
{<<"folsom">>,
|
||||
{git,"git@github.com:folsom-project/folsom.git",
|
||||
@ -46,25 +47,28 @@
|
||||
1},
|
||||
{<<"genlib">>,
|
||||
{git,"https://github.com/rbkmoney/genlib.git",
|
||||
{ref,"7fc1ca1a57dbe2b8b837951095e314c32afd6c9a"}},
|
||||
{ref,"f805a11f6e73faffb05656c5192fbe199df36f27"}},
|
||||
0},
|
||||
{<<"goldrush">>,{pkg,<<"goldrush">>,<<"0.1.9">>},1},
|
||||
{<<"hackney">>,{pkg,<<"hackney">>,<<"1.5.7">>},0},
|
||||
{<<"gproc">>,{pkg,<<"gproc">>,<<"0.8.0">>},1},
|
||||
{<<"gun">>,
|
||||
{git,"https://github.com/ninenines/gun.git",
|
||||
{ref,"e7dd9f227e46979d8073e71c683395a809b78cb4"}},
|
||||
1},
|
||||
{<<"hackney">>,{pkg,<<"hackney">>,<<"1.15.0">>},0},
|
||||
{<<"how_are_you">>,
|
||||
{git,"https://github.com/rbkmoney/how_are_you.git",
|
||||
{ref,"e960df58c1e8a764894206623eaed0ec57878b91"}},
|
||||
0},
|
||||
{<<"idna">>,{pkg,<<"idna">>,<<"1.2.0">>},1},
|
||||
{<<"jesse">>,
|
||||
{git,"git@github.com:rbkmoney/jesse.git",
|
||||
{ref,"39105922d1ce5834383d8e8aa877c60319b9834a"}},
|
||||
{git,"https://github.com/rbkmoney/jesse.git",
|
||||
{ref,"723e835708a022bbce9e57807ecf220b00fb771a"}},
|
||||
0},
|
||||
{<<"jose">>,{pkg,<<"jose">>,<<"1.7.9">>},0},
|
||||
{<<"jsx">>,{pkg,<<"jsx">>,<<"2.8.2">>},0},
|
||||
{<<"lager">>,{pkg,<<"lager">>,<<"3.2.4">>},0},
|
||||
{<<"lager_logstash_formatter">>,
|
||||
{git,"git@github.com:rbkmoney/lager_logstash_formatter.git",
|
||||
{ref,"83a0f21c03dacbd876c7289435f369f573c749b1"}},
|
||||
{<<"logger_logstash_formatter">>,
|
||||
{git,"git@github.com:rbkmoney/logger_logstash_formatter.git",
|
||||
{ref,"4348f24487c400da0579032422d93acd89c6e121"}},
|
||||
0},
|
||||
{<<"metrics">>,{pkg,<<"metrics">>,<<"1.0.1">>},1},
|
||||
{<<"mimerl">>,{pkg,<<"mimerl">>,<<"1.0.2">>},1},
|
||||
@ -80,15 +84,14 @@
|
||||
{git,"git@github.com:rbkmoney/payproc-errors-erlang.git",
|
||||
{ref,"9c720534eb88edc6ba47af084939efabceb9b2d6"}},
|
||||
0},
|
||||
{<<"pooler">>,{pkg,<<"pooler">>,<<"1.5.0">>},0},
|
||||
{<<"ranch">>,{pkg,<<"ranch">>,<<"1.3.2">>},1},
|
||||
{<<"ranch">>,{pkg,<<"ranch">>,<<"1.6.2">>},1},
|
||||
{<<"rfc3339">>,
|
||||
{git,"https://github.com/rbkmoney/rfc3339.git",
|
||||
{ref,"ee3a1a6b1ee60219c49fdcaa9f36a25e91962bb5"}},
|
||||
0},
|
||||
{<<"scoper">>,
|
||||
{git,"git@github.com:rbkmoney/scoper.git",
|
||||
{ref,"802057089bac258f45e35263eb2223961618468d"}},
|
||||
{ref,"e03318fd1feea0e2bb0ba5c634bb38b18aa81efa"}},
|
||||
1},
|
||||
{<<"snowflake">>,
|
||||
{git,"https://github.com/rbkmoney/snowflake.git",
|
||||
@ -97,11 +100,11 @@
|
||||
{<<"ssl_verify_fun">>,{pkg,<<"ssl_verify_fun">>,<<"1.1.0">>},1},
|
||||
{<<"thrift">>,
|
||||
{git,"https://github.com/rbkmoney/thrift_erlang.git",
|
||||
{ref,"240bbc842f6e9b90d01bd07838778cf48752b510"}},
|
||||
{ref,"d393ef9cdb10f3d761ba3a603df2b2929dc19a10"}},
|
||||
1},
|
||||
{<<"woody">>,
|
||||
{git,"git@github.com:rbkmoney/woody_erlang.git",
|
||||
{ref,"98469234e415214c1b197f08539612c20b3a3ee5"}},
|
||||
{ref,"5ee89dd0b2d52ff955a4107a8d9dc0f8fdd365a0"}},
|
||||
0},
|
||||
{<<"woody_user_identity">>,
|
||||
{git,"git@github.com:rbkmoney/woody_erlang_user_identity.git",
|
||||
@ -111,18 +114,17 @@
|
||||
{pkg_hash,[
|
||||
{<<"base64url">>, <<"36A90125F5948E3AFD7BE97662A1504B934DD5DAC78451CA6E9ABF85A10286BE">>},
|
||||
{<<"bear">>, <<"16264309AE5D005D03718A5C82641FCC259C9E8F09ADEB6FD79CA4271168656F">>},
|
||||
{<<"cache">>, <<"3C11DBF4CD8FCD5787C95A5FB2A04038E3729CFCA0386016EEA8C953AB48A5AB">>},
|
||||
{<<"certifi">>, <<"A7966EFB868B179023618D29A407548F70C52466BF1849B9E8EBD0E34B7EA11F">>},
|
||||
{<<"cowboy">>, <<"A324A8DF9F2316C833A470D918AAF73AE894278B8AA6226CE7A9BF699388F878">>},
|
||||
{<<"cowlib">>, <<"9D769A1D062C9C3AC753096F868CA121E2730B9A377DE23DEC0F7E08B1DF84EE">>},
|
||||
{<<"goldrush">>, <<"F06E5D5F1277DA5C413E84D5A2924174182FB108DABB39D5EC548B27424CD106">>},
|
||||
{<<"hackney">>, <<"F3809C0A17A3E523A865C65F6552B526F6B799ACD0389803A05F88573EA26162">>},
|
||||
{<<"cowboy">>, <<"4EF3AE066EE10FE01EA3272EDC8F024347A0D3EB95F6FBB9AED556DACBFC1337">>},
|
||||
{<<"cowlib">>, <<"8AA629F81A0FC189F261DC98A42243FA842625FEEA3C7EC56C48F4CCDB55490F">>},
|
||||
{<<"gproc">>, <<"CEA02C578589C61E5341FCE149EA36CCEF236CC2ECAC8691FBA408E7EA77EC2F">>},
|
||||
{<<"hackney">>, <<"287A5D2304D516F63E56C469511C42B016423BCB167E61B611F6BAD47E3CA60E">>},
|
||||
{<<"idna">>, <<"AC62EE99DA068F43C50DC69ACF700E03A62A348360126260E87F2B54ECED86B2">>},
|
||||
{<<"jose">>, <<"9DC5A14AB62DB4E41677FCC97993752562FB57AD0B8BA062589682EDD3ACB91F">>},
|
||||
{<<"jsx">>, <<"7ACC7D785B5ABE8A6E9ADBDE926A24E481F29956DD8B4DF49E3E4E7BCC92A018">>},
|
||||
{<<"lager">>, <<"A6DEB74DAE7927F46BD13255268308EF03EB206EC784A94EAF7C1C0F3B811615">>},
|
||||
{<<"metrics">>, <<"25F094DEA2CDA98213CECC3AEFF09E940299D950904393B2A29D191C346A8486">>},
|
||||
{<<"mimerl">>, <<"993F9B0E084083405ED8252B99460C4F0563E41729AB42D9074FD5E52439BE88">>},
|
||||
{<<"pooler">>, <<"0FD4BE5D2976E6A2E9A1617623031758C26F200C1FCA89E4A3C542747BEC6371">>},
|
||||
{<<"ranch">>, <<"E4965A144DC9FBE70E5C077C65E73C57165416A901BD02EA899CFD95AA890986">>},
|
||||
{<<"ranch">>, <<"6DB93C78F411EE033DBB18BA8234C5574883ACB9A75AF0FB90A9B82EA46AFA00">>},
|
||||
{<<"ssl_verify_fun">>, <<"EDEE20847C42E379BF91261DB474FFBE373F8ACB56E9079ACB6038D4E0BF414F">>}]}
|
||||
].
|
||||
|
Loading…
Reference in New Issue
Block a user