mirror of
https://github.com/valitydev/wapi-lib.git
synced 2024-11-07 10:38:52 +00:00
Second untested approach to session machines
This commit is contained in:
parent
2503d01cee
commit
c79e6e24f4
@ -26,7 +26,8 @@
|
||||
-type destination() :: #{
|
||||
wallet := wallet(),
|
||||
resource := resource(),
|
||||
status := status()
|
||||
status := status(),
|
||||
masked_pan := binary()
|
||||
}.
|
||||
|
||||
-export_type([destination/0]).
|
||||
|
15
apps/fistful/src/ff_adpt.erl
Normal file
15
apps/fistful/src/ff_adpt.erl
Normal file
@ -0,0 +1,15 @@
|
||||
%%% Withdrawal adapter generic
|
||||
-module(ff_adpt).
|
||||
|
||||
%%
|
||||
%% Types
|
||||
%%
|
||||
|
||||
-type adapter() :: atom().
|
||||
-type adapter_state() :: any().
|
||||
|
||||
-type withdrawal() :: ff_adpt_withdrawal:withdrawal().
|
||||
|
||||
-export_type([adapter/0]).
|
||||
-export_type([withdrawal/0]).
|
||||
-export_type([adapter_state/0]).
|
143
apps/fistful/src/ff_adpt_client.erl
Normal file
143
apps/fistful/src/ff_adpt_client.erl
Normal file
@ -0,0 +1,143 @@
|
||||
%%% Client for adapter for withdrawal provider
|
||||
-module(ff_adpt_client).
|
||||
|
||||
-include_lib("dmsl/include/dmsl_domain_thrift.hrl").
|
||||
-include_lib("dmsl/include/dmsl_withdrawals_provider_adapter_thrift.hrl").
|
||||
|
||||
%% API
|
||||
-export([process_withdrawal/5]).
|
||||
|
||||
%%
|
||||
%% Internal types
|
||||
%%
|
||||
|
||||
-type id() :: machinery:id().
|
||||
-type identity_id() :: id().
|
||||
|
||||
-type withdrawal() :: ff_adpt_withdrawal:withdrawal().
|
||||
-type destination() :: ff_adpt_withdrawal:destination().
|
||||
-type cash() :: ff_adpt_withdrawal:cash().
|
||||
|
||||
-type adapter() :: ff_wthadpt:adapter().
|
||||
-type intent() :: {finish, status()} | {sleep, timer()}.
|
||||
-type status() :: {success, trx_info()} | {failure, ff_adpt:failure()}.
|
||||
-type timer() :: dmsl_base_thrift:'Timer'().
|
||||
-type trx_info() :: dmsl_domain_thrift:'TransactionInfo'().
|
||||
-type adapter_state() :: ff_adpt:adapter_state().
|
||||
-type process_result() :: {ok, intent(), adapter_state()} | {ok, intent()}.
|
||||
|
||||
-type domain_withdrawal() :: dmsl_withdrawals_provider_adapter_thrift:'Withdrawal'().
|
||||
-type domain_cash() :: dmsl_withdrawals_provider_adapter_thrift:'Cash'().
|
||||
-type domain_currency() :: dmsl_domain_thrift:'Currency'().
|
||||
-type domain_destination() :: dmsl_withdrawals_provider_adapter_thrift:'Destination'().
|
||||
-type domain_identity() :: dmsl_withdrawals_provider_adapter_thrift:'Identity'().
|
||||
|
||||
-type backend() :: machinery:backend(_).
|
||||
|
||||
%%
|
||||
%% API
|
||||
%%
|
||||
|
||||
-spec process_withdrawal(Adapter, Withdrawal, ASt, AOpt, Be) -> process_result() when
|
||||
Adapter :: adapter(),
|
||||
Withdrawal :: withdrawal(),
|
||||
ASt :: adapter_state(),
|
||||
AOpt :: map(),
|
||||
Be :: backend().
|
||||
process_withdrawal(Adapter, Withdrawal, ASt, AOpt, Be) ->
|
||||
DomainWithdrawal = build_and_encode_withdrawal(Withdrawal, Be),
|
||||
{ok, Result} = call(Adapter, 'ProcessWithdrawal', [DomainWithdrawal, ASt, AOpt]),
|
||||
decode_result(Result).
|
||||
|
||||
%%
|
||||
%% Internals
|
||||
%%
|
||||
|
||||
call(Adapter, Function, Args) ->
|
||||
Request = {{dmsl_withdrawals_provider_adapter_thrift, 'Adapter'}, Function, Args},
|
||||
ff_woody_client:call(Adapter, Request).
|
||||
|
||||
%% Encoders
|
||||
|
||||
-spec build_and_encode_withdrawal(Withdrawal, Be) -> domain_withdrawal() when
|
||||
Withdrawal :: withdrawal(),
|
||||
Be :: backend().
|
||||
build_and_encode_withdrawal(Withdrawal, Be) ->
|
||||
#{
|
||||
id := WId,
|
||||
cash := Cash,
|
||||
destination := Dest,
|
||||
sender := Sender,
|
||||
receiver := Receiver
|
||||
} = Withdrawal,
|
||||
#wthadpt_Withdrawal{
|
||||
id = WId,
|
||||
body = encode_body(Cash),
|
||||
destination = encode_destination(Dest),
|
||||
sender = fetch_and_encode_identity(Sender, Be),
|
||||
receiver = fetch_and_encode_identity(Receiver, Be)
|
||||
}.
|
||||
|
||||
-spec encode_body(cash()) -> domain_cash().
|
||||
encode_body({Amount, CurrencyId}) ->
|
||||
Currency = ff_currency:get(CurrencyId),
|
||||
DomainCurrency = encode_currency(Currency),
|
||||
#wthadpt_Cash{amount = Amount, currency = DomainCurrency}.
|
||||
|
||||
-spec encode_currency(ff_currency:currency()) -> domain_currency().
|
||||
encode_currency(#{
|
||||
name := Name,
|
||||
symcode := Symcode,
|
||||
numcode := Numcode,
|
||||
exponent := Exponent
|
||||
}) ->
|
||||
#domain_Currency{
|
||||
name = Name,
|
||||
symbolic_code = Symcode,
|
||||
numeric_code = Numcode,
|
||||
exponent = Exponent
|
||||
}.
|
||||
|
||||
-spec encode_destination(destination()) -> domain_destination().
|
||||
encode_destination(Destination) ->
|
||||
#{resource := Resource} = Destination,
|
||||
#{
|
||||
token := Token,
|
||||
payment_system := PaymentSystem,
|
||||
bin := Bin,
|
||||
masked_pan := MaskedPan
|
||||
} = Resource,
|
||||
{bank_card, #domain_BankCard{
|
||||
token = Token,
|
||||
payment_system = PaymentSystem,
|
||||
bin = Bin,
|
||||
masked_pan = MaskedPan
|
||||
}}.
|
||||
|
||||
-spec fetch_and_encode_identity
|
||||
(identity_id(), backend()) -> domain_identity();
|
||||
(undefined, backend()) -> undefined.
|
||||
fetch_and_encode_identity(undefined, _Be) ->
|
||||
undefined;
|
||||
fetch_and_encode_identity(IdentityId, _Be) ->
|
||||
% {ok, Identity} = ff_identity:get(IdentityId, Be),
|
||||
% TODO: Add documents and contract fields
|
||||
#wthdm_Identity{
|
||||
id = IdentityId
|
||||
}.
|
||||
|
||||
-spec decode_result(dmsl_withdrawals_provider_adapter_thrift:'ProcessResult'()) -> process_result().
|
||||
decode_result(#wthadpt_ProcessResult{intent = Intent, next_state = undefined}) ->
|
||||
{ok, decode_intent(Intent)};
|
||||
decode_result(#wthadpt_ProcessResult{intent = Intent, next_state = NextState}) ->
|
||||
{ok, decode_intent(Intent), NextState}.
|
||||
|
||||
%% Decoders
|
||||
|
||||
-spec decode_intent(dmsl_withdrawals_provider_adapter_thrift:'Intent'()) -> intent().
|
||||
decode_intent({finish, #wthadpt_FinishIntent{status = {success, #wthadpt_Success{trx_info = TrxInfo}}}}) ->
|
||||
{finish, {success, TrxInfo}};
|
||||
decode_intent({finish, #wthadpt_FinishIntent{status = {failure, Failure}}}) ->
|
||||
{finish, {failure, Failure}};
|
||||
decode_intent({sleep, #wthadpt_SleepIntent{timer = Timer}}) ->
|
||||
{sleep, Timer}.
|
@ -1,7 +1,7 @@
|
||||
%%%
|
||||
%%% Withdrawal session machine
|
||||
%%%
|
||||
-module(ff_wth_session_machine).
|
||||
-module(ff_adpt_session_machine).
|
||||
-behaviour(machinery).
|
||||
|
||||
%% API
|
||||
@ -20,11 +20,11 @@
|
||||
-type session() :: #{
|
||||
id => id(),
|
||||
status => session_status(),
|
||||
withdrawal => ff_wthadpt:withdrawal(),
|
||||
withdrawal => withdrawal(),
|
||||
adapter => adapter()
|
||||
}.
|
||||
|
||||
-type session_result() :: {success, trx_info()} | {failed, ff_wthadpt:failure()}.
|
||||
-type session_result() :: {success, trx_info()} | {failed, ff_adpt:failure()}.
|
||||
|
||||
-type session_status() :: new
|
||||
| active
|
||||
@ -32,10 +32,10 @@
|
||||
|
||||
-type ev() :: {created, session()}
|
||||
| started
|
||||
| {next_state, ff_wthadpt:adapter_state()}
|
||||
| {next_state, ff_adpt:adapter_state()}
|
||||
| {finished, session_result()}.
|
||||
|
||||
-type adapter() :: {ff_wthadpt:adapter(), map()}.
|
||||
-type adapter() :: {ff_adpt:adapter(), map()}.
|
||||
|
||||
%%
|
||||
%% Internal types
|
||||
@ -47,6 +47,7 @@
|
||||
|
||||
-type auxst() :: #{}.
|
||||
|
||||
-type withdrawal() :: ff_adpt_withdrawal:withdrawal().
|
||||
-type machine() :: machinery:machine(ev(), auxst()).
|
||||
-type result() :: machinery:result(ev(), auxst()).
|
||||
-type handler_opts() :: machinery:handler_opts().
|
||||
@ -56,7 +57,7 @@
|
||||
|
||||
-type st() :: #{
|
||||
session => session(),
|
||||
adapter_state => ff_wthadpt:adapter_state()
|
||||
adapter_state => ff_adpt:adapter_state()
|
||||
}.
|
||||
|
||||
%% Pipeline
|
||||
@ -71,7 +72,7 @@
|
||||
Ns :: namespace(),
|
||||
Id :: id(),
|
||||
Adapter :: adapter(),
|
||||
Withdrawal :: ff_wthadpt:withdrawal(),
|
||||
Withdrawal :: withdrawal(),
|
||||
Be :: backend(),
|
||||
Error :: {error, exists}.
|
||||
create(Ns, Id, Adapter, Withdrawal, Be) ->
|
||||
@ -121,7 +122,7 @@ process_session(#{session := #{status := active} = Session} = St) ->
|
||||
withdrawal := Withdrawal
|
||||
} = Session,
|
||||
ASt = maps:get(adapter_state, St, []),
|
||||
case ff_wthadpt_client:process_withdrawal(Adapter, Withdrawal, ASt, AdapterOpts) of
|
||||
case ff_adpt_client:process_withdrawal(Adapter, Withdrawal, ASt, AdapterOpts) of
|
||||
{ok, Intent, NextState} ->
|
||||
process_intent(Intent, NextState);
|
||||
{ok, Intent} ->
|
||||
@ -145,7 +146,7 @@ process_intent({sleep, Timer}) ->
|
||||
|
||||
%%
|
||||
|
||||
-spec create_session(id(), adapter(), ff_wthadpt:withdrawal()) -> session().
|
||||
-spec create_session(id(), adapter(), ff_adpt:withdrawal()) -> session().
|
||||
create_session(Id, Adapter, Withdrawal) ->
|
||||
#{
|
||||
id => Id,
|
22
apps/fistful/src/ff_adpt_withdrawal.erl
Normal file
22
apps/fistful/src/ff_adpt_withdrawal.erl
Normal file
@ -0,0 +1,22 @@
|
||||
-module(ff_adpt_withdrawal).
|
||||
|
||||
%%
|
||||
%% Types
|
||||
%%
|
||||
|
||||
-type destination() :: ff_destination:destination().
|
||||
-type identity() :: ff_identity:identity().
|
||||
-type cash() :: ff_transfer:body().
|
||||
|
||||
-type withdrawal() :: #{
|
||||
id => binary(),
|
||||
destination => destination(),
|
||||
cash => cash(),
|
||||
sender => identity() | undefined,
|
||||
receiver => identity() | undefined
|
||||
}.
|
||||
|
||||
-export_type([destination/0]).
|
||||
-export_type([identity/0]).
|
||||
-export_type([cash/0]).
|
||||
-export_type([withdrawal/0]).
|
@ -19,6 +19,7 @@
|
||||
}.
|
||||
|
||||
-export_type([id/0]).
|
||||
-export_type([currency/0]).
|
||||
|
||||
-export([get/1]).
|
||||
|
||||
|
@ -32,6 +32,7 @@
|
||||
}.
|
||||
|
||||
-export_type([transfer/0]).
|
||||
-export_type([posting/0]).
|
||||
-export_type([status/0]).
|
||||
|
||||
-export([trxid/1]).
|
||||
|
@ -1,31 +0,0 @@
|
||||
%%% Withdrawal generic
|
||||
-module(ff_wthadpt).
|
||||
|
||||
%%
|
||||
%% Types
|
||||
%%
|
||||
|
||||
-type adapter() :: atom().
|
||||
-type wth_id() :: binary().
|
||||
-type destination() :: dmsl_withdrawals_provider_adapter_thrift:'Destination'().
|
||||
-type identity() :: dmsl_withdrawals_provider_adapter_thrift:'Identity'().
|
||||
-type cash() :: dmsl_withdrawals_provider_adapter_thrift:'Cash'().
|
||||
-type failure() :: dmsl_domain_thrift:'Failure'().
|
||||
-type adapter_state() :: any().
|
||||
|
||||
-type withdrawal() :: #{
|
||||
id => wth_id(),
|
||||
body => cash(),
|
||||
destination => destination(),
|
||||
sender => identity() | indefined,
|
||||
receiver => identity() | indefined
|
||||
}.
|
||||
|
||||
-export_type([adapter/0]).
|
||||
-export_type([wth_id/0]).
|
||||
-export_type([destination/0]).
|
||||
-export_type([identity/0]).
|
||||
-export_type([cash/0]).
|
||||
-export_type([failure/0]).
|
||||
-export_type([withdrawal/0]).
|
||||
-export_type([adapter_state/0]).
|
@ -1,67 +0,0 @@
|
||||
%%% Client for adapter for withdrawal provider
|
||||
-module(ff_wthadpt_client).
|
||||
|
||||
-include_lib("dmsl/include/dmsl_withdrawals_provider_adapter_thrift.hrl").
|
||||
|
||||
%% API
|
||||
-export([process_withdrawal/4]).
|
||||
|
||||
%%
|
||||
%% Internal types
|
||||
%%
|
||||
|
||||
-type withdrawal() :: ff_wthadpt:withdrawal().
|
||||
-type adapter() :: ff_wthadpt:adapter().
|
||||
-type intent() :: {finish, status()} | {sleep, timer()}.
|
||||
-type status() :: {success, trx_info()} | {failure, ff_wthadpt:failure()}.
|
||||
-type timer() :: dmsl_base_thrift:'Timer'().
|
||||
-type trx_info() :: dmsl_domain_thrift:'TransactionInfo'().
|
||||
-type adapter_state() :: ff_wthadpt:adapter_state().
|
||||
-type process_result() :: {ok, intent(), adapter_state()} | {ok, intent()}.
|
||||
|
||||
%%
|
||||
%% API
|
||||
%%
|
||||
|
||||
-spec process_withdrawal(adapter(), withdrawal(), adapter_state(), map()) -> process_result().
|
||||
process_withdrawal(Adapter, Withdrawal, State, Options) ->
|
||||
{ok, Result} = call(Adapter, 'ProcessWithdrawal', [encode_withdrawal(Withdrawal), State, Options]),
|
||||
decode_result(Result).
|
||||
|
||||
%%
|
||||
%% Internals
|
||||
%%
|
||||
|
||||
call(Adapter, Function, Args) ->
|
||||
Request = {{dmsl_withdrawals_provider_adapter_thrift, 'Adapter'}, Function, Args},
|
||||
ff_woody_client:call(Adapter, Request).
|
||||
|
||||
-spec encode_withdrawal(withdrawal()) -> dmsl_withdrawals_provider_adapter_thrift:'Withdrawal'().
|
||||
encode_withdrawal(#{
|
||||
id := Id,
|
||||
body := Body,
|
||||
destination := Destination,
|
||||
sender := Sender,
|
||||
receiver := Receiver
|
||||
}) ->
|
||||
#wthadpt_Withdrawal{
|
||||
id = Id,
|
||||
body = Body,
|
||||
destination = Destination,
|
||||
sender = Sender,
|
||||
receiver = Receiver
|
||||
}.
|
||||
|
||||
-spec decode_result(dmsl_withdrawals_provider_adapter_thrift:'ProcessResult'()) -> process_result().
|
||||
decode_result(#wthadpt_ProcessResult{intent = Intent, next_state = undefined}) ->
|
||||
{ok, decode_intent(Intent)};
|
||||
decode_result(#wthadpt_ProcessResult{intent = Intent, next_state = NextState}) ->
|
||||
{ok, decode_intent(Intent), NextState}.
|
||||
|
||||
-spec decode_intent(dmsl_withdrawals_provider_adapter_thrift:'Intent'()) -> intent().
|
||||
decode_intent({finish, #wthadpt_FinishIntent{status = {success, #wthadpt_Success{trx_info = TrxInfo}}}}) ->
|
||||
{finish, {success, TrxInfo}};
|
||||
decode_intent({finish, #wthadpt_FinishIntent{status = {failure, Failure}}}) ->
|
||||
{finish, {failure, Failure}};
|
||||
decode_intent({sleep, #wthadpt_SleepIntent{timer = Timer}}) ->
|
||||
{sleep, Timer}.
|
Loading…
Reference in New Issue
Block a user